robodraw

Submodules

Classes

Drawing

Draw 2D or pseudo-3D diagrams using matplotlib. This handles the

Functions

darken_color(color[, factor])

Take color and darken it by factor.

get_color(which[, alpha, hue_factor, sat_factor, ...])

Get a color by name, optionally modifying its alpha, hue, saturation

hash_to_color(s[, hmin, hmax, smin, smax, vmin, vmax])

Generate a random color for a string s.

Package Contents

class robodraw.Drawing(background=(0, 0, 0, 0), drawcolor=(0.14, 0.15, 0.16, 1.0), shapecolor=(0.45, 0.5, 0.55, 1.0), projection=('orthographic', 20, 40), xscale=1, yscale=1, zscale=1, presets=None, ax=None, adjust_lims='auto', **kwargs)[source]

Draw 2D or pseudo-3D diagrams using matplotlib. This handles the 3D projection and the z-ordering of the elements, as well as named preset styles for repeated elements, and the automatic adjustment of the figure limits. It also has basic support for drawing smooth curves and shaded areas around certain elements automatically.

Parameters:
  • background (color, optional) – The background color of the figure, defaults to transparent.

  • drawcolor (color, optional) – The default color to draw lines and text in.

  • shapecolor (color, optional) – The default color to fill shapes with.

  • projection (tuple, optional) –

    The 3D projection mode and parameters, specified as a tuple of (mode, *args). Available modes:

    • ("orthographic", azimuth, elevation) : Orthographic projection (camera at infinity). azimuth is the horizontal camera angle in degrees (0 means looking along +y, i.e. the y-axis extends into the page). elevation is the vertical angle above the horizontal (0 is side-on, 90 is top-down). ("orthographic", 0, 90) gives an exact top-down view.

    • ("axonometric", a, b) : Axonometric projection where a and b are the angles of the x and y axes measured counterclockwise from horizontal, in degrees. True isometric projection is ("axonometric", 30, 150), which you can also specify with the string "isometric".

    Default is ("orthographic", 20, 40).

  • xscale (float) – A factor to scale the x-axis by.

  • yscale (float) – A factor to scale the y-axis by.

  • zscale (float) – A factor to scale the z-axis by.

  • presets (dict[str, dict], optional) – A dictionary of named style presets. When you add an element to the drawing, you can specify a preset name to use as default styling.

  • ax (matplotlib.axes.Axes) – The axes to draw on. If None, a new figure is created. If an external ax is supplied, then note that this Drawing instance will not automatically adjust the limits of the axes as elements are added.

  • adjust_lims (bool or "auto", optional) – Whether to automatically adjust the axes limits as elements are added. If “auto” (the default), then this is True if ax is None, else False, i.e. only adjust limits if we own the figure.

  • kwargs – Passed to plt.figure if ax is None.

adjust_lims = 'auto'
drawcolor = (0.14, 0.15, 0.16, 1.0)
shapecolor = (0.45, 0.5, 0.55, 1.0)
_xmin = None
_xmax = None
_ymin = None
_ymax = None
presets
_project_xscale = 1
_project_yscale = 1
_project_zscale = 1
_projection
_3d_xmin = None
_3d_xmax = None
_3d_ymin = None
_3d_ymax = None
_3d_zmin = None
_3d_zmax = None
_offset = (0, 0, 0)
_screen_offset = (0, 0)
_axis_angle(axis)[source]

Get the screen rotation angle (in degrees) of a 3D axis.

_2d_project(x, y)[source]
_3d_project(x, y, z)[source]
_coo_to_zorder(x, y, z)[source]
translate(dx=0, dy=0, dz=0)[source]

Context manager to temporarily translate all draw operations, in coordinate space (i.e. before any projection and scaling).

Parameters:
  • dx (float) – The x offset.

  • dy (float) – The y offset.

  • dz (float) – The z offset (only relevant for 3D coordinates).

Examples

>>> d = Drawing()
>>> with d.translate(10, 5):
...     d.circle((0, 0))  # drawn at (10, 5)
translate_screen(dx=0, dy=0)[source]

