SVG Path Objects and Parser
svg.path is a collection of objects that implement the different path commands in SVG, and a parser for SVG path definitions. It provides classes for various path segments (Line, Arc, CubicBezier, QuadraticBezier) and a `Path` object to collect them. As of version 7.0, it's actively maintained and frequently updated to reflect improvements and address edge cases in SVG path parsing.
Warnings
- breaking In version 7.0, the `Move` class was reclassified as a `PathSegment` for type annotation consistency. If you were using `isinstance()` to check for drawing commands (i.e., expecting `Move` *not* to be a `PathSegment`), your code will break.
- breaking In version 4.0, the `Path` object no longer has a `closed` attribute.
- gotcha For `CubicBezier` and `Arc` segments, setting `min_depth` to 0 (the recursion depth for approximation) can lead to inaccurate representations, especially for `CubicBezier` where it might approximate to a straight line. The default value is 5.
- gotcha SVG path data can use implicit commands (e.g., `M 10 20 30 40` implies `M 10 20 L 30 40`). The parser handles this correctly, but developers should be aware of this SVG specification detail when constructing or debugging path strings manually.
Install
-
pip install svg.path
Imports
- Path
from svg.path import Path
- Line
from svg.path import Line
- Arc
from svg.path import Arc
- CubicBezier
from svg.path import CubicBezier
- QuadraticBezier
from svg.path import QuadraticBezier
- Close
from svg.path import Close
- parse_path
from svg.path import parse_path
Quickstart
from svg.path import parse_path, Path, Line, Arc
import cmath # For complex numbers used by svg.path
# Parse an SVG path string
path_data = "M 10 10 L 100 10 L 50 50 Z"
path = parse_path(path_data)
print(f"Path has {len(path)} segments.")
for i, segment in enumerate(path):
print(f"Segment {i}: {type(segment).__name__} from {segment.start} to {segment.end}")
# Example: Get a point along the segment
if hasattr(segment, 'point'):
mid_point = segment.point(0.5)
print(f" Midpoint: ({mid_point.real:.2f}, {mid_point.imag:.2f})")
# Construct a path programmatically
p = Path([
Line(start=cmath.rect(1, cmath.pi/2), end=cmath.rect(10, cmath.pi/2)), # Example using complex numbers
Line(start=(10+0j), end=(10+50j)),
Arc(start=(10+50j), radius=(20,20), rotation=0, large_arc=True, sweep=True, end=(30+70j))
])
print(f"\nProgrammatic path has {len(p)} segments.")