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.

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.

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.

Sample SVG with fill stroke inline style inherited fill and gradient colors

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 performs four operations: it loads an SVG document, finds the target element with query_selector(), changes color-related attributes, and writes the edited file with SVGDocument.save(). Use the if circle is not None check when the input SVG may change or come from different sources.

The illustration below shows the source SVG and the result after changing the circle fill, stroke, and stroke-width attributes. It focuses on the first workflow only, so the visual comparison stays readable.

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 literal 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 intentionally compares literal color strings. 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, "gradient-recolored.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.

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 matchUse tag-name search, query_selector_all(), or XPath when all matches must be edited
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