Context manager to temporarily translate all draw operations in 2D screen space (i.e. after any projection and scaling).

Parameters:
  • dx (float) – The x screen offset.

  • dy (float) – The y screen offset.

Examples

>>> d = Drawing()
>>> with d.translate_screen(10, 5):
...     d.circle((0, 0, 0))  # 3D projected, then shifted
_project_coos(coos, style, zorder_delta=0.0, zorder_aggregate='mean', project=True)[source]

Possibly project sequence of coordinates and inject zorder.

_adjust_lims(x, y)[source]
text(coo, text, preset=None, **kwargs)[source]

Place text at the specified coordinate.

Parameters:
  • coo (tuple[int, int] or tuple[int, int, int]) – The 2D or 3D coordinate of the text. If 3D, the coordinate will be projected onto the 2D plane, and a z-order will be assigned.

  • text (str) – The text to place.

  • preset (str, optional) – A preset style to use for the text.

  • kwargs – Specific style options passed to matplotlib.axes.Axes.text.

text_between(cooa, coob, text, preset=None, **kwargs)[source]

Place text between two coordinates.

Parameters:
  • cooa (tuple[int, int] or tuple[int, int, int]) – The 2D or 3D coordinates of the text endpoints. If 3D, the coordinates will be projected onto the 2D plane, and a z-order will be assigned based on average z-order of the endpoints.

  • coob (tuple[int, int] or tuple[int, int, int]) – The 2D or 3D coordinates of the text endpoints. If 3D, the coordinates will be projected onto the 2D plane, and a z-order will be assigned based on average z-order of the endpoints.

  • text (str) – The text to place.

  • center (float, optional) – The position of the text along the line, where 0.0 is the start and 1.0 is the end. Default is 0.5.

  • shorten (float or tuple[float, float], optional) – Shorten the implicit line by this absolute amount at each end. If a tuple, the first value is the start shortening, the second the end shortening.

  • preset (str, optional) – A preset style to use for the text.

  • kwargs – Specific style options passed to matplotlib.axes.Axes.text.

label_ax(x, y, text, preset=None, **kwargs)[source]

Place text at the specified location, using the axis coordinates rather than 2D or 3D data coordinates.

Parameters:
  • x (float) – The x and y positions of the text, relative to the axis.

  • y (float) – The x and y positions of the text, relative to the axis.

  • text (str) – The text to place.

  • preset (str, optional) – A preset style to use for the text.

  • kwargs – Specific style options passed to matplotlib.axes.Axes.text.

label_fig(x, y, text, preset=None, **kwargs)[source]

Place text at the specified location, using the figure coordinates rather than 2D or 3D data coordinates.

Parameters:
  • x (float) – The x and y positions of the text, relative to the figure.

  • y (float) – The x and y positions of the text, relative to the figure.

  • text (str) – The text to place.

  • preset (str, optional) – A preset style to use for the text.

  • kwargs – Specific style options passed to matplotlib.axes.Axes.text.

_project_and_parse_style_for_marker(coo, preset=None, project=True, **kwargs)[source]
_adjust_lims_for_marker(x, y, r)[source]
circle(coo, preset=None, **kwargs)[source]

Draw a circle at the specified coordinate.

Parameters:
  • coo (tuple[int, int] or tuple[int, int, int]) – The 2D or 3D coordinate of the circle. If 3D, the coordinate will be projected onto the 2D plane, and a z-order will be assigned.

  • preset (str, optional) – A preset style to use for the circle.

  • kwargs – Specific style options passed to matplotlib.patches.Circle.

wedge(coo, theta1, theta2, preset=None, **kwargs)[source]

Draw a wedge at the specified coordinate.

Parameters:
  • coo (tuple[int, int] or tuple[int, int, int]) – The 2D or 3D coordinate of the wedge. If 3D, the coordinate will be projected onto the 2D plane, and a z-order will be assigned.

  • theta1 (float) – The angle in degrees of the first edge of the wedge.

  • theta2 (float) – The angle in degrees of the second edge of the wedge.

  • preset (str, optional) – A preset style to use for the wedge.

  • kwargs – Specific style options passed to matplotlib.patches.Wedge.

