Python Julia Plotter
A script to render Julia sets (the
sets of points in the complex plane that don’t escape with the repeated
application of a complex rational function) or grids of Julia sets with a
comfortable command-line interface, enabled-by-default conversion to
magick required in path), and pretty-by-default HTML export.
Table of Contents
- Python Julia Plotter
- Table of Contents
- HTML Output Features
- General Usage
- Example Renders
- Arguments and options
- Quick argument table
- -f zₙ₊₁, --fn zₙ₊₁ (Default: z^2 + c)
- -c constant (Default: 0 + 0i)
- -a aspect, --aspect aspect (Default: 1)
- -w width, --width width (Default: 500)
- -i iterations, --iterations iterations (Default: 32)
- -r c-range, --c-range c-range (Default: 1.5)
- -n cell count, --cell-count cell count (Default: 1)
- -e cx cy, --center cx cy (Default: 0 0)
- -z zoom, --zoom zoom (Default: 1)
- -s, --silent (Default: Off)
Low memory requirements
Instead of storing the image data an array before writing it, it’s written one
byte at a time. This means that rendering a 65536×65536 image takes up just as
much (run-time) memory as rendering a 500×500 image. The raw
.ppm output will
9 + ⌈log10(w)⌉ + ⌈log10(⌊w/a⌋)⌉ + 3w⌊w/a⌋ bytes (three per pixel plus
a header, where
w is the image width and
a is the aspect ratio).
Any formula is accepted, with fairly versatile equation parsing.
- Imaginary numbers in the form of (ex.
- Coefficients for variables and functions (
- Implicit parenthesis (ONLY if the variable passed to a function is unmodified;
sin z^2will parse as
- Implicit multiplication (
(z - 2)(z + c),
z(z - 3),
- Exponentiation (
julia.py contains a built-in system for rendering grids of Julia sets. Why?
Because the same equation that makes this very interesting image:
./julia.py -f "(z-c)(z+2-0.5i)(z+0.5c)(z)" -c "0 + 0.9 i" -i 32 -w 2048 -a 1.0 -e 0.0 0.0 -z 1.0 -g 1.0 -u 30.0
(Note: Most of those arguments are superfluous, but are outputted in case
defaults change. The actual rendering command was something much closer to
./julia.py -f "(z-c)(z+2-0.5i)(z+0.5c)(z)" -c "0 + 0.9 i" -w 2048)
Creates this very uninteresting image:
./julia.py -f "(z-c)(z+2-0.5i)(z+0.5c)(z)" -c "0.3 + 0.3 i" -i 32 -w 2048 -a 1.0 -e 0.0 0.0 -z 0.75 -g 1.0 -u 30.0
These two sets are in the same family of equations, but have a different
constant c. With the
-n cells option,
julia.py will render a grid of
cells × cells sets with c-values ranging from -range to range in the real axis,
and -range·i to range·i in the imaginary axis, where the range is controlled
-r range option. We may discover which constants are interesting and
which are not with a preliminary render:
julia.py -f "(z-c)(z+2-0.5i)(z+0.5c)(z)" -n 11 -i 32 -w 2048 -a 1.0 -e 0 0 -z 0.5 -g 1.0 -u 30
(Aside: Although it might look it at first, the grid is not symmetrical over the real or imaginary axis.)
julia.py will then automatically open the HTML output, allowing us to click on
an interesting cell and copy the command-line invocation to create a more
HTML Output Features
At a glance, the HTML output contains everything you need to recreate a render, the easy way (by copying and pasting the given command-line invocation) or the hard way (by manually typing in the arguments in the table [do not do this]). There are two other notable features:
- In renders with multiple cells (i.e. with
-n> 1), clicking on a cell in the image will reveal the column, row, c-value, and a command-line invocation to render that cell in a larger image (by default to the same width as the render it came from). Note that this uses an image
- In renders with one cell (i.e. with
-n 1or with
-e). By clicking on a region of the render you would like to see enlarged and increasing the zoom value (
-z), more detailed renders can easily be created.
usage: julia.py [-h] [-f zₙ₊₁] [-c constant] [-a aspect] [-w width] [-i iterations] [-r c-range] [-e center center] [-n cell count] [-z zoom] [-g gradient speed] [-u escape]
Note that if
-f is omitted, it will default to
z^2 + c, and if
omitted, it will default to
0 + 0i, but if both
-c are omitted,
-f will default to
z^2 + c and
-c will default to
random — this may
be unexpected, but results in interesting-and-unpredictable-by-default renders.
./julia.py -f "(z^3)/(((z-2)^5)(z+0.5i)) + c" -c " 1.16667 + 0.166667i" -i 32 -w 2048 -a 1.0 -e 2.0 0.0 -z 0.5 -g 1.0 -u 30
./julia.py -c "0.285 + 0.01i" -z 0.75 -w 2048
Arguments and options
The following is an enumeration of most of the useful and common arguments.
There are a few others and this readme may fall slightly out of date — view the
most up-to-date and complete list with
Quick argument table
|Arg||Long arg||What it controls||Default value|
||Render function zₙ₊₁(z, c)||
||Render constant (
||Image aspect ratio||
||Range of c-values when
||Info output, shelling out||Off|
-f zₙ₊₁, --fn zₙ₊₁ (Default:
z^2 + c)
The Julia set's function for iteration. Enter
random to generate a random
complex rational function (P(z)/Q(z), where P and Q are complex polynomials of
maximum degree 3 and 6, respectively).
-c constant (Default:
0 + 0i)
The constant c for the function zₙ₊₁(z, c). Enter
random to select a random
value for c.
-a aspect, --aspect aspect (Default:
The output image's w/h aspect ratio. Ex.:
-a 2 implies an image twice as wide
as it is tall.
-w width, --width width (Default:
The output image's width.
-i iterations, --iterations iterations (Default:
The iterations to calculate the set to.
-r c-range, --c-range c-range (Default:
The range of c values to use — only relevant if the cell count option is used to
render a grid of sets; the c values for each sets will range from
(c_r - crange, c_i - crange·i) to
(c_r + crange, c_i + crange·i), where
c_i are the real and imaginary components of the constant supplied with
-n cell count, --cell-count cell count (Default:
The number of rows and columns to render. A cell count of 1 will render a single
set, and other values will render grids of Julia sets. The different values of c
are determined by
-r. Note that
-n 4 implies 4 rows and 4
columns, for a total of 16 actual cells (
--row-and-column-count was considered
slightly too verbose), perhaps a mildly confusing name.
-e cx cy, --center cx cy (Default:
The coordinate the graph is centered around, entered as two floats separated by a space. (Not a comma! No parenthesis! Technically two separate arguments consumed by one option.)
-z zoom, --zoom zoom (Default:
How zoomed in the render is. The distance between the center-point and the top / bottom of the rendered area is 1 / zoom. Larger values of will produce a more zoomed-in image, smaller values (<1) will produce a more zoomed-out image.
-s, --silent (Default: Off)
Don't log info, show progress, convert the .ppm to a .png, or open the file when
finished. Equivalent to
--no-open --no-convert --no-progress --no-info.
MIT / Expat; see license.txt.