Shoebot documentation¶
- Main site <https://shoebot.github.io>
- GitHub repository <https://github.com/shoebot/shoebot>
- Issue tracker <https://github.com/shoebot/shoebot/issues>
Contents:
Introduction¶
Shoebot is a tool to automate the process of drawing vector graphics using a minimal and easy-to-understand syntax.
Using code to create and tweak shapes, colours and features is a model that departs from the WYSIWYG paradigm that is present in mainstream graphics applications. Shoebot was inspired by a rich lineage of tools dedicated to generative creativity:
- Nodebox
- Drawbot
- Processing
- Paper.js
- Scriptographer
- Design By Numbers
Shoebot is a fork/rewrite of Nodebox 1 by Frederik de Bleser and Tom de Smedt, which is itself based on DrawBot by Just van Rossum. There are slightly different syntax approaches in each language, and Shoebot tries to support both.
Why scripting?¶
The most evident purpose of scripting is to automate repetitive tasks. Using Shoebot, we can create an image with 2000 randomly positioned circles in two lines of code:

for step in range(2000):
ellipse(random(WIDTH), random(HEIGHT), 10, 10)
This is something that would be much more involved to create using the mouse and keyboard to draw on the canvas manually. Using scripts to control your output offers many new uses and possibilities for image generation and manipulation.
One common use for this kind of approach is the creation of dynamic systems to generate drawings, be them ‘generative’ (systems that grow, often unpredictably, from a set of initial parameters) or ‘procedural’ (rule-based systems).
Why use Shoebot¶
Shoebot is meant to run scripts with instructions to draw both simple shapes
and complex compositions. The syntax is Python with a set of additional
commands that ease the process of iterating through different options and
designs. There are many examples showcasing the possibilities of Shoebot inside
the examples/
directory.
The output of Shoebot scripts can be exported to the most widely used vector file formats – SVG, PDF and PostScript – as well as the PNG bitmap format.
Shoebot’s distinguishing feature is that it can be run in a terminal without a graphical editor. Drawing without the overhead of a GUI makes Shoebot a useful and easy-to-grasp tool for fast, procedural image generation.
A script’s variables can be accessed through an automatically generated GUI or even from outside applications – see the Interfacing with the outside world section.
There is also a set of libraries ported from Nodebox which enable SVG importing, Spiro splines, image fetching and manipulation, computer vision, video and webcam input, and more!
Getting Started¶
[TODO: - explain the language with some example scripts. - how to edit scripts with a GUI (Gedit) ]
Command-line usage¶
Using the Shoebot console runner is straightforward:
sbot hypnoval.bot
This command will run the hypnoval.bot
script, and create an output image
file – the default filename is output.svg
). You can find many example Shoebot scripts inside the examples dir.
You’ll probably want to specify your own output file name:
sbot inputfile.bot -o image.png
The allowed extensions for the output filename are .svg
, .ps
, .pdf
and .png
.
Shoebot can also run in a window, which is useful for quick previews, as well
as realtime manipulation of parameters. For this, just use the --window
flag or -w
:
sbot -w inputfile.bot
For a list of extra options, there’s always --help
or -h
.
sbot -h
Command reference¶
This documentation is still missing many parts. Refer to the [Nodebox documentation](https://www.nodebox.net/code/index.php/Reference) for the best reference in the meantime.
Drawing shapes¶
-
rect
(x, y, width, height, roundness=0, draw=True, fill=None)¶ Draw a rectangle on the canvas.
Parameters: - x – top left x-coordinate
- y – top left y-coordinate
- width – rectangle width
- height – rectangle height
- roundness – rounded corner radius
- draw (boolean) – whether to draw the shape on the canvas or not
- fill – fill color
rect(10, 10, 35, 35) # see how roundness affects the shape rect(55, 10, 35, 35, 0.3) rect(10, 55, 35, 35, 0.7) rect(55, 55, 35, 35, 1)
-
ellipse
(x, y, width, height, draw=True)¶ Draw an ellipse on the canvas. Same as oval().
Parameters: - x – top left x-coordinate
- y – top left y-coordinate
- width – ellipse width
- height – ellipse height
- draw (boolean) – whether to draw the shape on the canvas or not
ellipse(10, 20, 30, 60) ellipse(50, 30, 40, 40) # circle
-
arrow
(x, y, width, type=NORMAL, draw=True)¶ Draw an arrow on the canvas.
Parameters: - x – arrow tip x-coordinate
- y – arrow tip y-coordinate
- width – arrow width (also sets height)
- type (NORMAL or FORTYFIVE) – arrow type
- draw (boolean) – whether to draw the shape on the canvas or not
arrow(50, 40, 40) # NORMAL is the default arrow type arrow(90, 40, 40, FORTYFIVE)
-
star
(startx, starty, points=20, outer=100, inner=50, draw=True)¶ Draw a star-like polygon on the canvas.
Parameters: - startx – center x-coordinate
- starty – center y-coordinate
- points – amount of points
- outer – outer radius
- inner – inner radius
- draw (boolean) – whether to draw the shape on the canvas or not
star(25, 25, 5, 20, 10) # top left star(75, 25, 10, 20, 3) # top right star(25, 75, 20, 20, 17) # bottom left star(75, 75, 40, 20, 19) # bottom right
-
line
(x1, y1, x2, y2, draw=True)¶ Draw a line from (x1,y1) to (x2,y2).
Parameters: - x1 – x-coordinate of the first point
- y1 – y-coordinate of the first point
- x2 – x-coordinate of the second point
- y2 – y-coordinate of the second point
- draw (boolean) – whether to draw the shape on the canvas or not
stroke(0.5) strokewidth(3) line(20, 20, 80, 80) line(20, 80, 80, 20) line(50, 20, 50, 80)
-
rectmode
(mode=None)¶ Change the way rectangles are specified. Each mode alters the parameters necessary to draw a rectangle using the
rect()
function.Parameters: mode (CORNER, CENTER or CORNERS) – the mode to draw new rectangles in There are 3 different modes available:
- CORNER mode (default)
- x-value of the top left corner
- y-value of the top left corner
- width
- height
- CENTER mode
- x-coordinate of the rectangle’s center point
- y-coordinate of the rectangle’s center point
- width
- height
- CORNERS mode
- x-coordinate of the top left corner
- y-coordinate of the top left corner
- x-coordinate of the bottom right corner
- y-coordinate of the bottom right corner
So while you always specify 4 parameters to the
rect()
function, you can userectmode()
to change the function’s behaviour according to what might suit your script’s needs.
Bézier paths¶
-
beginpath
(x=None, y=None)¶ Begin drawing a Bézier path. If x and y are not specified, this command should be followed by a
moveto()
call.Parameters: - x (float or None) – x-coordinate of the starting point
- y (float or None) – y-coordinate of the starting point
-
moveto
(x, y)¶
-
relmoveto
(x, y)¶
-
lineto
(x, y)¶
-
rellineto
(x, y)¶
-
curveto
(x1, y1, x2, y2, x3, y3)¶
-
arc
(x, y, radius, angle1, angle2)¶
-
closepath
()¶
-
endpath
(draw=True)¶
-
drawpath
(path)¶
-
autoclosepath
(close=True)¶
-
findpath
(points, curvature=1.0)¶
Images¶
-
drawimage
(image)¶ - image: Image to draw
- x: optional, x coordinate (default is image.x)
- y: optional, y coordinate (default is image.y)
Transforms¶
-
transform
(mode=None)¶ Parameters: mode (CORNER or CENTER) – the mode to base new transformations on
-
translate
(xt, yt, mode=None)¶
-
rotate
(degrees=0, radians=0)¶
-
scale
(x=1, y=None)¶
-
skew
(x=1, y=0)¶
-
push
()¶
-
pop
()¶
-
reset
()¶
Colors¶
- Colors can be specified in a few ways:
- grayscale: (value)
- grayscale with alpha: (value, alpha)
- RGB: (red, green, blue)
- RGBA: (red, green, blue, alpha)
- hex: (‘#FFFFFF’)
- hex with alpha: (‘#FFFFFFFF’)
You can use any of these formats to specify a colour; for example, fill(1,0,0) and fill(‘#FF0000’) yield the same result.
-
background
(*args)¶
Set background to any valid color
-
outputmode
()¶ Not implemented yet (Nodebox API)
-
colormode
(mode=None, crange=None)¶
Set the current colormode (can be RGB or HSB) and eventually the color range.
If called without arguments, it returns the current colormode.
- mode: Color mode, either “rgb”, or “hsb”
- crange: Maximum scale value for color, e.g. 1.0 or 255
-
colorrange
(crange)¶
By default colors range from 0.0 - 1.0 using colorrange other defaults can be used, e.g. 0.0 - 255.0
- crange: Color range of 0.0 - 255:
-
fill
(*args)¶
Sets a fill color, applying it to new paths.
- args: color in supported format
-
stroke
(*args)¶
Set a stroke color, applying it to new paths.
- args: color in supported format
-
nofill
()¶
Stop applying fills to new paths.
-
nostroke
()¶
Stop applying strokes to new paths.
-
strokewidth
(w=None)¶ - w: Stroke width.
- return: If no width was specified then current width is returned.
-
color
(*args)¶ - args: color in a supported format.
- return: Color object containing the color.
Color¶
[TODO: Describe all the possible color syntax options, and link the above commands to these.]
Text¶
-
text
(txt, x, y, width=None, height=1000000, outline=False, draw=True)
Draws a string of text according to current font settings.
- txt: Text to output
- x: x-coordinate of the top left corner
- y: y-coordinate of the top left corner
- width: text width
- height: text height
- outline: If True draws outline text (defaults to False)
- draw: Set to False to inhibit immediate drawing (defaults to True)
- return: Path object representing the text.
-
font
(fontpath=None, fontsize=None)¶
Set the font to be used with new text instances.
Accepts TrueType and OpenType files. Depends on FreeType being installed.
- fontpath: path to truetype or opentype font.
- fontsize: size of font
- return: current current fontpath (if fontpath param not set)
-
fontsize
(fontsize=None)¶
Set or return size of current font.
- fontsize: Size of font.
- return: Size of font (if fontsize was not specified)
-
textpath
(txt, x, y, width=None, height=1000000, draw=False)¶
Generates an outlined path of the input text.
- txt: Text to output
- x: x-coordinate of the top left corner
- y: y-coordinate of the top left corner
- width: text width
- height: text height
- draw: Set to False to inhibit immediate drawing (defaults to False)
- return: Path object representing the text.
-
textmetrics
(txt, width=None, height=None)¶ - return: the width and height of a string of text as a tuple (according to current font settings).
-
textwidth
(txt, width=None)¶ - return: the width of a string of text according to the current font settings.
-
textheight
(txt, width=None)¶ - return: the height of a string of text according to the current font settings.
-
lineheight
(height=None)¶
Set text lineheight.
- height: line height.
-
align
(align="LEFT")¶
Set text alignment
- align: Text alignment (LEFT, CENTER, RIGHT)
-
fontoptions
(hintstyle=None, hintmetrics=None, subpixelorder=None, antialias=None)¶ Not implemented yet.
-
autotext
(sourceFile)¶
generates mock philosophy based on a context-free grammar
Utility functions¶
-
random
(v1=None, v2=None)¶
-
grid
(cols, rows, colSize=1, rowSize=1, shuffled=False)¶
-
files
(path="*")¶ You can use wildcards to specify which files to pick, e.g.
>>> f = files('*.gif')
Parameters: path – wildcard to use in file list.
-
snapshot
(filename=None, surface=None, defer=None, autonumber=False)¶ Save the contents of current surface into a file or cairo surface/context.
Parameters: - filename – File name to output to. The file type will be deduced from the extension.
- surface – If specified will output snapshot to the supplied cairo surface.
- defer (boolean) – Decides whether the action needs to happen now or can happen later. When set to False, it ensures that a file is written before returning, but can hamper performance. Usually you won’t want to do this. For files defer defaults to True, and for Surfaces to False, this means writing files won’t stop execution, while the surface will be ready when snapshot returns. The drawqueue will have to stop and render everything up until this point.
- autonumber (boolean) – If true then a number will be appended to the filename.
Core¶
-
ximport
(libName)¶ Import nodebox libraries.
The libraries get _ctx, which provides them with the nodebox API.
Parameters: libName – Library name to import
-
size
(w=None, h=None)¶ Sets the size of the canvas, and creates a Cairo surface and context. Only the first call will actually be effective.
-
speed
(framerate)¶
Set animation framerate.
- framerate: Frames per second to run bot.
- return: Current framerate of animation.
-
run
(inputcode, iterations=None, run_forever=False, frame_limiter=False)¶ Executes the contents of a Nodebox or Shoebot script in the current surface’s context.
Advanced usage¶
This section is aimed at Python dabblers and hackers who want to get into the more involved features of Shoebot.
Using Shoebot as a Python module¶
Shoebot can be easily loaded as a module inside a Python script.
import shoebot
# set up a canvas
bot = shoebot.create_bot(outputfile="output.svg")
# size() needs to be called first
bot.size(400,400)
# now we can draw!
bot.rect(10,10,100,100)
# finish() should be called after all drawing commands
bot.finish()
Take a snapshot of the current state:
bot.snapshot("snap.png")
Run a Shoebot/Nodebox script:
bot.run("example.bot")
Command-line usage¶
Enter sbot -h to see all the available options:
usage: usage: sbot [options] inputfile.bot [args] [-h] [-o FILE] [-s]
[-p SERVERPORT] [-v VARS]
[-ns NAMESPACE] [-l]
[-a SCRIPT_ARGS] [-r REPEAT]
[-g GRAMMAR] [-w] [-f]
[-t TITLE] [-c] [-dv] [-dt]
[-V]
script [script_args]
positional arguments:
script Shoebot / Nodebox script to run (filename or code)
optional arguments:
-h, --help show this help message and exit
Input / Output:
-o FILE, --outputfile FILE
run script and output to image file (accepts .png .svg
.pdf and .ps extensions)
-s, --socketserver run a socket server for external control (will run the
script in windowed mode)
-p SERVERPORT, --serverport SERVERPORT
set socketserver port to listen for connections
(default is 7777)
-v VARS, --vars VARS Initial variables, in JSON (Note: Single quotes
OUTSIDE, double INSIDE) --vars='{"variable1": 1}'
-ns NAMESPACE, --namespace NAMESPACE
Initial namespace, in JSON (Note: Single quotes
OUTSIDE, double INSIDE) --namespace='{"variable1": 1}'
-l, --l Simple shell - for IDE interaction
-a SCRIPT_ARGS, --args SCRIPT_ARGS
Pass to the bot
script_args
Bot Lifecycle:
-r REPEAT, --repeat REPEAT
set number of iteration, multiple images will be
produced
-g GRAMMAR, --grammar GRAMMAR
Select the bot grammar 'nodebox' (default) or
'drawbot' languages
Window Management:
-w, --window run script in a GTK window
-f, --fullscreen run in fullscreen mode
-t TITLE, --title TITLE
Set window title
-c, --close Close window after running bot (use with -r for
benchmarking)
-dv, --disable-vars disable the variables pane when in windowed mode.
Debugging / Dev flags:
-dt, --disable-background-thread
disable running bot code in background thread.
-V, --verbose Show internal shoebot error information in traceback
Working directly with Cairo¶
TODO
Interfacing with the outside world¶
Shoebot is not limited to what you write inside your .bot file; you can open your sketch for receiving and reacting to data from outside applications and environments.
Live variables¶
These can be set from the commandline using JSON syntax:
$ sbot -w –vars=’{ “hue”: 32 }’ examples/basic/var_number_hsb.bot
You can also set these values from the socketserver (see below), or running the live shell.
Using the live variables GUI¶
When a script uses the var keyword, the corresponding widget will appear in the live variables GUI.
The following code will make a slider with a minimum value of 0, a maximum value of 100, and an initial (default) value of 25.
var('a_number', NUMBER, 25., 0., 100.)

Socketserver¶
If shoebot is run with the –serverport option, a socket server will also be started. Socket servers can accept connections from other applications or even across the network in order to set variables inside Shoebot scripts. The default socket server port is 7777.
$ sbot -ws -p examples/animation/hypnoval.bot Listening on port 7777...
Once it’s running, it’s easy to connect with telnet:
$ telnet 127.0.0.1 7777
This gets you into the shell, where you can use the commands below to list and set variables, rewind and go to frames.
The following commands can also be sent through other applications like Pure Data; there is a simple PD example in examples/socketcontrol/helloworld.pd.
Be sure to take a look at the socket server examples in action inside the examples/socketserver directory.
Socketserver commands¶
Playback Commands
Command Description goto 100 Go to frame 100 pause pause playback rewind set FRAME to 0 restart set FRAME to 0 and reset all variables Using variables
Command Description vars Show content of all Shoebot Variables set n=1 set variable ‘n’ to value 1 n=1 set variable ‘n’ to value 1 Other
Command Description help Show list of all commands
Live coding: Editors/IDEs and the live shell¶
Shoebot provides a live shell for communication with text editors.
All the socket server commands above are available, as well as load_base64 which allows livecoding.
To experiment with the livecoding shell, run an example with the -l option
$ sbot -wl examples/animation/hypnoval.bot
This has all the commands that the socket server has, and extra commands that can be useful for an editor or IDE.
Live Shell commands¶
Live Shell Commands
Command Description quit quit shoebot load_base64 used by IDE/Editor to send new code to Shoebot
Embedding¶
For applications that use standard image formats, like the web it is enough to use create_bot and output image formats (see ‘using shoebot as a module’).
Pure Data¶
Shoebot libraries¶
[TODO: How to install]
OpenCV¶
Video¶
SVG¶
Boids¶
Colors¶
Web¶
Graph¶
Cornu¶
L-System¶
Photobot¶
Supershape¶
TUIO¶
Extensions¶
There are a few plug-ins and extensions that make for a much better experience.
Gedit¶
This Gedit plugin adds a menu to allow for running Shoebot scripts. It will open a Shoebot window using the current document as the Shoebot code.
Installation¶
Run the following commands to add the plugin to Gedit:
$ cd shoebot/extensions/gedit $ python install.py
Restart Gedit. Navigate to Edit > Preferences > Plugins and activate the Shoebotit plugin.
Example scripts¶
This is a set of example scripts from the examples
directory.
[Work-in-progress!]
How curves work¶

# about:
# Demonstrate how the different parameters of curves work.
size(200,200)
import math
# Setup colors: no fill is needed, and stroke the curves with black.
nofill()
stroke(0)
# Set the initial position
x,y = 50, 50
width = 50
# The dx and dy parameters are the relative control points.
# When using math.pi/2, you actually define the lower half
# of a circle.
dy = width/(math.pi / 2)
# Begin drawing the path. The starting position is on the
# given x and y coordinates.
beginpath(x, y)
# Calculate the control points.
cp1 = (x, y + dy)
cp2 = (x + width, y + dy)
# Draw the curve. The first four parameters are the coordinates
# of the two control curves; the last two parameters are
# the coordinates of the destination point.
curveto(cp1[0], cp1[1], cp2[0], cp2[1], x + width, y)
# End the path; ending the path automatically draws it.
endpath()
# To demonstrate where the control points actually are,
# we draw them using lines.
# The first control point starts at the x,y position.
line(x, y, cp1[0], cp1[1])
# The second control point is the ending point.
line(x + width, y, cp2[0], cp2[1])
# To liven things up just a little bit, little ovals are
# drawn in red on the position of the control points.
nostroke()
fill(1,0,0)
oval(cp1[0] - 2, cp1[1] - 2, 4, 4)
oval(cp2[0] - 2, cp2[1] - 2, 4, 4)