dot(coo, preset=None, **kwargs)[source]

Draw a small circle with no border. Alias for circle with defaults radius=0.1 and linewidth=0.0.

Parameters:
  • coo (tuple[int, int] or tuple[int, int, int]) – The 2D or 3D coordinate of the dot. If 3D, the coordinate will be projected onto the 2D plane, and a z-order will be assigned.

  • preset (str, optional) – A preset style to use for the dot.

  • kwargs – Specific style options passed to matplotlib.patches.Circle.

regular_polygon(coo, preset=None, **kwargs)[source]

Draw a regular polygon at the specified coordinate.

Parameters:
  • coo (tuple[int, int] or tuple[int, int, int]) – The 2D or 3D coordinate of the polygon. If 3D, the coordinate will be projected onto the 2D plane, and a z-order will be assigned.

  • n (int) – The number of sides of the polygon.

  • orientation (float, optional) – The orientation of the polygon in radians. Default is 0.0.

  • preset (str, optional) – A preset style to use for the polygon.

  • kwargs – Specific style options passed to matplotlib.patches.Polygon.

star(coo, preset=None, **kwargs)[source]
cross(coo, preset=None, **kwargs)[source]
marker(coo, preset=None, **kwargs)[source]

Draw a ‘marker’ at the specified coordinate. This is a shorthand for creating polygons with shape specified by a single character.

Parameters:
  • coo (tuple[int, int] or tuple[int, int, int]) – The 2D or 3D coordinate of the marker. If 3D, the coordinate will be projected onto the 2D plane, and a z-order will be assigned.

  • marker (str, optional) – The marker shape to draw. One of "o.v^<>sDphH8".

  • preset (str, optional) – A preset style to use for the marker.

  • kwargs – Specific style options.

square(coo, preset=None, **kwargs)[source]

Draw a square of ‘radius’ radius at the specified coordinate. This is a shorthand for Drawing.marker with marker=’s’.

cube(coo, preset=None, **kwargs)[source]

Draw a cube at the specified coordinate, which must be 3D.

Parameters:
  • coo (tuple[int, int, int]) – The 3D coordinate of the cube. The coordinate will be projected onto the 2D plane, and a z-order will be assigned.

  • preset (str, optional) – A preset style to use for the cube.

  • kwargs – Specific style options passed to matplotlib.patches.Polygon.

tetrahedron(coo, preset=None, **kwargs)[source]

Draw a tetrahedron at the specified coordinate, which must be 3D.

Parameters:
  • coo (tuple[int, int, int]) – The 3D coordinate of the tetrahedron. The coordinate will be projected onto the 2D plane, and a z-order will be assigned.

  • preset (str, optional) – A preset style to use for the tetrahedron.

  • kwargs – Specific style options passed to matplotlib.patches.Polygon.

octahedron(coo, preset=None, **kwargs)[source]

Draw an octahedron at the specified coordinate, which must be 3D.

Parameters:
  • coo (tuple[int, int, int]) – The 3D coordinate of the octahedron. The coordinate will be projected onto the 2D plane, and a z-order will be assigned.

  • preset (str, optional) – A preset style to use for the octahedron.

  • kwargs – Specific style options passed to matplotlib.patches.Polygon.

dodecahedron(coo, preset=None, **kwargs)[source]

Draw a dodecahedron at the specified coordinate, which must be 3D.

Parameters:
  • coo (tuple[int, int, int]) – The 3D coordinate of the dodecahedron. The coordinate will be projected onto the 2D plane, and a z-order will be assigned.

  • preset (str, optional) – A preset style to use for the dodecahedron.

  • kwargs – Specific style options passed to matplotlib.patches.Polygon.

icosahedron(coo, preset=None, **kwargs)[source]

Draw an icosahedron at the specified coordinate, which must be 3D.

