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.

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

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)

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.

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.

Draws the axes using the Context supplied in the `Axes`

constructor.

draw()

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.

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.

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.

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.

Copyright (c) Axlesoft Ltd 2020