Change SVG Colors in Python

Quick Answer: To change SVG colors in Python, load the file with SVGDocument, find elements with selectors or tag-name search, update fill, stroke, style, or stop-color with set_attribute(), and save the edited SVG.

1from aspose.svg import SVGDocument
2
3with SVGDocument("document.svg") as document:
4    circle = document.root_element.query_selector("circle")
5    if circle is not None:
6        circle.set_attribute("fill", "#2e86de")
7        circle.set_attribute("stroke", "#1b4f72")
8    document.save("recolored.svg")

In this article, you will learn how to:

Where SVG Colors Are Stored

SVG colors can be defined in several places. Before changing a file, inspect the markup and choose the editing method that matches how the original SVG stores color.

Color locationExampleBest editing approach
Presentation attributefill="#ff0000"Set fill, stroke, or another color attribute on the element
Inline stylestyle="fill:#ff0000;stroke:#222"Update the needed property inside the style attribute
Gradient stop<stop stop-color="#ff0000">Update stop-color on <stop> elements
Inherited group style<g fill="#ff0000">Change the group attribute or override child elements
CSS rule<style>.logo { fill: red; }</style>Edit the stylesheet text or convert the rule to inline attributes

The examples below use DOM-based editing. This is usually safer than plain text replacement because it targets SVG elements and attributes rather than every matching string in the file.

How to Change SVG Colors in Python

Use this workflow when you need to recolor an SVG file while preserving its structure:

  1. Load the SVG file with SVGDocument.
  2. Inspect where the color is stored, such as fill, stroke, inline style, or stop-color.
  3. Find the target element or group of elements with a selector, tag-name search, or DOM traversal.
  4. Update the relevant color attribute or style declaration.
  5. Save the edited SVG and compare the output with the source image.

This article uses the sample file change-svg-colors.svg for the code examples and illustrations. It contains direct color attributes, an inline style, inherited group color, and a gradient, so the same input can be used throughout the article. Use it as data/change-svg-colors.svg when running the code examples.

Change Fill and Stroke Colors

Use this workflow when the SVG stores colors directly in fill or stroke attributes. The example loads change-svg-colors.svg, finds the first circle, changes its fill and stroke, and saves the result as a new SVG file.

 1import os
 2from aspose.svg import SVGDocument
 3
 4input_folder = "data/"
 5output_folder = "output/"
 6input_path = os.path.join(input_folder, "change-svg-colors.svg")
 7output_path = os.path.join(output_folder, "circle-recolored.svg")
 8os.makedirs(output_folder, exist_ok=True)
 9
10with SVGDocument(input_path) as document:
11    svg_element = document.root_element
12    circle = svg_element.query_selector("circle")
13
14    if circle is not None:
15        circle.set_attribute("fill", "#2e86de")
16        circle.set_attribute("stroke", "#1b4f72")
17        circle.set_attribute("stroke-width", "4")
18
19    document.save(output_path)

The code follows this SVG color editing workflow:

  1. Loads the SVG file as an SVGDocument.
  2. Finds the target element with query_selector().
  3. Updates the fill, stroke, and stroke-width attributes with set_attribute().
  4. Saves the edited SVG with SVGDocument.save().

The illustration below shows the source SVG file (a) and the result after changing the circle fill, stroke, and stroke-width attributes (b). The other elements stay unchanged, so the effect of the first example is easy to see.

Original SVG sample and result after changing the circle fill and stroke colors

Replace a Specific Color in Many Elements

Use this approach when you want to replace one exact text color value across many SVG elements. The example changes every fill or stroke attribute that exactly matches the old color.

 1import os
 2from aspose.svg import SVGDocument
 3
 4input_folder = "data/"
 5output_folder = "output/"
 6input_path = os.path.join(input_folder, "change-svg-colors.svg")
 7output_path = os.path.join(output_folder, "sample-blue.svg")
 8os.makedirs(output_folder, exist_ok=True)
 9
10old_color = "#ff0000"
11new_color = "#0057b8"
12
13with SVGDocument(input_path) as document:
14    for element in document.get_elements_by_tag_name("*"):
15        for attribute_name in ("fill", "stroke"):
16            if element.has_attribute(attribute_name):
17                value = element.get_attribute(attribute_name).strip()
18                if value.lower() == old_color.lower():
19                    element.set_attribute(attribute_name, new_color)
20
21    document.save(output_path)

This example compares color as a text value. It changes #ff0000 and #FF0000, but it does not treat red, rgb(255,0,0), and #f00 as the same color. If your input uses multiple color formats, normalize those values in your own preprocessing step or handle each spelling explicitly.

Change Colors in Inline Style Attributes

Some SVG tools store colors inside the style attribute instead of direct fill or stroke attributes. In that case, update the needed CSS declaration while keeping the rest of the inline style intact.

 1import os
 2from aspose.svg import SVGDocument
 3
 4
 5def set_style_property(style_text, property_name, property_value):
 6    declarations = []
 7    updated = False
 8
 9    for part in style_text.split(";"):