Parameters:
  • coo (tuple[int, int, int]) – The 3D coordinate of the icosahedron. The coordinate will be projected onto the 2D plane, and a z-order will be assigned.

  • preset (str, optional) – A preset style to use for the icosahedron.

  • kwargs – Specific style options passed to matplotlib.patches.Polygon.

line(cooa, coob, preset=None, **kwargs)[source]

Draw a line between two coordinates.

Parameters:
  • cooa (tuple[int, int] or tuple[int, int, int]) – The 2D or 3D coordinates of the line endpoints. If 3D, the coordinates will be projected onto the 2D plane, and a z-order will be assigned based on average z-order of the endpoints.

  • coob (tuple[int, int] or tuple[int, int, int]) – The 2D or 3D coordinates of the line endpoints. If 3D, the coordinates will be projected onto the 2D plane, and a z-order will be assigned based on average z-order of the endpoints.

  • shorten (float or tuple[float, float], optional) – Shorten the line by this absolute amount at each end. If a tuple, the first value is the start shortening, the second the end shortening.

  • stretch (float) – Stretch the line by this relative factor. 1.0 is no stretch, 0.5 is half length, 2.0 is double length. Default is 1.0.

  • arrowhead (bool or dict, optional) – Draw an arrowhead at the end of the line. Default is False. If a dict, it is passed as keyword arguments to the arrowhead method.

  • text_between (str, optional) – Add text along the line.

  • preset (str, optional) – A preset style to use for the line.

  • kwargs – Specific style options passed to matplotlib.lines.Line2D.

line_offset(cooa, coob, offset, midlength=0.5, relative=True, preset=None, **kwargs)[source]

Draw a line between two coordinates, but curving out by a given offset perpendicular to the line.

Parameters:
  • cooa (tuple[int, int] or tuple[int, int, int]) – The 2D or 3D coordinates of the line endpoints. If 3D, the coordinates will be projected onto the 2D plane, and a z-order will be assigned based on average z-order of the endpoints.

  • coob (tuple[int, int] or tuple[int, int, int]) – The 2D or 3D coordinates of the line endpoints. If 3D, the coordinates will be projected onto the 2D plane, and a z-order will be assigned based on average z-order of the endpoints.

  • offset (float) – The offset of the curve from the line, as a fraction of the total line length. This is always processed in the 2D projected plane.

  • midlength (float) – The length of the middle straight section, as a fraction of the total line length. Default is 0.5.

  • arrowhead (bool or dict, optional) – Draw an arrowhead at the end of the line. Default is False. If a dict, it is passed as keyword arguments to the arrowhead method.

  • text_between (str, optional) – Add text along the line.

  • relative (bool, optional) – If True (the default), then offset is taken as a fraction of the line length, else in absolute units.

  • preset (str, optional) – A preset style to use for the line.

  • kwargs – Specific style options passed to curve.

zigzag(cooa, coob, preset=None, **kwargs)[source]

Draw a zig-zagging line between two coordinates.

Parameters:
  • cooa (tuple[int, int] or tuple[int, int, int]) – The coordinates of the start and end of the line. If 3D, the coordinates will be projected onto the 2D plane, and a z-order will be assigned based on average z-order of the endpoints.

  • coob (tuple[int, int] or tuple[int, int, int]) – The coordinates of the start and end of the line. If 3D, the coordinates will be projected onto the 2D plane, and a z-order will be assigned based on average z-order of the endpoints.

  • width (float, optional) – The width of the zig-zagging. Default is to aim for 8 zig-zags.

  • extend (float, optional) – Only start zig-zagging after this distance from the end-points.

  • density (float, optional) – The density of the zig-zags, where 1.0 is the default density resulting in approximately 8 zig-zags along the line.

  • shorten (float or tuple[float, float], optional) – Shorten the zigzag by this absolute amount at each end. If a tuple, the first value is the start shortening, the second the end shortening.

  • preset (str, optional) – A preset style to use for the line.

  • kwargs – Specific style options passed to Drawing.curve.

arrowhead(cooa, coob, preset=None, **kwargs)[source]

Draw just a arrowhead on the line between cooa and coob.

