Programmatically generate SVG (vector) images, animations, and interactive Jupyter widgets
1# drawSvg 2 3This is a Python 3 library for programmatically generating SVG images (vector drawings) and rendering them or displaying them in an iPython notebook. 4 5Most common SVG tags are supported and others can easily be added by writing a small subclass of `DrawableBasicElement` or `DrawableParentElement`. 6 7# Install 8drawSvg is available on PyPI: 9 10``` 11$ pip3 install drawSvg 12``` 13 14# Examples 15 16### Basic drawing elements 17```python 18import drawSvg as draw 19 20d = draw.Drawing(200, 100, origin='center') 21 22d.append(draw.Lines(-80, -45, 23 70, -49, 24 95, 49, 25 -90, 40, 26 close=False, 27 fill='#eeee00', 28 stroke='black')) 29 30d.append(draw.Rectangle(0,0,40,50, fill='#1248ff')) 31d.append(draw.Circle(-40, -10, 30, 32 fill='red', stroke_width=2, stroke='black')) 33 34p = draw.Path(stroke_width=2, stroke='green', 35 fill='black', fill_opacity=0.5) 36p.M(-30,5) # Start path at point (-30, 5) 37p.l(60,30) # Draw line to (60, 30) 38p.h(-70) # Draw horizontal line to x=-70 39p.Z() # Draw line to start 40d.append(p) 41 42d.append(draw.ArcLine(60,-20,20,60,270, 43 stroke='red', stroke_width=5, fill='red', fill_opacity=0.2)) 44d.append(draw.Arc(60,-20,20,60,270,cw=False, 45 stroke='green', stroke_width=3, fill='none')) 46d.append(draw.Arc(60,-20,20,270,60,cw=True, 47 stroke='blue', stroke_width=1, fill='black', fill_opacity=0.3)) 48 49d.setPixelScale(2) # Set number of pixels per geometry unit 50#d.setRenderSize(400,200) # Alternative to setPixelScale 51d.saveSvg('example.svg') 52d.savePng('example.png') 53 54# Display in iPython notebook 55d.rasterize() # Display as PNG 56d # Display as SVG 57``` 58 59![Example output image](https://github.com/cduck/drawSvg/raw/master/example1.png) 60 61### Gradients 62```python 63import drawSvg as draw 64 65d = draw.Drawing(1.5, 0.8, origin='center') 66 67d.draw(draw.Rectangle(-0.75,-0.5,1.5,1, fill='#ddd')) 68 69# Create gradient 70gradient = draw.RadialGradient(0,-0.35,0.7*10) 71gradient.addStop(0.5/0.7/10, 'green', 1) 72gradient.addStop(1/10, 'red', 0) 73 74# Draw a shape to fill with the gradient 75p = draw.Path(fill=gradient, stroke='black', stroke_width=0.002) 76p.arc(0,-0.35,0.7,30,120) 77p.arc(0,-0.35,0.5,120,30,cw=True, includeL=True) 78p.Z() 79d.append(p) 80 81# Draw another shape to fill with the same gradient 82p = draw.Path(fill=gradient, stroke='red', stroke_width=0.002) 83p.arc(0,-0.35,0.75,130,160) 84p.arc(0,-0.35,0,160,130,cw=True, includeL=True) 85p.Z() 86d.append(p) 87 88# Another gradient 89gradient2 = draw.LinearGradient(0.1,-0.35,0.1+0.6,-0.35+0.2) 90gradient2.addStop(0, 'green', 1) 91gradient2.addStop(1, 'red', 0) 92d.append(draw.Rectangle(0.1,-0.35,0.6,0.2, 93 stroke='black', stroke_width=0.002, 94 fill=gradient2)) 95 96# Display 97d.setRenderSize(w=600) 98d 99``` 100 101![Example output image](https://github.com/cduck/drawSvg/raw/master/example2.png) 102 103### Duplicate geometry and clip paths 104```python 105import drawSvg as draw 106 107d = draw.Drawing(1.4, 1.4, origin='center') 108 109# Define clip path 110clip = draw.ClipPath() 111clip.append(draw.Rectangle(-.25,.25-1,1,1)) 112 113# Draw a cropped circle 114c = draw.Circle(0,0,0.5, stroke_width='0.01', stroke='black', 115 fill_opacity=0.3, clip_path=clip, 116 id='circle') 117d.append(c) 118 119# Make a transparent copy, cropped again 120g = draw.Group(opacity=0.5, clip_path=clip) 121g.append(draw.Use('circle', 0.25,0.1)) 122d.append(g) 123 124# Display 125d.setRenderSize(400) 126d.rasterize() 127``` 128 129![Example output image](https://github.com/cduck/drawSvg/raw/master/example3.png) 130 131### Implementing other SVG tags 132```python 133import drawSvg as draw 134 135# Subclass DrawingBasicElement if it cannot have child nodes 136# Subclass DrawingParentElement otherwise 137# Subclass DrawingDef if it must go between <def></def> tags in an SVG 138class Hyperlink(draw.DrawingParentElement): 139 TAG_NAME = 'a' 140 def __init__(self, href, target=None, **kwargs): 141 # Other init logic... 142 # Keyword arguments to super().__init__() correspond to SVG node 143 # arguments: stroke_width=5 -> stroke-width="5" 144 super().__init__(href=href, target=target, **kwargs) 145 146d = draw.Drawing(1, 1.2, origin='center') 147 148# Create hyperlink 149hlink = Hyperlink('https://www.python.org', target='_blank', 150 transform='skewY(-30)') 151# Add child elements 152hlink.append(draw.Circle(0,0,0.5, fill='green')) 153hlink.append(draw.Text('Hyperlink',0.2, 0,0, center=0.6, fill='white')) 154 155# Draw and display 156d.append(hlink) 157d.setRenderSize(200) 158d 159``` 160 161![Example output image](https://github.com/cduck/drawSvg/blob/master/example4.svg) 162