A Python library to create SVG drawings programmatically.
Helper functions, unit handling, color utilities, and extension modules for specialized functionality and enhanced productivity.
Functions for creating and managing color values in SVG-compatible formats.
def rgb(r=0, g=0, b=0, mode='RGB'):
"""
Convert RGB values to SVG color string
Args:
r: Red component (0-255 for RGB mode, 0-100 for % mode) (default: 0)
g: Green component (0-255 for RGB mode, 0-100 for % mode) (default: 0)
b: Blue component (0-255 for RGB mode, 0-100 for % mode) (default: 0)
mode: Color mode 'RGB' or '%' (default: 'RGB')
Returns:
str: RGB color string in format 'rgb(r, g, b)' or 'rgb(r%, g%, b%)'
"""Usage Examples:
import svgwrite
dwg = svgwrite.Drawing('colors.svg', size=('300px', '200px'))
# RGB colors with integer values (0-255)
red = svgwrite.rgb(255, 0, 0) # 'rgb(255, 0, 0)'
green = svgwrite.rgb(0, 255, 0) # 'rgb(0, 255, 0)'
blue = svgwrite.rgb(0, 0, 255) # 'rgb(0, 0, 255)'
purple = svgwrite.rgb(128, 0, 128) # 'rgb(128, 0, 128)'
# RGB colors with percentage values
light_red = svgwrite.rgb(100, 50, 50, '%') # 'rgb(100%, 50%, 50%)'
light_green = svgwrite.rgb(50, 100, 50, '%') # 'rgb(50%, 100%, 50%)'
# Use colors in shapes
dwg.add(dwg.rect((20, 20), (50, 40), fill=red))
dwg.add(dwg.rect((80, 20), (50, 40), fill=green))
dwg.add(dwg.rect((140, 20), (50, 40), fill=blue))
dwg.add(dwg.circle((50, 120), 25, fill=purple))
dwg.add(dwg.circle((150, 120), 25, fill=light_red))
# Dynamic color generation
for i in range(5):
intensity = i * 50
color = svgwrite.rgb(intensity, 0, 255 - intensity)
dwg.add(dwg.rect((20 + i*40, 80), (30, 30), fill=color))Comprehensive unit handling system for precise dimensional control in SVG graphics.
class Unit:
"""
Unit class for adding measurement units to numeric values
"""
def __init__(unit='cm'):
"""
Create unit instance
Args:
unit: Unit string (cm, mm, px, em, etc.) (default: 'cm')
"""
def __rmul__(other):
"""
Add unit string to numeric value (e.g., 5*cm => '5cm')
Args:
other: Numeric value to apply unit to
Returns:
str: Value with unit suffix
"""
def __call__(*args):
"""
Add unit strings to multiple arguments
Args:
*args: List of numeric values
Returns:
str: Comma-separated values with units (e.g., cm(1,2,3) => '1cm,2cm,3cm')
"""
# Predefined unit instances
cm = Unit('cm') # Centimeters
mm = Unit('mm') # Millimeters
px = Unit('px') # Pixels
em = Unit('em') # Relative to font size
ex = Unit('ex') # Relative to x-height
inch = Unit('in') # Inches
pc = Unit('pc') # Picas
pt = Unit('pt') # Points
percent = Unit('%') # Percentage
deg = Unit('deg') # Degrees
grad = Unit('grad') # Gradians
rad = Unit('rad') # Radians
Hz = Unit('Hz') # Hertz
kHz = Unit('kHz') # KilohertzUsage Examples:
import svgwrite
dwg = svgwrite.Drawing('units.svg', size=(500, 400))
# Using predefined units with multiplication
rect1 = dwg.rect(insert=(1*svgwrite.cm, 1*svgwrite.cm),
size=(3*svgwrite.cm, 2*svgwrite.cm),
fill='lightblue')
dwg.add(rect1)
# Using unit call syntax for coordinate lists
line = dwg.line(start=svgwrite.mm(10, 10),
end=svgwrite.mm(50, 30),
stroke='red', stroke_width=2*svgwrite.px)
dwg.add(line)
# Mixed units in single element
circle = dwg.circle(center=(2*svgwrite.inch, 3*svgwrite.cm),
r=15*svgwrite.mm,
fill='green')
dwg.add(circle)
# Font-relative units for text
text = dwg.text('Relative Size', insert=(50*svgwrite.px, 100*svgwrite.px),
font_size=2*svgwrite.em,
dx=svgwrite.ex(0, 1, 2, 3)) # Multiple relative offsets
dwg.add(text)
# Percentage units for responsive layouts
responsive_rect = dwg.rect(insert=(10*svgwrite.percent, 20*svgwrite.percent),
size=(80*svgwrite.percent, 30*svgwrite.percent),
fill='orange', fill_opacity=0.7)
dwg.add(responsive_rect)
# Angular units for rotations
rotated_rect = dwg.rect(insert=(200*svgwrite.px, 150*svgwrite.px),
size=(60*svgwrite.px, 40*svgwrite.px),
fill='purple',
transform=f'rotate({45*svgwrite.deg} 230 170)')
dwg.add(rotated_rect)
# Custom unit instances
custom_unit = svgwrite.Unit('vw') # Viewport width
viewport_rect = dwg.rect(insert=(5*custom_unit, 5*custom_unit),
size=(20*custom_unit, 15*custom_unit),
fill='navy', fill_opacity=0.5)
dwg.add(viewport_rect)Additional container elements for advanced document organization.
def g(**extra):
"""
Create group container for organizing related elements
Args:
**extra: SVG attributes (id, class, transform, etc.)
Returns:
Group: Group element with Transform and Presentation mixins
"""
def defs(**extra):
"""
Create definitions container for reusable elements
Args:
**extra: SVG attributes
Returns:
Defs: Definitions element inheriting from Group
"""
def use(href, insert=None, size=None, **extra):
"""
Create element reference to instantiate defined elements
Args:
href: Reference to element with ID (element or ID string)
insert: Insertion point as (x, y) tuple (default: None)
size: Override size as (width, height) tuple (default: None)
**extra: Additional SVG attributes
Returns:
Use: Use element with Transform, XLink, and Presentation mixins
"""
def symbol(**extra):
"""
Create symbol definition for reusable graphics
Args:
**extra: SVG attributes (viewBox, preserveAspectRatio, etc.)
Returns:
Symbol: Symbol element with ViewBox and Presentation mixins
"""
def marker(insert=None, size=None, orient=None, **extra):
"""
Create marker definition for line endings and decorations
Args:
insert: Reference point as (x, y) tuple (default: None)
size: Marker size as (width, height) tuple (default: None)
orient: Orientation 'auto', 'auto-start-reverse', or angle (default: None)
**extra: Additional marker attributes
Returns:
Marker: Marker element with ViewBox and Presentation mixins
"""
def a(href, **extra):
"""
Create hyperlink container for interactive elements
Args:
href: Target URL or URI for the hyperlink
**extra: SVG attributes (target, title, etc.)
Returns:
Hyperlink: Hyperlink element with Transform and Presentation mixins
"""
def script(href=None, content="", **extra):
"""
Create script element for client-side scripting
Args:
href: External script file URL (default: None)
content: Inline script content (default: "")
**extra: Additional script attributes
Returns:
Script: Script element for JavaScript or other client-side languages
"""
def style(content="", **extra):
"""
Create style element for embedded CSS
Args:
content: CSS stylesheet content (default: "")
**extra: Additional style attributes (media, type, etc.)
Returns:
Style: Style element for CSS stylesheets
"""Usage Examples:
import svgwrite
dwg = svgwrite.Drawing('containers.svg', size=('400px', '300px'))
# Create definitions
defs = dwg.defs()
# Define reusable symbol
star_symbol = dwg.symbol(id='star', viewBox='0 0 20 20')
star_points = [(10, 0), (12, 7), (20, 7), (14, 12), (16, 20),
(10, 15), (4, 20), (6, 12), (0, 7), (8, 7)]
star_shape = dwg.polygon(points=star_points, fill='gold', stroke='orange')
star_symbol.add(star_shape)
defs.add(star_symbol)
# Define arrow marker
arrow_marker = dwg.marker(insert=(0, 3), size=(10, 6), orient='auto', id='arrow')
arrow_path = dwg.path(d='M 0,0 L 0,6 L 9,3 z', fill='red')
arrow_marker.add(arrow_path)
defs.add(arrow_marker)
dwg.add(defs)
# Use symbols multiple times
star1 = dwg.use(star_symbol, insert=(50, 50), size=(40, 40))
dwg.add(star1)
star2 = dwg.use(star_symbol, insert=(150, 50), size=(30, 30))
star2.rotate(45, center=(165, 65))
dwg.add(star2)
star3 = dwg.use(star_symbol, insert=(250, 50), size=(50, 50))
star3.scale(1, 0.5) # Squashed star
dwg.add(star3)
# Group with transformations
group = dwg.g(transform='translate(100, 150) rotate(30)')
group.add(dwg.rect((0, 0), (60, 40), fill='lightblue'))
group.add(dwg.text('Grouped', insert=(10, 25), font_size='12px'))
dwg.add(group)
# Interactive hyperlink container
link_group = dwg.a(href='https://example.com', target='_blank')
link_group.add(dwg.rect((50, 120), (100, 30), fill='lightgreen', stroke='green'))
link_group.add(dwg.text('Click Me', insert=(60, 140), font_size='14px'))
dwg.add(link_group)
# Embedded CSS styles
css_styles = """
.glow { filter: drop-shadow(0 0 5px #00ff00); }
.pulse { animation: pulse 2s infinite; }
"""
style_elem = dwg.style(content=css_styles)
dwg.add(style_elem)
# Client-side scripting
js_code = """
function handleClick(evt) {
evt.target.style.fill = 'red';
}
"""
script_elem = dwg.script(content=js_code)
dwg.add(script_elem)
# Line with marker
arrow_line = dwg.line((50, 200), (200, 250), stroke='black', stroke_width=2,
marker_end='url(#arrow)')
dwg.add(arrow_line)Specialized utility functions for creating complex geometric shapes.
# Shape generation utilities (svgwrite.extensions.shapes)
def ngon(num_corners, edge_length=None, radius=None, rotation=0.):
"""
Generate regular polygon vertices
Args:
num_corners: Number of polygon corners/sides
edge_length: Length of each edge (default: None)
radius: Radius from center to vertex (default: None)
rotation: Rotation angle in radians (default: 0.)
Returns:
list: List of (x, y) coordinate tuples for polygon vertices
"""
def star(spikes, r1, r2, rotation=0.):
"""
Generate star shape vertices
Args:
spikes: Number of star points/spikes
r1: Outer radius (to spike tips)
r2: Inner radius (to valley points)
rotation: Rotation angle in radians (default: 0.)
Returns:
list: List of (x, y) coordinate tuples for star vertices
"""
# Vertex transformation utilities
def translate(vertices, delta_x, delta_y):
"""
Translate vertex coordinates
Args:
vertices: List of (x, y) coordinate tuples
delta_x: Translation in X direction
delta_y: Translation in Y direction
Returns:
list: Translated vertex coordinates
"""
def scale(vertices, scale_x, scale_y):
"""
Scale vertex coordinates
Args:
vertices: List of (x, y) coordinate tuples
scale_x: Scale factor for X coordinates
scale_y: Scale factor for Y coordinates
Returns:
list: Scaled vertex coordinates
"""
def rotate(vertices, delta):
"""
Rotate vertices around origin
Args:
vertices: List of (x, y) coordinate tuples
delta: Rotation angle in degrees
Returns:
list: Rotated vertex coordinates
"""
def centroid(vertices):
"""
Calculate centroid (center point) of vertices
Args:
vertices: List of (x, y) coordinate tuples
Returns:
tuple: Centroid coordinates as (x, y)
"""Usage Examples:
import svgwrite
from svgwrite.extensions.shapes import ngon, star, translate, scale, rotate, centroid
dwg = svgwrite.Drawing('shapes-ext.svg', size=('500px', '400px'))
# Regular polygons
triangle = ngon(3, radius=30)
pentagon = ngon(5, edge_length=40)
octagon = ngon(8, radius=25, rotation=0.3927) # Rotated flat side up (22.5°)
# Position and add polygons
triangle_pos = translate(triangle, 80, 80)
pentagon_pos = translate(pentagon, 200, 80)
octagon_pos = translate(octagon, 350, 80)
dwg.add(dwg.polygon(triangle_pos, fill='red', stroke='darkred'))
dwg.add(dwg.polygon(pentagon_pos, fill='blue', stroke='darkblue'))
dwg.add(dwg.polygon(octagon_pos, fill='green', stroke='darkgreen'))
# Star shapes
star4 = star(4, r1=40, r2=20) # 4-pointed star
star6 = star(6, r1=35, r2=15) # 6-pointed star
star8 = star(8, r1=30, r2=12, rotation=0.3927) # 8-pointed star, rotated (22.5°)
# Position stars
star4_pos = translate(star4, 80, 200)
star6_pos = translate(star6, 200, 200)
star8_pos = translate(star8, 350, 200)
dwg.add(dwg.polygon(star4_pos, fill='orange', stroke='darkorange'))
dwg.add(dwg.polygon(star6_pos, fill='purple', stroke='indigo'))
dwg.add(dwg.polygon(star8_pos, fill='gold', stroke='goldenrod'))
# Complex transformations
base_shape = ngon(6, radius=25)
# Scale and position variations
scaled_shape = scale(base_shape, 1.5, 0.8) # Stretch horizontally
scaled_pos = translate(scaled_shape, 80, 320)
rotated_shape = rotate(base_shape, 30) # Rotate 30 degrees
rotated_pos = translate(rotated_shape, 200, 320)
# Combined transformations
complex_shape = rotate(scale(base_shape, 1.2, 1.8), 45)
complex_pos = translate(complex_shape, 350, 320)
dwg.add(dwg.polygon(scaled_pos, fill='lightblue', stroke='navy'))
dwg.add(dwg.polygon(rotated_pos, fill='lightgreen', stroke='forestgreen'))
dwg.add(dwg.polygon(complex_pos, fill='lightyellow', stroke='olive'))
# Mark centroids
for shape_vertices, color in [
(triangle_pos, 'darkred'),
(pentagon_pos, 'darkblue'),
(octagon_pos, 'darkgreen'),
(star4_pos, 'darkorange'),
(star6_pos, 'indigo'),
(star8_pos, 'goldenrod')
]:
center = centroid(shape_vertices)
dwg.add(dwg.circle(center, 2, fill=color))Specialized functionality for enhanced compatibility with Inkscape SVG editor.
# Inkscape extension (svgwrite.extensions.inkscape)
class Inkscape:
"""
Support for Inkscape-specific features and extensions
"""
def __init__(drawing):
"""
Initialize Inkscape extension for a drawing
Args:
drawing: SVGWrite Drawing instance
"""
def layer(label=None, locked=False, **kwargs):
"""
Create Inkscape layer (special group with layer attributes)
Args:
label: Layer name for Inkscape layer panel (default: None)
locked: Lock layer to prevent editing (default: False)
**kwargs: Additional group attributes
Returns:
Group: Group element with Inkscape layer attributes
"""Usage Examples:
import svgwrite
from svgwrite.extensions.inkscape import Inkscape
dwg = svgwrite.Drawing('inkscape.svg', size=('400px', '300px'))
# Initialize Inkscape extension
inkscape = Inkscape(dwg)
# Create layers for organized editing in Inkscape
background_layer = inkscape.layer(label='Background', locked=False)
background_layer.add(dwg.rect((0, 0), ('100%', '100%'), fill='lightgray'))
dwg.add(background_layer)
shapes_layer = inkscape.layer(label='Shapes', locked=False)
shapes_layer.add(dwg.circle((100, 100), 40, fill='red'))
shapes_layer.add(dwg.rect((200, 60), (80, 80), fill='blue'))
dwg.add(shapes_layer)
text_layer = inkscape.layer(label='Text', locked=True) # Locked layer
text_layer.add(dwg.text('Layer Text', insert=(50, 200), font_size='18px'))
dwg.add(text_layer)
effects_layer = inkscape.layer(label='Effects')
# Add elements with filters or other effects
gradient = dwg.linearGradient((0, 0), (100, 0), id='grad')
gradient.add_stop_color(0, 'yellow')
gradient.add_stop_color(1, 'orange')
dwg.defs.add(gradient)
effects_layer.add(dwg.ellipse((300, 150), (60, 30),
fill=gradient.get_paint_server()))
dwg.add(effects_layer)Access to library version details and compatibility information.
# Version constants
VERSION = "1.4.3" # String version number
__version__ = "1.4.3" # Standard Python version attribute
version = (1, 4, 3, 'release') # Tuple version informationUsage Examples:
import svgwrite
# Check library version
print(f"SVGWrite version: {svgwrite.VERSION}")
print(f"Version tuple: {svgwrite.version}")
# Version-dependent feature usage
if svgwrite.version >= (1, 4, 0):
# Use features available in 1.4.0+
dwg = svgwrite.Drawing('modern.svg', profile='full')
# Add advanced features...
else:
# Fallback for older versions
dwg = svgwrite.Drawing('basic.svg', profile='tiny')
# Use basic features only...
# Include version in SVG metadata
dwg = svgwrite.Drawing('versioned.svg')
dwg.add(dwg.desc(f'Created with SVGWrite {svgwrite.VERSION}'))Install with Tessl CLI
npx tessl i tessl/pypi-svgwrite