Commands
arcto()
Syntax
arcto(x, y, ccw=False, close=False)
Draw a semicircular arc from the current pen location to the destination coordinates
arcto(cx, cy, x, y, radius, close=False)
Draw a circular arc within the angle created by the current point, a control point, and the destination point
Description
Draws a circular arc between the current point in the path and a destination point. When called with a single pair of x/y arguments, a full semicircle will connect the points. The ccw
argument can be set to True
to draw a mirror image of the arc.
To draw more complex arcs, include an additional x/y point to specify where the arc should ‘peak’ between the origin and destination points. An arc will be drawn at the corner of the triangle formed by the current point in the path, the control handle, and the destination point. Be sure to specify a radius
that is small enough to fit within that angle.
If the close
argument is set to True
, a lineto() command will be synthesized connecting the end of the arc to the origin point of the active subpath. The arcto() command must be called inside a bezier() context (or between beginpath() and endpath()).
Tutorial
Example
for i in range(9): with bezier(50,120, stroke=0.2, fill=None): arcto(100, 100-i*10)
with bezier(30, 50, stroke=0.2, fill=None): arcto(55,100, 80,50, 10)
bezier()
Syntax
bezier(points=[], smooth=False, **opts)
Draw a path based on a list of Point or Curve objects (or x/y tuples)
bezier(path, **opts)
Draw the provided Bezier object using the current graphics state
with bezier(x=0, y=0, **opts) as path: ... # drawing commands like moveto(), lineto(), arcto(), or curveto()
Draw a path based on a starting point and a sequence of ‘to’ commands
Description
Draws custom shapes that you define point-by-point. When called with a list as the first argument, the path will be constructed by drawing lines between the points specified in the list’s elements.
If the list contains more than three Points (or x
/y
tuples), the optional smooth
argument controls how line-segments are stitched together. By default straight lines will be used, but if smooth=True
the control handles will be positioned to minimize sharpness at the vertices.
Context Manager
When called as part of a with
statement, the optional x
& y
parameters set the location of the first point (origin) in the path. When not supplied in the call to bezier(), a starting location for the path should be given inside the indented block using the moveto() command.
Inside the with
block, a series of other drawing commands usually follows. You can call any of the ‘to’ commands (moveto(), lineto(), etc.) as well as any of the shape-drawing primitives (arc(), poly(), line(), and friends).
The path will be drawn after the last command in the indented block unless you set the plot
argument to False
. In these cases, you can plot() the path later on using the variable ‘captured’ in the as
clause of the with
statement. Note that the captured path-variable continues to be valid even outside of the indented-block.
Optional Parameters
plot
By default, paths are drawn as soon as the with
block completes (or immediately if a points
list was provided). But when called with plot=False
, a reference to the path will be returned but will not be drawn. You can manually add it to the canvas later on by passing the reference to the plot() command.
close
If True
, connect the final point in the path back to the starting position after the final drawing command. If omitted, it defaults to False
(or inherits the value from the last call to autoclosepath()).
fill
/ stroke
/ nib
Values passed to these parameters will override the state set in previous calls to the corrseponding fill(), stroke(), and pen() commands. If omitted, the path will inherit values from the graphics state when drawn.
cap
Set the shape of the path’s endpoints to BUTT
, SQUARE
or ROUND
. If omitted, the style defaults to BUTT
(or inherits the value from the last call to pen() that included a cap
parameter).
join
Set the shape of the path’s vertices to MITER
, BEVEL
or ROUND
. If omitted, the style defaults to MITER
(or inherits the value from the last call to pen() that included a join
parameter).
Tutorial
Examples
# define a path inside of a 'with' block with bezier(10, 10, stroke=0.2) as path: lineto(40, 10)
# define a list of x,y points for the path points = [(10, 10), (50, 90), (120, 50), (60, 10), (60, 60)] # draw the path twice; once with straight lines in light grey # and again with smoothed lines in dark grey nofill() bezier(points, stroke=0.75) bezier(points, stroke=0.25, smooth=True) # draw red dots at the point coordinates for x, y in points: arc(x, y, radius=3, fill='red')
curveto()
Syntax
curveto(h1x, h1y, h2x, h2y, x, y, close=False)
Description
Draws a curve between the current point in the path and a new ‘destination’ point. The pair of positional args, x
and y
, set the location of the destination point. The first two pairs of arguments set the location of the two ‘control points’ of the curve. These control points (or handles in Illustrator nomenclature) define the edge and slant of the curve.
If the close
argument is set to True
, a lineto() command will be synthesized connecting the end of the curve to the origin point of the active subpath.
The curveto() command must be called inside a bezier() context (or between beginpath() and endpath()).
Tutorial
Example
nofill() stroke(0.2) with bezier(10,50) as path: curveto(10,0, 110,100, 110,50)or
nofill() stroke(0.2) autoclosepath(False) beginpath(10, 50) curveto(10,0, 110,100, 110,50) path = endpath()
lineto()
Syntax
lineto(x, y, close=False)
Description
Draws a line between the current point in the path and a new destination point (set by the x
and y
parameters). If the close
argument is set to True
, a lineto() command will be synthesized connecting the end of the line-segment to the origin point of the active subpath.
The lineto() command must be called inside a bezier() context (or between beginpath() and endpath()).
Tutorial
Example
nofill() with bezier(10, 10, stroke=0.2) as path: lineto(40, 40) lineto(80, 40, close=True)or
nofill() stroke(0.2) beginpath(10, 10) lineto(40, 40) lineto(80, 40) endpath()
moveto()
Syntax
moveto(x, y)
Description
Moves the ‘current’ point of the path to a new location (x,y) without drawing a line from the previous point. This is conceptually similar to lifting your pen from the page and putting it down somewhere else before continuing to draw.
The moveto() command must be called inside a bezier() context (or between beginpath() and endpath()).
Tutorial
Example
with bezier(10, 10, stroke=0.2) as path: lineto(50, 100) moveto(60, 100) lineto(100, 100)or
stroke(0.2) beginpath(10, 10) lineto(50, 100) moveto(60, 100) lineto(100, 100) endpath()
Objects
Bezier
Syntax
Bezier()
Description
Every ‘shape’ you create in PlotDevice (see for example, rect(), oval(), bezier(), textpath()) is a Bezier object. This object has a number of properties to manipulate indivdual points in the path and can be passed to the bezier() command to draw it on the canvas.
Properties
path.bounds path.length path.contours path[i] # list elements are Curve objects
Methods
path.moveto(x, y) path.lineto(x, y) path.curveto(h1x, h1y, h2x, h2y, x, y) path.closepath() path.rect(x, y, width, height) path.oval(x, y, width, height) path.arc(x, y, radius) path.poly(x, y, radius)
Adding line segments and shapes to the path
path.contains(x, y)
Hit-testing
path.point(t) path.points(amount=100) path.addpoint(t) path.segmentlengths(relative=False, n=10)
Point interpolation (accessing and mutating coordinates within the Curve objects)
path.intersects(pth) path.intersect(pth, flatness=0.6) path.union(pth, flatness=0.6) path.difference(pth, flatness=0.6)
Boolean logical operators
path.fit(x=None, y=None, width=None, height=None, stretch=False)
Clamping the path to fit based on optional constraints
path.copy()
See the tutorial on paths to learn about all the methods.
With the segmentlengths() method you can define the math precision for point() and points() by making n a higher value (usually 10 is fine).
When you loop over a path it returns a list of Curve objects.
Context
Syntax
Context()
Description
An object wrapping a canvas and all the PlotDevice commands that operate on it. Context objects are primarily useful outside of the app—when you’re writing a plain python script that imports the plotdevice
module and uses the export() command to generate output.
Properties
ctx.canvas ctx.WIDTH ctx.HEIGHT
Methods
ctx.size() ctx.background() ctx.fill() ctx.stroke() ctx.export() # ... and all the other commands in the PlotDevice API
Example
#/usr/bin/env python3 from plotdevice import Context ctx = Context() ctx.size(400, 300) ctx.background('black', 'white', angle=0) ctx.fill('black', 'white', angle=180) ctx.rect(100,100, 200,100) ctx.export('output@2x.png')
Note that you would run this script from the command line with the ordinary python3
command—not the plotdevice
command line tool.
Curve
Syntax
Curve()
Description
Each element of a Bezier is a Curve object representing a PostScript-style drawing command. This object has a number of properties that describe the coordinates and handles of the path element.
See the tutorial on paths to learn about how Curve and Bezier objects interact.
Properties
curve.cmd curve.x curve.y curve.ctrl1.x curve.ctrl1.y curve.ctrl2.x curve.ctrl2.y
The cmd
property describes the type of line-segment this Curve belongs to. Its value can be MOVETO
, LINETO
, CURVETO
or CLOSE
. The x
& y
properties will be defined for all cmd
types except for CLOSE
. The ctrl1
& ctrl2
properties are only relevant if cmd
is CURVETO
(in which case, each property is a Point object).
Methods
curve.angle(point) curve.distance(point) curve.coordinates(distance, angle) curve.reflect(point, d=1.0, a=180)
These geometry helper-methods behave the same as those supported by the Point object. They implicitly use the Curve’s x
& y
properties. Be careful when blindly iterating through Curves since any with a cmd
of CLOSE
will have (0,0) coordinates (which might give you unexpected results).
Image
Description
The image() command in PlotDevice returns an Image object representing a bitmap or vector image file. If you call image() with a plot=False
argument, you can make copies of the image and position or plot() the object manually.
Methods
img.draw() img.copy()
Properties
img.x img.y img.width img.height img.frame # position & maximal size defined when creating the Image img.bounds # position & size of the scaled image (fitted to the frame) img.size # the (unscaled) dimensions of the source image
Legacy Commands
autoclosepath()
Syntax
autoclosepath(close=True)
Description
Defines whether custom shapes created between beginpath() and endpath() are automatically closed by connecting the last point and the first point in the path with a line. It takes a single parameter of True
or False
. All shapes created with beginpath() following this command will adhere to the setting.
PlotDevice Equivalent
The new bezier() command takes a keyword argument called close
which, when set to True
will close the path at the end of a with
block. The lineto(), cuveto(), and arcto() commands will also accept a close
argument allowing you to close the subpath after adding a line segment.
Tutorial
beginpath()
Syntax
beginpath(x=None, y=None)
Description
Using the beginpath() and endpath() commands allows creating custom shapes. The two parameters of beginpath() set the location of the first point (origin) in the path. These parameters are optional. When not supplied, a starting location for the path should be given with the moveto() command.
After calling the beginpath() command, a series of other path commands usually follows (for example moveto(), lineto(), or curveto()). Finally, the endpath() command draws the path to the screen.
PlotDevice Equivalent
The beginpath() command has been subsumed into the new bezier() command. Rather than calling beginpath() and endpath() to construct beziers, you can call bezier() as part of a with
statement.
Tutorial
Example
stroke(0.2) beginpath(10, 10) lineto(40, 10) endpath()
drawpath()
Syntax
drawpath(path)
Description
Draws a Bezier path to the screen. The path is a series of lines and curves defined between beginpath() and endpath(). Normally, endpath() draws the path to the screen, but this can be suppressed by calling it with plot=False
. The path can then be assigned to a variable, and this variable used as a parameter for drawpath().
Note: if you have one path that you want to draw multiple times with drawpath(), for example each with its own rotation and position, you need to supply a copy:
drawpath(path.copy())
PlotDevice Equivalent
The new plot() command will draw Bezier objects (as well as images and text) to the canvas. You can also pass a Bezier object to the bezier() command and it will draw a new copy of it (inheriting the canvas’s current graphics state in the process).
Tutorial
Example
stroke(0.2) beginpath(10, 10) lineto(40, 10) p = endpath(plot=False) drawpath(p)
endpath()
Syntax
endpath(draw=True)
Description
The endpath() command is the companion to beginpath() and may only be called after the latter. When endpath() is called, the path (defined by commands between beginpath() and endpath()) is drawn to the screen. If called with draw=False
, the path is not drawn to the screen but can be assigned to a variable. Later on, the variable can be drawn with the drawpath() command.
Returns
PlotDevice Equivalent
The endpath() command has been subsumed into the new bezier() command. Rather than calling beginpath() and endpath() to construct beziers, you can call bezier() as part of a with
statement.
Tutorial
Example
stroke(0.2) beginpath(10, 10) lineto(40, 10) p = endpath(plot=False) drawpath(p)
findpath()
Syntax
findpath(list, curvature=1.0)
Description
Returns
PlotDevice Equivalent
The findpath() command has been subsumed into the new bezier() command, though note that it gives you less control over curvature. The boolean smooth
argument to bezier() is equivalent to calling findpath() with a curvature of 1.0 or 0.
Tutorial
Example
points = [(10, 10), (90, 90), (350, 200)] for x, y in points: oval(x-2, y-2, 4, 4) nofill() stroke(0.2) autoclosepath(False) path = findpath(points) drawpath(path)