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()

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)

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.

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.

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.

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.

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.

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.