Programmatically generate SVG (vector) images, animations, and interactive Jupyter widgets

Add marker SVG element, add to example 1

Changed files
+45 -1
drawSvg
examples
+20 -1
README.md
···
```python
import drawSvg as draw
-
d = draw.Drawing(200, 100, origin='center')
+
d = draw.Drawing(200, 100, origin='center', displayInline=False)
+
# Draw an irregular polygon
d.append(draw.Lines(-80, -45,
70, -49,
95, 49,
···
fill='#eeee00',
stroke='black'))
+
# Draw a rectangle
d.append(draw.Rectangle(0,0,40,50, fill='#1248ff'))
+
+
# Draw a circle
d.append(draw.Circle(-40, -10, 30,
fill='red', stroke_width=2, stroke='black'))
+
# Draw an arbitrary path (a triangle in this case)
p = draw.Path(stroke_width=2, stroke='green',
fill='black', fill_opacity=0.5)
p.M(-30,5) # Start path at point (-30, 5)
···
p.Z() # Draw line to start
d.append(p)
+
# Draw multiple circular arcs
d.append(draw.ArcLine(60,-20,20,60,270,
stroke='red', stroke_width=5, fill='red', fill_opacity=0.2))
d.append(draw.Arc(60,-20,20,60,270,cw=False,
stroke='green', stroke_width=3, fill='none'))
d.append(draw.Arc(60,-20,20,270,60,cw=True,
stroke='blue', stroke_width=1, fill='black', fill_opacity=0.3))
+
+
# Draw arrows
+
arrow = draw.Marker(-0.1, -0.5, 0.9, 0.5, scale=4, orient='auto')
+
arrow.append(draw.Lines(-0.1, -0.5, -0.1, 0.5, 0.9, 0, fill='red', close=True))
+
p = draw.Path(stroke='red', stroke_width=2, fill='none',
+
marker_end=arrow) # Add an arrow to the end of a path
+
p.M(20, -40)
+
p.L(20, -27)
+
p.L(0, -20)
+
d.append(p)
+
d.append(draw.Line(30, -20, 0, -10,
+
stroke='red', stroke_width=2, fill='none',
+
marker_end=arrow)) # Add an arrow to the end of a line
d.setPixelScale(2) # Set number of pixels per geometry unit
#d.setRenderSize(400,200) # Alternative to setPixelScale
+20
drawSvg/defs.py
···
def __init__(self, tag_name, **args):
super().__init__(**args)
self.TAG_NAME = tag_name
+
+
class Marker(DrawingDef):
+
''' A small drawing that can be placed at the ends of (or along) a path.
+
+
This can be used for arrow heads or points on a graph for example.
+
+
By default, units are multiples of stroke width.'''
+
TAG_NAME = 'marker'
+
def __init__(self, minx, miny, maxx, maxy, scale=1, orient='auto',
+
**kwargs):
+
width = maxx - minx
+
height = maxy - miny
+
kwargs = {
+
'markerWidth': width if scale == 1 else float(width) * scale,
+
'markerHeight': height if scale == 1 else float(height) * scale,
+
'viewBox': '{} {} {} {}'.format(minx, -maxy, width, height),
+
'orient': orient,
+
**kwargs,
+
}
+
super().__init__(**kwargs)
examples/example1.png

This is a binary file and will not be displayed.

+5
examples/example1.svg
···
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="400" height="200" viewBox="-100.0 -50.0 200 100">
<defs>
+
<marker markerWidth="4.0" markerHeight="4.0" viewBox="-0.1 -0.5 1.0 1.0" orient="auto" id="d0">
+
<path d="M-0.1,0.5 L-0.1,-0.5 L0.9,0 Z" fill="red" />
+
</marker>
</defs>
<path d="M-80,45 L70,49 L95,-49 L-90,-40" fill="#eeee00" stroke="black" />
<rect x="0" y="-50" width="40" height="50" fill="#1248ff" />
···
<circle cx="60" cy="20" r="20" stroke-dasharray="73.30382858376184 52.35987755982988" stroke-dashoffset="-31.41592653589793" stroke="red" stroke-width="5" fill="red" fill-opacity="0.2" />
<path d="M70.0,2.679491924311229 A20,20,0,1,0,59.99999999999999,40.0" stroke="green" stroke-width="3" fill="none" />
<path d="M59.99999999999999,40.0 A20,20,0,1,1,70.0,2.679491924311229" stroke="blue" stroke-width="1" fill="black" fill-opacity="0.3" />
+
<path d="M20,40 L20,27 L0,20" stroke="red" stroke-width="2" fill="none" marker-end="url(#d0)" />
+
<path d="M30,20 L0,10" stroke="red" stroke-width="2" fill="none" marker-end="url(#d0)" />
</svg>