Overview
Samila is a generative art generator written in Python, Samila lets you create images based on many thousand points. The position of every single point is calculated by a formula, which has random parameters. Because of the random numbers, every image looks different.
| Open Hub |  |
| PyPI Counter |  |
| Github Stars |  |
| Branch | master | dev |
| CI |  |  |
| Code Quality |  |  |
Installation
PyPI
Source code
Conda
Usage
Magic
>>> import matplotlib.pyplot as plt
>>> from samila import GenerativeImage
>>> g = GenerativeImage()
>>> g.generate()
>>> g.plot()
>>> plt.show()
ℹ️ You can change function generation seed by func_seed parameter in GenerativeImage
Basic
>>> import random
>>> import math
>>> def f1(x, y):
result = random.uniform(-1,1) * x**2 - math.sin(y**2) + abs(y-x)
return result
>>> def f2(x, y):
result = random.uniform(-1,1) * y**3 - math.cos(x**2) + 2*x
return result
>>> g = GenerativeImage(f1, f2)
>>> g.generate()
>>> g.plot()
>>> g.seed
188781
>>> plt.show()
Generation mode
>>> from samila import GenerateMode
>>> g = GenerativeImage(f1, f2)
>>> g.generate(mode=GenerateMode.F1_VS_INDEX)
>>> g.plot()
>>> g.seed
883114
>>> plt.show()
ℹ️ Supported modes : F1_VS_F2, F2_VS_F1, F1_VS_INDEX, F2_VS_INDEX, INDEX_VS_F1, INDEX_VS_F2, F1_VS_X1, F1_VS_X2, F2_VS_X1, F2_VS_X2, X1_VS_F1, X1_VS_F2, X2_VS_F1, X2_VS_F2, F1F2_VS_F1, F1F2_VS_F2, F1_VS_F1F2, F2_VS_F1F2 and RANDOM
ℹ️ Default mode is F1_VS_F2
Projection
>>> from samila import Projection
>>> g = GenerativeImage(f1, f2)
>>> g.generate()
>>> g.plot(projection=Projection.POLAR)
>>> g.seed
829730
>>> plt.show()
ℹ️ Supported projections : RECTILINEAR, POLAR, AITOFF, HAMMER, LAMBERT, MOLLWEIDE and RANDOM
ℹ️ Default projection is RECTILINEAR
Marker
>>> from samila import Marker
>>> g = GenerativeImage(f1, f2)
>>> g.generate()
>>> g.plot(marker=Marker.CIRCLE, spot_size=10)
>>> g.seed
448742
>>> plt.show()
ℹ️ Supported markers : POINT, PIXEL, CIRCLE, TRIANGLE_DOWN, TRIANGLE_UP, TRIANGLE_LEFT, TRIANGLE_RIGHT, TRI_DOWN, TRI_UP, TRI_LEFT, TRI_RIGHT, OCTAGON, SQUARE, PENTAGON, PLUS, PLUS_FILLED, STAR, HEXAGON_VERTICAL, HEXAGON_HORIZONTAL, X, X_FILLED, DIAMOND, DIAMON_THIN, VLINE, HLINE and RANDOM
ℹ️ Default marker is POINT
Rotation
You can even rotate your art by using rotation parameter. Enter your desired rotation for the image in degrees and you will have it.
>>> g = GenerativeImage(f1, f2)
>>> g.generate()
>>> g.plot(rotation=45)
ℹ️ Default rotation is 0
Range
>>> g = GenerativeImage(f1, f2)
>>> g.generate(start=-2*math.pi, step=0.01, stop=0)
>>> g.plot()
>>> g.seed
234752
>>> plt.show()
ℹ️ Default range is $(-\pi, \pi)$
Color
>>> g = GenerativeImage(f1, f2)
>>> g.generate()
>>> g.plot(color="yellow", bgcolor="black", projection=Projection.POLAR)
>>> g.seed
1018273
>>> plt.show()
ℹ️ Default color is black
ℹ️ Default background-color is white
ℹ️ Supported colors are available in VALID_COLORS list
ℹ️ color and bgcolor parameters supported formats:
- Color name (example:
color="yellow")
- RGB/RGBA (example:
color=(0.1,0.1,0.1), color=(0.1,0.1,0.1,0.1))
- Hex (example:
color="#eeefff")
- Random (example:
color="random")
- Complement (example:
color="complement", bgcolor="blue")
- Transparent (example:
bgcolor="transparent")
- List (example:
color=["black", "#fffeef",...])
⚠️ Transparent mode is only available for background
⚠️ List mode is only available for color
⚠️ In List mode, the length of this list must be equal to the lengths of data1 and data2
Point color
You can make your custom color map and use it in Samila.
>>> colorarray = [
... [0.7, 0.2, 0.2, 1],
... [0.6, 0.3, 0.2, 1],
... "black",
... [0.4, 0.4, 0.3, 1],
... [0.3, 0.4, 0.4, 1],
... "#ff2561"]
>>> g.generate()
>>> g.seed
454893
>>> g.plot(cmap=colorarray, color=g.data2, projection=Projection.POLAR)
>>> plt.show()
Regeneration
>>> g = GenerativeImage(f1, f2)
>>> g.generate(seed=1018273)
>>> g.plot(projection=Projection.POLAR)
>>> plt.show()
Save image
Save generated image.
>>> g.save_image(file_adr="test.png")
{'status': True, 'message': 'FILE_PATH'}
Save generated image in higher resolutions.
>>> g.save_image(file_adr="test.png", depth=5)
{'status': True, 'message': 'FILE_PATH'}
Save data
Save generated image data.
>>> g.save_data(file_adr="data.json")
{'status': True, 'message': 'FILE_PATH'}
So you can load it into a GenerativeImage instance later by
>>> g = GenerativeImage(data=open('data.json', 'r'))
Data structure:
{
"plot": {
"projection": "polar",
"bgcolor": "black",
"color": "snow",
"spot_size": 0.01
},
"matplotlib_version": "3.0.3",
"data1": [
0.3886741692042526,
22.57390286376703,
-0.1646310981668766,
66.23632344600155
],
"data2": [
-0.14588750183600108,
20.197945942677833,
0.5485453260942901,
-589.3284610518896
]
}
Save config
Save generated image config. It contains string formats of functions which is also human readable.
>>> g.save_config(file_adr="config.json")
{'status': True, 'message': 'FILE_PATH'}
So you can load it into a GenerativeImage instance later by
>>> g = GenerativeImage(config=open('config.json', 'r'))
Config structure:
{
"matplotlib_version": "3.0.3",
"generate": {
"seed": 379184,
"stop": 3.141592653589793,
"step": 0.01,
"start": -3.141592653589793
},
"f2": "random.uniform(-1,1)*math.cos(x*(y**3))+random.uniform(-1,1)*math.ceil(y-x)",
"f1": "random.uniform(-1,1)*math.ceil(y)-random.uniform(-1,1)*y**2+random.uniform(-1,1)*abs(y-x)",
"plot": {
"color": "snow",
"bgcolor": "black",
"projection": "polar",
"spot_size": 0.01
}
}
Command Line Interface (CLI)
You can easily create art directly from the command line with Samila CLI. Here's an example command to get started:
samila --color=red --bgcolor=black --rotation=30 --projection=polar --mode f2_vs_f1 --save-image test.png
In this example:
--color=red: Sets the primary color of the art.
--bgcolor=black: Sets the background color.
--rotation=30: Rotates the artwork by 30 degrees.
--projection=polar: Use polar projection for plotting.
--mode=f2_vs_f1: Sets the generation mode
--save-image=test.png: Saves the generated image as test.png.
For more options and detailed usage, run the following command to access help:
samila --help
This will provide additional information on all available parameters and how to customize your artwork further.
Mathematical details
Samila is simply a transformation between a square-shaped space from the Cartesian coordinate system to any arbitrary coordination like Polar coordinate system.
Example
We have set of points in the first space (left square) which can be defined as follow:
And below functions are used for transformation:
>>> def f1(x, y):
result = random.uniform(-1,1) * x**2 - math.sin(y**2) + abs(y-x)
return result
>>> def f2(x, y):
result = random.uniform(-1,1) * y**3 - math.cos(x**2) + 2*x
return result
here we use Projection.POLAR so later space will be the polar space and we have:
>>> g = GenerativeImage(f1, f2)
>>> g.generate(seed=10)
>>> g.plot(projection=Projection.POLAR)
Try Samila in your browser!
Samila can be used online in interactive Jupyter Notebooks via the Binder or Colab services!
Try it out now!