Parameters:
  • cooa (tuple[int, int] or tuple[int, int, int]) – The coordinates of the start and end of the line. If 3D, the coordinates will be projected onto the 2D plane, and a z-order will be assigned based on average z-order of the endpoints.

  • coob (tuple[int, int] or tuple[int, int, int]) – The coordinates of the start and end of the line. If 3D, the coordinates will be projected onto the 2D plane, and a z-order will be assigned based on average z-order of the endpoints.

  • reverse (bool or "both", optional) – Reverse the direction by switching cooa and coob. If "both", draw an arrowhead in both directions. Default is False.

  • center (float, optional) – The position of the arrowhead along the line, where 0 is the start and 1 is the end. Default is 0.5.

  • width (float, optional) – The width of the arrowhead. Default is 0.05.

  • length (float, optional) – The length of the arrowhead. Default is 0.1.

  • relative (bool or float, optional) – If True, the the width and length parameters are scaled as total_line_length ** relative.

  • preset (str, optional) – A preset style to use for the arrowhead, including the above options.

  • kwargs – Specific style options passed to matplotlib.lines.Line2D.

curve(coos, preset=None, **kwargs)[source]

Draw a smooth line through the given coordinates.

Parameters:
  • coos (Sequence[tuple[int, int]] or Sequence[tuple[int, int, int]]) – The 2D or 3D coordinates of the line. If 3D, the coordinates will be projected onto the 2D plane, and a z-order will be assigned based on average z-order of the endpoints.

  • smoothing (float, optional) – The amount of smoothing to apply to the curve. 0.0 is no smoothing, 1.0 is maximum smoothing. Default is 0.5.

  • shorten (float or tuple[float, float], optional) – Shorten the line by this absolute amount at each end. If a tuple, the first value is the start shortening, the second the end shortening. The shortening is calculated with respect to the first and last segments of the curve.

  • preset (str, optional) – A preset style to use for the curve.

  • kwargs – Specific style options passed to matplotlib.patches.PathPatch.

shape(coos, preset=None, **kwargs)[source]

Draw a closed shape with (sharp) corners at the given coordinates.

Parameters:
  • coos (sequence of coordinates) – The coordinates of the corners’ of the shape.

  • preset (str, optional) – A preset style to use for the shape.

  • kwargs – Specific style options passed to matplotlib.patches.PathPatch.

See also

Drawing.patch

rectangle(cooa, coob, preset=None, **kwargs)[source]
patch(coos, preset=None, **kwargs)[source]

Draw a closed smooth patch through given coordinates.

Parameters:
  • coos (sequence of coordinates) – The coordinates of the ‘corners’ of the patch, the outline is guaranteed to pass through these points.

  • smoothing (float) – The smoothing factor, the higher the smoother. The default is 0.5.

  • preset (str, optional) – A preset style to use for the patch.

  • kwargs – Specific style options passed to matplotlib.patches.PathPatch.

patch_around(coos, *, preset=None, **kwargs)[source]

Draw a patch around the given coordinates, by contructing a convex hull around the points, optionally including an extra uniform or per coordinate radius.

Parameters:
  • coos (sequence[tuple[int, int]] or sequence[tuple[int, int, int]]) – The coordinates of the points to draw the patch around. If 3D, the coordinates will be projected onto the 2D plane, and a z-order will be assigned based on min z-order of the endpoints.

  • radius (float or sequence[float], optional) – The radius of the patch around each point. If a sequence, must be the same length as coos. Default is 0.0.

  • resolution (int, optional) – The number of points to use pad around each point. Default is 12.

  • preset (str, optional) – A preset style to use for the patch.

  • kwargs – Specific style options passed to matplotlib.patches.PathPatch.

bezier(coos, preset=None, **kwargs)[source]

Draw a bezier curve, explicitly supplying the sequence of coordinates and anchors like [coo0, anchor0, anchor1, coo1, …].

Parameters:
  • coos (sequence[tuple[int, int]] or sequence[tuple[int, int, int]]) – The coordinates of the points to draw the bezier curve around.

  • preset (str, optional) – A preset style to use for the bezier curve.

  • kwargs – Specific style options passed to matplotlib.patches.PathPatch.

