generativepy.graph module


Martin McBride, 2020-08-08
Tags graph
Categories generativepy generative art

The graph module provides the ability to draw graphs of mathematical functions. It can also be used in conjunction with the movie and tween modules to create animated graphs that can be converted to gifs or videos.

Graph scaling

Graphs are drawn in the current user space. This means that in order to draw a graph that is 10 units by 10 units, you should first select a user space that maps the image size in pixels onto a user space that extends from 0 to 10 in both dimensions. This is most easily done using the setup function.

generativepy device space follows the computer graphic convention that y values start at 0 at the top of the image, and increase in value going down the image. In maths, of course, the origin is usually at the bottom of the page and y-values increase going up the page. For the graph module to work properly you must flip user space. Again this can be done very easily using the setup function.

Remember also that if you draw any text in a flipped user space, you must also flip the text (using the flip parameter of the text drawing functions).

Example

Here is an example graph drawn using the Axes object, and adding 3 curves:

The code for this can be found on github as simplegraph.py:

from generativepy import graph
from generativepy.drawing import make_image, setup
from generativepy.color import Color
from generativepy.graph import Axes

'''
Create a simple graph
'''

def draw(ctx, width, height, frame_no, frame_count):

    setup(ctx, width, height, width=12, startx=-6, starty=-6, background=Color(1), flip=True)

    # Creates a set of axes.
    # Use the default size of 10 units, but offset the start toplace the origin inthe centre
    axes = Axes(ctx, start=(-5, -5))
    axes.draw()

    # Add various curves
    graph.plot_curve(axes, lambda x: x*x)
    graph.plot_xy_curve(axes, lambda x: 1.5**x, line_color=Color(0, 0, 0.5))
    graph.plot_polar_curve(axes, lambda x: 2*x, line_color=Color(0, 0.5, 0))


make_image("/tmp/simplegraph.png", draw, 500, 500)

Axes

The Axes class draws graph axes, including the main axes, divisions, origin marker and division values. You simply need to create an Axes object then call draw to draw the axes.

Axes constructor

Creates an Axes object.

Axes(ctx, start=(0, 0), extent=(10, 10), divisions=(1, 1), pixel_divider=10)
Parameter Type Description
ctx Context The Pycairo Context to draw to
start 2-tuple The (x, y) value of the bottom left corner of the graph in user space.
extent 2-tuple The (width, height) of the graph in user space.
divisions 2-tuple The division spacing for x and y.
pixel_divider number Scale factor

The graph will be drawn at the (x, y) position, with its (width, height) extents according to the current user space. This means that you will normally want to choose your user space and graph space to match your requirements.

pixel_divider is a number that number that is used to scale the text size and line thicknesses when the graph is drawn.

The default text size and line thickness is optimal for a graph with a pixel size of about 500 pixels, and an extent of about 10 user units. If you are using different sizes, you might need to adjust the pixel_divider value to make the graph appear correct.

Axes.draw

Draws the axes using the Context supplied in the Axes constructor.

draw()

Plotting curves

There are several curve plotting functions:

  • plot_curve for plotting functions of the form y = f(x).
  • plot_xy_curve for plotting inverse functions of the form x = f(y).
  • plot_polar_curve for plotting polar functions of the form r = f(a).

They each plot a curve against on a predefined set of axes.

plot_curve function

Plots a function of the form y = f(x)

plot_curve(axes, fn, line_color=Color(1, 0, 0), extent=None, line_width=.7,
           dash=None, cap=drawing.SQUARE, join=drawing.MITER, miter_limit=None)
Parameter Type Description
axes Axes The axes that the graph will be plotted against
fn function A Python function that takes a single number parameter and returns a number.
line_color Color The colour of the line.
extent 2-tuple The range of x values.
line_width number The width of the line.
dash list of numbers Line dash style.
cap number Line cap style.
join number line join style.
miter_limit number Corner miter limit.

If the extent is not supplied, the graph will be plotted for values of x that cover the full range of the axes. The extent can be used to limit the range to less than the full extent of the axes.

The line_width is a nominal value that might require adjustment for very large or small graphs.

The parameters dash, cap, join and miter_limit are as described for the stroke method of Shapes.

plot_xy_curve function

Plots a function of the form x = f(y)

plot_xy_curve(axes, fn, line_color=Color(1, 0, 0), extent=None, line_width=.7)
Parameter Type Description
axes Axes The axes that the graph will be plotted against
fn function A Python function that takes a single number parameter and returns a number.
line_color Color The colour of the line.
extent 2-tuple The range of y values.
line_width number The width of the line.
dash list of numbers Line dash style.
cap number Line cap style.
join number line join style.
miter_limit number Corner miter limit.

If the extent is not supplied, the graph will be plotted for values of y that cover the full range of the axes. The extent can be used to limit the range to less than the full extent of the axes.

The line_width is a nominal value that might require adjustment for very large or small graphs.

The parameters dash, cap, join and miter_limit are as described for the stroke method of Shapes.

plot_polar_curve function

Plots a polar function of the form r = f(a)

plot_polar_curve(axes, fn, line_color=Color(1, 0, 0), extent=(0, 2*math.pi), line_width=.7)
Parameter Type Description
axes Axes The axes that the graph will be plotted against
fn function A Python function that takes a single number parameter and returns a number.
line_color Color The colour of the line.
extent 2-tuple The range of angle values.
line_width number The width of the line.
dash list of numbers Line dash style.
cap number Line cap style.
join number line join style.
miter_limit number Corner miter limit.

fn is a function that accepts an angle value (in radians) and returns a radius value.

If the extent is not supplied, the graph will be plotted for values of a from 0 to 2*math.pi radians (0 to 360 degrees). You can use a smaller or larger range.

The line_width is a nominal value that might require adjustment for very large or small graphs.

The parameters dash, cap, join and miter_limit are as described for the stroke method of Shapes.

If you found this article useful, you might be interested in the book Computer Graphics in Python or other books by the same author.

Prev

Popular tags

2d arrays abstract data type alignment and animation arc array arrays behavioural pattern bezier curve built-in function callable object circle classes close closure cmyk colour comparison operator comprehension context context manager conversion creational pattern data types design pattern device space dictionary drawing duck typing efficiency else encryption enumerate fill filter font font style for loop function function composition function plot functools game development generativepy tutorial generator geometry gif gradient greyscale higher order function hsl html image image processing imagesurface immutable object index inner function input installing iter iterable iterator itertools l system lambda function len line linspace list list comprehension logical operator lru_cache magic method mandelbrot mandelbrot set map monad mutability named parameter numeric python numpy object open operator optional parameter or partial application path polygon positional parameter print pure function pycairo radial gradient range recipes rectangle recursion reduce rgb rotation scaling sector segment sequence singleton slice slicing sound spirograph sprite square str strategy stream string stroke structural pattern subpath symmetric encryption template text text metrics tinkerbell fractal transform translation transparency tuple turtle unpacking user space vectorisation webserver website while loop zip