Just another one simple PyQt (PySide6) GUI that shows beautiful Mandelbrot and Julia fractals, allowing the user to explore them interactively. The user can zoom into different parts of the fractals, adjust calculation parameters, customise colours, and save the generated images.
- Interactive visualisation of Mandelbrot and Julia sets
- Support for arbitrary powers
$k$ (from 2 to 8) in defining the sets - Zooming and panning for detailed exploration
- Customisable calculation parameters
- Various colourmaps, including user-defined ones
- Shading options for enhanced visuals
- Export images to common formats
- Scripts for creating the zoom and rotation animations
- Installation
- Theory of Mandelbrot and Julia fractals
- Setting the limits and exploring
- Adjustable parameters
- Colours and Shading
- Saving and loading
- Animations
- Gallery
This Application requires Pyside 6.5+ and Python 3.11+. The easiest way is to create the virtual environment and run the code through it:
python3 -m venv fractal
source fractal/bin/activate
Then update pip, install all the required packages, and run the code:
pip3 install -r requirements.txt
python3 Interface.py
Both Mandelbrot and Julia sets are defined in the
complex plane
For the Mandelbrot set, the sequence starts
with
If, for a given value of
Strictly speaking, from a mathematical perspective,
images of the Mandelbrot and Julia sets should be
black-and-white β the given point either belongs
to the set or it does not. To add colour, a common
approach is used: points near the outer boundary of
the set are coloured based on the number of iterations
required to determine that the point does not belong
to the set (i.e. when the divergence
criterion
Where
The application allows the user to interactively explore different regions of the Mandelbrot and Julia sets by adjusting the limits of the complex plane.
- Use mouse selection to zoom into a rectangular region
of interest within the fractal display. Click
the
π
button on the matplotlib toolbar under the image and drag over the fractal image to define the zoom area. - The new region will be recalculated and rendered
based on the current or default parameters
(horizon,
$N$ , power,$C$ , see below). - Use the
Zoom
buttons to zoom-in or zoom-out twice. - The Matplotlib toolbar also includes the
Pan/Move
,π
(return to the initial view),β¬ οΈ
, andβ‘οΈ
(navigate to the previous/next view) buttons for moving around the image. - Zooming deeper into the set reveals more intricate
structures. As a result, a higher iteration limit
$N$ may be required for finer detail. By default, this limit depends on the zoom level β the deeper the zoom, the larger the$N$ value.
For precise control, you can set the complex plane limits manually:
- Click the
Set new limits
button to open the limit configuration dialogue. - Enter the desired bounds:
Xmin, Xmax
andYmin, Ymax
β the desired X- and Y-bounds, orXCentre
,YCentre
,deltaX
anddeltaY
β coordinates of the centre and the width of the X- and Y-axis.
- Confirm the values to apply them to the view.
The current X- and Y-limits, as well as the coordinates
of the centre, are displayed above the Zoom buttons.
Use the Reset limits
button to restore the default view range.
It varies depending on the set type and power.
The GUI provides several options that the user can customise:
- Set type β Choose between Mandelbrot and Julia sets.
-
Power β Degree of the polynomial
$k$ ($2 \leq k \leq 8$ ). Mandelbrot sets shift when the power is changed, so use theReset limits
button to re-centre the set. -
Horizon β Divergence threshold
$\geq4$ . Very large for Mandelbrot ($\sim 2\cdot 10^{50}$ ), but small for Julia ($\sim 4$ ). -
$N$ β Iteration limit β The maximum number of iterations per point. The deeper you zoom into the set, the larger the value of$N$ required. This value can be:- Entered manually
- Adjusted via the
N-slider
- Reset to default using the
Reset N
button. The default value of$N$ depends on the zoom level as$N=100\cdot(1 + \lg({\rm zoom}))$ .
To generate an image with the desired Horizon and
N, enter the values and click the Rebuild
button.
To restore the default values, click the Reset
button.
-
$C$ β Complex constant for Julia set. This can be set in two ways:- By adjusting the
C-sliders
to modify either the real and imaginary parts of$C = x_c + i y_c$ , or the modulus$\rho$ and argument$\varphi$ :$C=\rho e^{i\varphi}$ . The relevant option βReC, ImC
or$\rho$, $\varphi$
β is selected via the corresponding dropdown menu. - Clicking the
set C
button, which allows input via:- Real and imaginary parts, or
- Modulus and argument.
- By adjusting the
The current value of Reset C
button.
The application offers customisable colour schemes and shading effects to enhance the visualisation of the Mandelbrot and Julia sets:
Choose from a wide range of matplotlib colour palettes via the dropdown menu. Each option displays a preview of the colour gradient.
- User-defined colourmaps: By selecting the
Set your own colourmap...
option from the dropdown menu, you can create your own colourmap by placing colour points along the gradient. You can also save the created colourmap to a file and load previously saved colourmaps to edit or use them.
There are two colouring techniques available in the
Regime
dropdown menu:
-
Standard
: Applies linear colour scaling, mapping the lowest data value to 0 and the highest to 1. -
Sin
: Transforms the data using the formula$\sin^2(\omega \cdot \text{data} + \Delta)$ , where the frequency$\omega$ (default:$0.01$ ) and the offset$\Delta$ (default:$0.0$ ) can be set by the user. This allows for cyclic colour variation.
Click Set shading
to apply hillshading
effects. In the configuration dialogue adjust:
- The light sourceβs azimuth and altitude. Angles are in degrees, with the azimuth measured clockwise from north and elevation up from the zero plane of the surface.
- The vertical exaggeration for 3D-like depth. This is the amount to exaggerate the elevation values by when calculating illumination.
For details see the matplotlib documentation
and tutorials.
To revert to the flat colourmap display, click
the Remove shading
button.
Save / Load
dropdown menu allows you to save images,
as well as to save and load metadata.
Generated images can be exported in multiple formats
for high-quality output by choosing the Save image
option
or clicking the πΎ
icon on the matplotlib toolbar
under the image:
- Supported Formats: PNG, JPEG, TIFF, PDF, and EPS.
- Customisation: Specify dimensions (in inches) to
control resolution and file size.
Enable
Lock Aspect Ratio
to maintain the current proportions when adjusting the width or height. ToggleWith Axes
to retain coordinate labels and ticks. In that case, you can also set the dots per inches (DPI) of the image, which will affect the size of the axes β see here for a discussion on DPI. The image renders at the specified resolution, preserving shading and colourmap preferences. - Antialiasing: You can also enable antialiasing by setting the supersampling antialiasing (SSAA) factor. If this factor is equal to one, no antialiasing is applied. Otherwise, the image is rendered at a higher resolution (scaled by this factor along each axis) and then downsampled by averaging the pixels to reduce aliasing. For more details, see Wikipedia. Note that antialiasing could affect the image colours.
Metadata refers to a JSON file that contains all the
information about the generated fractal β set type,
calculation parameters, axis limits, and colouring/shading
options. By selecting the Save metadata
option, you can
save the current fractal for quick access in the future.
To load a previously saved fractal, choose the
Load metadata
option.
The script zoom_animation.py
generates a smooth zoom animation
of a fractal β either the Mandelbrot set or a Julia set. It supports
many customisation options, which are described via the --help
flag:
python3 zoom_animation.py --help
usage: zoom_animation.py [-h] [--metadata METADATA] [--x_centre_1 X_CENTRE_1]
[--y_centre_1 Y_CENTRE_1] [--delta_x_1 DELTA_X_1]
[--delta_y_1 DELTA_Y_1] [--x_centre_2 X_CENTRE_2]
[--y_centre_2 Y_CENTRE_2] [--delta_x_2 DELTA_X_2]
[--delta_y_2 DELTA_Y_2] [--x_c X_C] [--y_c Y_C]
[-m mandelbrot|julia|burning_ship|burning_ship_julia]
[-p {2,3,4,5,6,7,8}] [--n_regime dynamic|static]
[--n_i N_I] [--n_f N_F] [-H HORIZON] [-f FRAMES]
[-l LENGTH] [-hei HEIGHT] [-c COLOURMAP]
[--c_regime standard|sin] [-fr FREQ] [-of OFFSET] [-s]
[-az AZDEG] [-al ALTDEG] [-ve VERT_EXAG] [-t THREADS]
[-ss SUPERSAMPLING]
...description...
The primary input parameters are the coordinates of the centres of
the initial and final fractals, along with the widths of the
X- and Y-axes for both views. Alternatively, you may provide
a previously saved metadata.json
file to set the final
fractal's coordinates and other calculation and colouring options.
You can also use a previously saved colourmap.json
file
to set the custom colourmap.
Another important parameter is the maximum number of iterations,
-
Static
β$N$ remains constant across all animation frames. It can be specified using the--n_f
flag. If metadata is provided, the number of iterations will be taken from there. -
Dynamic
β$N$ changes dynamically fromn_i
ton_f
, following the$n = n_i\cdot(1 + \alpha\lg({\rm zoom}))$ formula, where$\alpha$ is determined fromn_i
(default: 100) andn_f
. If metadata is provided, then_f
parameter will be taken from there.
Note: The aspect ratios of the initial and final frames should match. You can ensure this by adjusting the axis widths and the image's length and height accordingly. If the aspect ratios differ, the script will suggest possible corrections, but can still generate a video using the current aspect ratio.
Below is an example video created with the default values for all flags:
python3 zoom_animation.py
The video has been compressed for README:
video.mp4
Another example is created from this metadata, using the following flags:
python3 zoom_animation.py --metadata Metadata_11.json --length 1500
The video has been compressed for README:
output_reduce.mp4
The script rotate_animation.py
generates a smooth rotational animation
of a Julia set, in which the angle (argument --help
flag:
python3 rotate_animation.py --help
usage: rotate_animation.py [-h] [--metadata METADATA] [--xmin XMIN]
[--xmax XMAX] [--ymin YMIN] [--ymax YMAX]
[--rho RHO] [--phi_min PHI_MIN] [--phi_max PHI_MAX]
[-m julia|burning_ship_julia] [--n N]
[-p {2,3,4,5,6,7,8}] [-H HORIZON] [-f FRAMES]
[-l LENGTH] [-hei HEIGHT] [-c COLOURMAP]
[--c_regime standard|sin] [-fr FREQ] [-of OFFSET]
[-s] [-az AZDEG] [-al ALTDEG] [-ve VERT_EXAG]
[-t THREADS] [-ss SUPERSAMPLING]
...description...
The primary input parameters are the bounds of the X- and Y-axes,
the modulus metadata.json
file to set the fractal's coordinates and other calculation and
colouring options. You can also use a previously
saved colourmap.json
file to set the custom colourmap.
Note: The aspect ratio of the axes and image size should match. You can ensure this by adjusting the axis widths and the image's length and height accordingly. If the aspect ratios differ, the script will suggest possible corrections, but can still generate a video using the current aspect ratio.
Below is an example video created using the following flag:
python3 rotate_animation.py --power 3 --xmin -1.5 --xmax 1.5 --ymin -1.5 --ymax 1.5
The video has been compressed for README:
video.mp4
Overall, have fun! Some screenshots with corresponding metadata:
First:
Second:
Third:
Sin
colourisation results in beautifully cycling colours.
The parameter
Fifth:
Shading option (
vert_exag=3.0
) with
custom colourmap (Metadata):
Seventh:
Sin
colourisation and shading (vert_exag=100.0
, Metadata):