cup(cooa, coob, extend=0.0, flatness=1.0, which='left', preset=None, **kwargs)[source]

Draw a cup shape between two points.

patch_around_circles(cooa, ra, coob, rb, padding=0.2, pinch=True, preset=None, **kwargs)[source]

Draw a smooth patch around two circles.

Parameters:
  • cooa (tuple[int, int] or tuple[int, int, int]) – The coordinates of the center of the first circle. If 3D, the coordinates will be projected onto the 2D plane, and a z-order will be assigned based on average z-order of the endpoints.

  • ra (int) – The radius of the first circle.

  • coob (tuple[int, int] or tuple[int, int, int]) – The coordinates of the center of the second circle. If 3D, the coordinates will be projected onto the 2D plane, and a z-order will be assigned based on average z-order of the endpoints.

  • rb (int) – The radius of the second circle.

  • padding (float, optional) – The amount of padding to add around the circles. Default is 0.2.

  • pinch (bool or float, optional) – If or how much to pinch the patch in between the circles. Default is to match the padding.

  • preset (str, optional) – A preset style to use for the patch.

  • kwargs – Specific style options passed to matplotlib.patches.PathPatch.

See also

Drawing.patch

grid(color=(0, 0.7, 0.8), alpha=0.3, zorder=-100, subdivisions=(1 / 4, 2 / 4, 3 / 4), margin=0.5, overextend=0.0, ticklabels=True)[source]
grid3d(color=(0, 0.7, 0.8), alpha=0.3, zorder_delta=-1000, subdivisions=(1 / 4, 2 / 4, 3 / 4), margin=0.5, ticklabels=True)[source]
scale_figsize(scale=1.0)[source]

Scale this figure’s size according to the plot limits, so that one unit in the drawing corresponds to scale inches in the figure. Note this should be called after all drawing including .grid() calls.

savefig(fname, dpi=300, bbox_inches='tight')[source]

Save this drawing to a file, using matplotlib’s savefig and some nicer defaults.

Parameters:
  • fname (str) – The filename to save to.

  • dpi (int, optional) – The DPI to use. Default is 300.

  • bbox_inches (str or Bbox, optional) – The bbox_inches parameter to pass to matplotlib’s savefig. Default is ‘tight’.

robodraw.darken_color(color, factor=2 / 3)[source]

Take color and darken it by factor.

robodraw.get_color(which, alpha=None, hue_factor=0.0, sat_factor=1.0, val_factor=1.0)[source]

Get a color by name, optionally modifying its alpha, hue, saturation or value.

These colorblind friendly colors were ppularized in an article by Wong (https://www.nature.com/articles/nmeth.1618) but originally come from Okabe & Ito (https://jfly.uni-koeln.de/color/).

Parameters:
  • which ({'blue', 'orange', 'green', 'red', 'yellow', 'pink', 'bluedark'}) – The name of the color to get.

  • alpha (float, optional) – The alpha channel value to set for the color. Default is 1.0.

  • hue_factor (float, optional) – The amount to shift the hue of the color. Default is 0.0.

  • sat_factor (float, optional) – The amount to scale the saturation of the color. Default is 1.0.

  • val_factor (float, optional) – The amount to scale the value of the color. Default is 1.0.

Returns:

color – The RGBA color as a tuple of floats.

Return type:

tuple[float, float, float, float]

robodraw.hash_to_color(s, hmin=0.0, hmax=1.0, smin=0.3, smax=0.8, vmin=0.8, vmax=0.9)[source]

Generate a random color for a string s.

Parameters:
  • s (str) – The string to generate a color for.

  • hmin (float, optional) – The minimum hue value.

  • hmax (float, optional) – The maximum hue value.

  • smin (float, optional) – The minimum saturation value.

  • smax (float, optional) – The maximum saturation value.

  • vmin (float, optional) – The minimum value value.

  • vmax (float, optional) – The maximum value value.

Returns:

color – A tuple of floats in the range [0, 1] representing the RGB color.

Return type:

tuple