10        part = part.strip()
11        if not part:
12            continue
13        if ":" not in part:
14            declarations.append(part)
15            continue
16
17        name, value = part.split(":", 1)
18        if name.strip().lower() == property_name.lower():
19            declarations.append(f"{name.strip()}: {property_value}")
20            updated = True
21        else:
22            declarations.append(f"{name.strip()}: {value.strip()}")
23
24    if not updated:
25        declarations.append(f"{property_name}: {property_value}")
26
27    return "; ".join(declarations)
28
29
30input_folder = "data/"
31output_folder = "output/"
32input_path = os.path.join(input_folder, "change-svg-colors.svg")
33output_path = os.path.join(output_folder, "badge-recolored.svg")
34os.makedirs(output_folder, exist_ok=True)
35
36with SVGDocument(input_path) as document:
37    badge = document.root_element.query_selector(".badge")
38
39    if badge is not None:
40        style = badge.get_attribute("style")
41        style = set_style_property(style, "fill", "#0f766e")
42        style = set_style_property(style, "stroke", "#134e4a")
43        badge.set_attribute("style", style)
44
45    document.save(output_path)

The helper function changes only the requested style properties. This prevents a common bug where code replaces the whole style attribute and accidentally removes opacity, stroke width, font, or transform-related styling stored in the same attribute.

Change Gradient Stop Colors

Gradient colors are usually stored on <stop> elements. To recolor a gradient, update the stop-color attributes instead of changing the fill on the shape that references the gradient.

 1import os
 2from aspose.svg import SVGDocument
 3
 4input_folder = "data/"
 5output_folder = "output/"
 6input_path = os.path.join(input_folder, "change-svg-colors.svg")
 7output_path = os.path.join(output_folder, "change-svg-gradient-colors.svg")
 8os.makedirs(output_folder, exist_ok=True)
 9
10new_gradient_colors = ["#2563eb", "#22c55e", "#facc15"]
11
12with SVGDocument(input_path) as document:
13    stops = document.get_elements_by_tag_name("stop")
14
15    for index, stop in enumerate(stops):
16        color = new_gradient_colors[min(index, len(new_gradient_colors) - 1)]
17        stop.set_attribute("stop-color", color)
18
19    document.save(output_path)

If the gradient contains more stops than the list, the example reuses the last color. For production code, you can map colors by stop offset, by position in the gradient, or by an existing stop-color value.

The illustration below compares the original SVG gradient (a) with the result after updating the stop-color values on the gradient stops (b). The circle, inline-style element, and inherited group fill remain unchanged, so the image focuses on the gradient edit only.

Original SVG sample and result after changing gradient stop colors

Common Mistakes and Fixes

ProblemLikely causeFix
The color did not changeThe color is stored in style, a CSS rule, a gradient, or a parent groupInspect the SVG markup and update the actual color location
Only one element changedThe code used query_selector() and found only the first matchFor many attribute updates, prefer tag-name search as shown above. Use query_selector_all() only for edits supported by the returned nodes, such as text updates.
Inline styles were lostThe whole style attribute was overwrittenUpdate only the needed CSS property and preserve other declarations
Gradient color stayed the sameThe visible color comes from gradient <stop> elementsUpdate stop-color on the <stop> nodes inside the gradient
Matching colors were skippedThe file uses different spellings such as red, #f00, or rgb(255,0,0)Handle each expected color format or normalize colors before comparing values
The output file is unchangedThe edited document was not saved or the wrong file was openedCall document.save(output_path) after edits and verify the input path

FAQ

How do I change SVG fill color in Python?

Load the SVG with SVGDocument, find the element with document.root_element.query_selector() or get_elements_by_tag_name(), then call element.set_attribute("fill", "#2e86de") and save the document with document.save(output_path).

How do I change SVG stroke color in Python?

Load the SVG with SVGDocument, select the element that draws the outline, then call element.set_attribute("stroke", "#1b4f72"). If the outline is missing or too thin, also set stroke-width, for example element.set_attribute("stroke-width", "4"), and save the SVG.

Can I replace one color in the whole SVG file?

Yes. Iterate through the relevant elements and update matching fill, stroke, style, or stop-color values. Literal matching works only when the color spelling in the SVG matches the value your code compares.

Why does changing fill not affect my SVG?

The visible color may come from an inline style, a CSS rule, a gradient, or an inherited parent style. Inspect the SVG markup before choosing the edit.

Can I change SVG gradient colors?

Yes. Load the SVG with SVGDocument, iterate through gradient stops with document.get_elements_by_tag_name("stop"), update each stop with stop.set_attribute("stop-color", new_color), and save the edited file with document.save(output_path).

Related Articles