ℹ️ Check examples folder
Issues & bug reports
Just fill an issue and describe it. We'll check it ASAP! or send an email to info@samila.site.
- Please complete the issue template
You can also join our discord server
Social media
References
1- Schönlieb, Carola-Bibiane, and Franz Schubert. "Random simulations for generative art construction–some examples." Journal of Mathematics and the Arts 7.1 (2013): 29-39.
2- Create Generative Art with R
3- NFT.storage : Free decentralized storage and bandwidth for NFTs
Cite
If you use Samila in your research, we would appreciate citations to the following paper:
Sabouri, Sadra, Sepand Haghighi, and Elena Masrour. "Samila: A Generative Art Generator." arXiv preprint arXiv:2504.04298 (2025).
@article{sabouri2025samila,
title={Samila: A Generative Art Generator},
author={Sabouri, Sadra and Haghighi, Sepand and Masrour, Elena},
journal={arXiv preprint arXiv:2504.04298},
year={2025}
}
Acknowledgments
This project was funded through the Next Step Microgrant, a program established by Protocol Labs.
Show your support
Star this repo
Give a ⭐️ if this project helped you!
Donate to our project
If you do like our project and we hope that you do, can you please support us? Our project is not and is never going to be working for profit. We need the money just so we can continue doing what we do ;-) .

Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog
and this project adheres to Semantic Versioning.
1.6 - 2025-07-16
Added
Changed
README.md updated
demo.ipynb updated
- Test system modified
Python 3.6 support dropped
- Python typing features added to all modules
Removed
nft_storage method
Gateway enum
1.5 - 2025-01-22
Added
- 3 new generation modes
RANDOM
F1F2_VS_F1
F1F2_VS_F2
Changed
- Elapsed time added to CLI
- CLI bug fixed
--function_seed argument renamed to --function-seed
- Random mode modified
README.md updated
demo.ipynb updated
1.4 - 2024-11-20
Added
- Command Line Interface (CLI)
Changed
- GitHub actions are limited to the
dev and master branches
- Test system modified
Python 3.13 added to test.yml
1.3 - 2024-09-09
Added
deprecated function
- 14 new generation modes
F1_VS_F2
F2_VS_F1
F1_VS_INDEX
F2_VS_INDEX
INDEX_VS_F1
INDEX_VS_F2
F1_VS_X1
F2_VS_X1
F1_VS_X2
F2_VS_X2
X1_VS_F1
X1_VS_F2
X2_VS_F1
X2_VS_F2
bulk.ipynb notebook
Changed
mode parameter added to generate method
README.md updated
demo.ipynb updated
1.2 - 2024-06-25
Added
feature_request.yml template
config.yml for issue template
get_cmap function
Gateway enum
SECURITY.md
Changed
- Bug report template modified
func_seed parameter added to GenerativeImage __init__
- Minor edits in
functions.py
DEFAULT_CMAP renamed to DEFAULT_CMAP_NAME
pillow added to conda dependencies
codecov removed from dev-requirements.txt
gateway parameter added to nft_storage method
- Test system modified
- Random mode modified
README.md updated
Python 3.5 support dropped
Python 3.12 added to test.yml
1.1 - 2023-04-05
Added
__version__ attribute
python_version attribute
get_python_version function
RANDOM_EQUATION_MIN_COMPLEXITY parameter
RANDOM_EQUATION_FOF_MAX_DEPTH parameter
RANDOM_EQUATION_FOF_MIN_DEPTH parameter
rotate function
Changed
rotation parameter added to plot method
timeout parameter added to nft_storage method
load_config function modified
nft_storage_upload function modified
- Random mode modified
RANDOM_EQUATION_GEN_COMPLEXITY parameter renamed to RANDOM_EQUATION_MAX_COMPLEXITY
README.md updated
1.0 - 2022-12-14
Added
Marker enum
get_data function
get_config function
Changed
marker parameter added to plot method
upload_data parameter added to nft_storage method
upload_config parameter added to nft_storage method
generate method optimized
- Test system modified
README.md updated
Python 3.11 added to test.yml
plot method warning bug fixed
- Random mode modified
Removed
0.9 - 2022-09-28
Added
Changed
README.md updated
CODE_OF_CONDUCT.md updated
demo.ipynb updated
cmap parameter added to plot method
- Random mode modified
- Test system modified
generate method optimized
samila_help function updated
load_data and load_config functions error handling updated
0.8 - 2022-06-01
Added
INVALID_COLOR_TYPE_ERROR error
COLOR_NOT_FOUND_WARNING warning
BOTH_COLOR_COMPLEMENT_WARNING warning
set_background function
is_valid_color function
color_complement function
select_color function
Changed
- Transparent mode support for
bgcolor parameter
- Random mode modified
- Complementary color support for
color and bgcolor parameters
filter_color function modified
0.7 - 2022-05-04
Added
fill_data function
random_hex_color_gen function
color,bgcolor and projection parameters random mode
Changed
- Calculation warning added to
generate method
- Hex color support for
color and bgcolor parameters
- Test system modified
- Random mode modified
filter_color function modified
filter_projection function modified
is_same_data function modified
README.md updated
0.6 - 2022-04-13
Added
save_params_filter function
Changed
__del__ method updated
message field changed in save_fig_file function
message field changed in save_config_file function
message field changed in save_data_file function
message field changed in nft_storage_upload function
depth section added to config/data file
linewidth parameter added to plot method
linewidth parameter added to plot_params_filter function
- Random mode modified
README.md updated
0.5 - 2022-03-21
Added
__del__ method
- Demo notebook
Changed
depth parameter added to nft_storage method
depth parameter added to save_fig_buf function
alpha parameter added to plot method
alpha parameter added to plot_params_filter function
- Random mode modified
README.md updated
0.4 - 2022-01-13
Added
PLOT_DATA_ERROR error message
_GI_initializer function
generate_params_filter function
plot_params_filter function
filter_size function
save_config method
load_config function
save_config_file function
samilaConfigError class
samilaPlotError class
filter_float function
- Random equations mode
function1_str attribute
function2_str attribute
Changed
README.md updated
plot section added to data file
edgecolor changed to c in plot method
config parameter added to GenerativeImage __init__
filter_projection function edited
- Test system updated
Removed
NO_FUNCTION_ERROR error message
DATA_PARSING_ERROR error message
JUST_DATA_WARNING warning message
0.3 - 2021-11-10
Added
- Discord channel
load_data function
save_data_file function
save_data method
Changed
data parameter added to GenerativeImage __init__ method
depth parameter added to save_image method
depth parameter added to save_fig_file function
save_image and nft_storage methods background bug fixed
README.md updated
- Test system updated
Python 3.10 added to test.yml
0.2 - 2021-10-14
Added
dependabot.yml
requirements-splitter.py
samila_help function
test.py
function_test.py
overall_test.py
nft_upload_test.py
is_same_data function
save_image method
Changed
dev-requirements.txt updated
README.md updated
__main__.py updated
- Test system updated
nft_storage method updated
0.1 - 2021-09-30
Added
GenerativeImage class
plot method
generate method
nft_storage method