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 |
- Check Python Packaging User Guide
- Run
pip install samila==1.3
- Download Version 1.3 or Latest Source
- Run
pip install .
- Check Conda Managing Package
conda install -c sepandhaghighi samila
>>> 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
>>> 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()
>>> 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
and X2_VS_F2
ℹ️ Default mode is F1_VS_F2
>>> 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
>>> 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
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
>>> 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
>>> 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",...]
)
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()
>>> g = GenerativeImage(f1, f2)
>>> g.generate(seed=1018273)
>>> g.plot(projection=Projection.POLAR)
>>> plt.show()
Upload generated image directly to NFT.storage
>>> g.nft_storage(api_key="YOUR_API_KEY", timeout=5000)
{'status': True, 'message': 'FILE_LINK'}
You can also upload your config/data to nft storage as follows:
>>> g.nft_storage(api_key="API_KEY", upload_config=True)
{'status': {'image': True, 'config':True}, 'message': {'image':'IMAGE_FILE_LINK', 'config':'CONFIG_FILE_LINK'}
or
>>> g.nft_storage(api_key="API_KEY", upload_data=True)
{'status': {'image': True, 'data':True}, 'message': {'image':'IMAGE_FILE_LINK', 'data':'DATA_FILE_LINK'}
You have the option to choose a specific IPFS gateway:
>>> from samila import Gateway
>>> g.nft_storage(api_key="API_KEY", upload_data=True, gateway=Gateway.DWEB)
{'status': {'image': True, 'data':True}, 'message': {'image':'IMAGE_FILE_LINK', 'data':'DATA_FILE_LINK'}
ℹ️ Default timeout is 3000
seconds
ℹ️ Default gateway is IPFS_IO
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 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 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
}
}
Samila is simply a transformation between a square-shaped space from the Cartesian coordinate system to any arbitrary coordination like Polar coordinate system.
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)
Samila can be used online in interactive Jupyter Notebooks via the Binder or Colab services!
Try it out now!
ℹ️ Check examples
folder
Just fill an issue and describe it. We'll check it ASAP! or send an email to [email protected].
- Please complete the issue template
You can also join our discord server
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
This project was funded through the Next Step Microgrant, a program established by Protocol Labs.
Give a ⭐️ if this project helped you!
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 ;-) .