{"id":8691,"library":"svgpathtools","title":"svgpathtools","description":"svgpathtools is a Python library (version 1.7.2) for manipulating and analyzing SVG Path objects and Bézier curves. It offers functions to read, write, and display SVG files, convert Bézier segments to polynomials, compute tangents, curvature, intersections, and perform various geometric transformations. It is actively maintained with releases as needed.","status":"active","version":"1.7.2","language":"en","source_language":"en","source_url":"https://github.com/mathandy/svgpathtools","tags":["svg","path","bezier","vector graphics","geometry","manipulation","parsing"],"install":[{"cmd":"pip install svgpathtools","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Required for numerical operations, especially vector inputs and geometric calculations.","package":"numpy","optional":false},{"reason":"Required for writing SVG files using `wsvg()` and for rendering path data.","package":"svgwrite","optional":false},{"reason":"Optional, but recommended for performance, particularly for integration-related tasks.","package":"scipy","optional":true}],"imports":[{"note":"Main class for composite paths.","symbol":"Path","correct":"from svgpathtools import Path"},{"note":"Classes for individual path segments.","symbol":"Line, QuadraticBezier, CubicBezier, Arc","correct":"from svgpathtools import Line, QuadraticBezier, CubicBezier, Arc"},{"note":"Function to read paths from an SVG file.","symbol":"svg2paths","correct":"from svgpathtools import svg2paths"},{"note":"Function to write paths to an SVG file.","symbol":"wsvg","correct":"from svgpathtools import wsvg"},{"note":"While `svgpathtools` was inspired by `svg.path`, its classes and functions are part of the `svgpathtools` namespace. Direct imports from `svg.path` will result in different objects and methods.","wrong":"from svg.path import Path","symbol":"Path","correct":"from svgpathtools import Path"}],"quickstart":{"code":"from svgpathtools import svg2paths, wsvg, Path, Line, CubicBezier\nimport os\n\n# Create a dummy SVG file for demonstration\nwith open('example.svg', 'w') as f:\n    f.write('<svg width=\"200\" height=\"200\">')\n    f.write('<path d=\"M10 10 L100 10 L100 100 L10 100 Z\" fill=\"blue\"/>')\n    f.write('</svg>')\n\n# 1. Read paths from an existing SVG file\npaths, attributes = svg2paths('example.svg')\nprint(f\"Read {len(paths)} path(s) from example.svg\")\n\n# 2. Manipulate a path (e.g., scale the first path)\nif paths:\n    original_path = paths[0]\n    # Scale the path by 0.5\n    scaled_path = original_path.scaled(0.5)\n    paths[0] = scaled_path\n    print(f\"Scaled the first path. New length: {scaled_path.length():.2f}\")\n\n# 3. Create a new path programmatically\nnew_segment1 = Line(start=10+10j, end=50+100j)\nnew_segment2 = CubicBezier(start=50+100j, control1=150+50j, control2=50+150j, end=150+100j)\nnew_path = Path(new_segment1, new_segment2)\n\n# Add the new path to the list and assign attributes\npaths.append(new_path)\nattributes.append({'fill': 'red', 'stroke': 'black', 'stroke-width': '2'})\n\n# 4. Write the modified and new paths to a new SVG file\nwsvg(paths, attributes=attributes, filename='output.svg', openinbrowser=False)\nprint(\"Modified paths written to output.svg\")\n\n# Clean up dummy file (optional)\nos.remove('example.svg')\n# os.remove('output.svg') # Uncomment to remove output file after inspection","lang":"python","description":"This quickstart demonstrates how to read paths from an SVG file, modify an existing path (e.g., scaling it), create a new path using segment classes (Line, CubicBezier), and then write all paths to a new SVG file. Coordinates are handled as complex numbers (x + yj)."},"warnings":[{"fix":"Manually apply transformations to paths after reading, or use the experimental `Document` class for improved I/O which might handle transformations better (check its documentation). See GitHub issue #16 for discussion and manual transformation examples.","message":"The `svg2paths()` function currently ignores SVG group (<g>) transformations when parsing files. Paths inside groups will be read without the parent group's transformations applied.","severity":"gotcha","affected_versions":"All versions up to 1.7.2"},{"fix":"For potentially discontinuous paths, consider using the `Path.continuous_subpaths()` method to break them into continuous components as a workaround.","message":"Some functionality within `svgpathtools`, particularly concerning discontinuous `Path` objects, has not been fully tested and might lead to unexpected behavior.","severity":"gotcha","affected_versions":"All versions up to 1.7.2"},{"fix":"If encountering issues with small scaling factors, consider applying scaling to individual path segment parameters or control points manually, or scaling the SVG in a graphics editor before processing.","message":"The `Path.scaled()` method might produce visual artifacts or unexpected 'cavities' in paths when using very small scaling factors (e.g., below ~0.45). This could be due to internal segmentation or precision issues.","severity":"gotcha","affected_versions":"All versions up to 1.7.2"},{"fix":"Ensure you are using the latest version of `svgpathtools`. If discrepancies persist, consider installing directly from the GitHub source if comfortable, or check the `svg_to_paths.py` source file for the exact function signature on your installed version.","message":"The `svg2paths` function's argument signature in older installed versions (e.g., via `pip3`) might not perfectly match the latest documentation or GitHub source, particularly regarding `convert_circles_to_paths` and `convert_ellipses_to_paths` arguments.","severity":"deprecated","affected_versions":"Older pip installations prior to 1.6.0, specific to how `setup.py` was handled."}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Validate the SVG `d` string against the official SVG Path Data specification. Simplify the path in the originating software, or manually inspect and correct the `d` attribute string. Ensure all path commands (M, L, C, A, Z, etc.) are correctly capitalized (for absolute coordinates) or lowercase (for relative coordinates) and have the correct number of parameters.","cause":"This error, or similar ones like 'list index out of range', often occurs when `svgpathtools.parse_path()` attempts to parse an SVG path `d` attribute string that is malformed or contains unexpected characters/commands. This can happen with complex SVG exports from graphic design software (e.g., Inkscape) that might use non-standard or subtly incorrect syntax for path commands.","error":"could not convert string to float: 's'"},{"fix":"After reading the paths using `svg2paths()`, you need to manually traverse the SVG's DOM (e.g., using `xml.etree.ElementTree`) to identify parent group transformations and apply them to the respective child paths. The `Document` class (experimental) aims to provide a higher-level API that might simplify this in the future.","cause":"The `svg2paths()` function processes path elements directly and does not automatically apply transformations defined on parent `<g>` (group) elements in the SVG document structure.","error":"SVG groups are ignored. Especially transformations acting on the paths inside the group."}]}