kopia lustrzana https://github.com/sepandhaghighi/samila
commit
e42f80847d
|
@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
|
|||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at info@4r7.ir. All
|
||||
reported by contacting the project team at info@samila.site. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
name: publish_conda
|
||||
|
||||
on:
|
||||
push:
|
||||
# Sequence of patterns matched against refs/tags
|
||||
tags:
|
||||
- '*' # Push events to matching v*, i.e. v1.0, v20.15.10
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: publish-to-conda
|
||||
uses: sepandhaghighi/conda-package-publish-action@v1.2
|
||||
with:
|
||||
subDir: 'otherfiles'
|
||||
AnacondaToken: ${{ secrets.ANACONDA_TOKEN }}
|
|
@ -60,3 +60,6 @@ jobs:
|
|||
run: |
|
||||
codecov
|
||||
if: matrix.python-version == 3.7 && matrix.os == 'ubuntu-latest'
|
||||
- name: cProfile
|
||||
run: |
|
||||
python -m cProfile -s cumtime otherfiles/samila_profile.py
|
||||
|
|
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -5,6 +5,19 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
## [0.9] - 2022-09-28
|
||||
### Added
|
||||
- Anaconda workflow
|
||||
### 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
|
||||
|
@ -123,7 +136,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
- `generate` method
|
||||
- `nft_storage` method
|
||||
|
||||
[Unreleased]: https://github.com/sepandhaghighi/samila/compare/v0.8...dev
|
||||
[Unreleased]: https://github.com/sepandhaghighi/samila/compare/v0.9...dev
|
||||
[0.9]: https://github.com/sepandhaghighi/samila/compare/v0.8...v0.9
|
||||
[0.8]: https://github.com/sepandhaghighi/samila/compare/v0.7...v0.8
|
||||
[0.7]: https://github.com/sepandhaghighi/samila/compare/v0.6...v0.7
|
||||
[0.6]: https://github.com/sepandhaghighi/samila/compare/v0.5...v0.6
|
||||
|
|
37
README.md
37
README.md
|
@ -8,6 +8,7 @@
|
|||
<img src="https://codecov.io/gh/sepandhaghighi/samila/branch/master/graph/badge.svg" />
|
||||
</a>
|
||||
<a href="https://badge.fury.io/py/samila"><img src="https://badge.fury.io/py/samila.svg" alt="PyPI version" height="18"></a>
|
||||
<a href="https://anaconda.org/sepandhaghighi/samila"><img src="https://anaconda.org/sepandhaghighi/samila/badges/version.svg"></a>
|
||||
<a href="https://colab.research.google.com/github/sepandhaghighi/samila/blob/master">
|
||||
<img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Samila-Colab"/>
|
||||
</a>
|
||||
|
@ -88,7 +89,7 @@ Samila is a generative art generator written in Python, Samila let's you create
|
|||
|
||||
|
||||
### Source code
|
||||
- Download [Version 0.8](https://github.com/sepandhaghighi/samila/archive/v0.8.zip) or [Latest Source ](https://github.com/sepandhaghighi/samila/archive/dev.zip)
|
||||
- Download [Version 0.9](https://github.com/sepandhaghighi/samila/archive/v0.9.zip) or [Latest Source ](https://github.com/sepandhaghighi/samila/archive/dev.zip)
|
||||
- Run `pip install -r requirements.txt` or `pip3 install -r requirements.txt` (Need root access)
|
||||
- Run `python3 setup.py install` or `python setup.py install` (Need root access)
|
||||
|
||||
|
@ -96,12 +97,17 @@ Samila is a generative art generator written in Python, Samila let's you create
|
|||
|
||||
|
||||
- Check [Python Packaging User Guide](https://packaging.python.org/installing/)
|
||||
- Run `pip install samila==0.8` or `pip3 install samila==0.8` (Need root access)
|
||||
- Run `pip install samila==0.9` or `pip3 install samila==0.9` (Need root access)
|
||||
|
||||
### Easy install
|
||||
|
||||
- Run `easy_install --upgrade samila` (Need root access)
|
||||
|
||||
### Conda
|
||||
|
||||
- Check [Conda Managing Package](https://conda.io)
|
||||
- `conda install -c sepandhaghighi samila` (Need root access)
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
|
@ -181,9 +187,34 @@ Samila is a generative art generator written in Python, Samila let's you create
|
|||
4. Random (example: `color="random"`)
|
||||
5. Complement (example: `color="complement", bgcolor="blue"`)
|
||||
6. Transparent (example: `bgcolor="transparent"`)
|
||||
7. 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
|
||||
|
||||
```pycon
|
||||
>>> 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()
|
||||
```
|
||||
<img src="https://github.com/sepandhaghighi/samila/raw/master/otherfiles/images/8.png">
|
||||
|
||||
|
||||
### Regeneration
|
||||
```pycon
|
||||
>>> g = GenerativeImage(f1, f2)
|
||||
|
@ -333,7 +364,7 @@ Samila can be used online in interactive Jupyter Notebooks via the Binder or Col
|
|||
|
||||
## Issues & bug reports
|
||||
|
||||
Just fill an issue and describe it. We'll check it ASAP!
|
||||
Just fill an issue and describe it. We'll check it ASAP! or send an email to [info@samila.site](mailto:info@samila.site "info@samila.site").
|
||||
|
||||
- Please complete the issue template
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
python -m autopep8 samila --recursive --aggressive --aggressive --in-place --pep8-passes 2000 --verbose
|
||||
python -m autopep8 samila --recursive --aggressive --aggressive --in-place --pep8-passes 2000 --verbose --ignore=E721
|
||||
python -m autopep8 setup.py --recursive --aggressive --aggressive --in-place --pep8-passes 2000 --verbose
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
python -m autopep8 samila --recursive --aggressive --aggressive --in-place --pep8-passes 2000 --verbose
|
||||
python -m autopep8 samila --recursive --aggressive --aggressive --in-place --pep8-passes 2000 --verbose --ignore=E721
|
||||
python -m autopep8 setup.py --recursive --aggressive --aggressive --in-place --pep8-passes 2000 --verbose
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
matplotlib==3.5.2
|
||||
art==5.6
|
||||
matplotlib==3.5.3
|
||||
art==5.7
|
||||
vulture>=1.0
|
||||
bandit>=1.5.1
|
||||
pydocstyle>=3.0.0
|
||||
|
|
|
@ -134,9 +134,7 @@
|
|||
"source": [
|
||||
"## Color\n",
|
||||
"\n",
|
||||
"We can assign colors for both the background as well as the line\n",
|
||||
"\n",
|
||||
"Supported colors are available in `VALID_COLORS` list\n"
|
||||
"We can assign colors for both the background as well as the line\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -155,6 +153,7 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"* Supported colors are available in `VALID_COLORS` list\n",
|
||||
"* `color` and `bgcolor` parameters supported formats:\n",
|
||||
"\n",
|
||||
" 1. Color name (example: `color=\"yellow\"`)\n",
|
||||
|
@ -163,8 +162,40 @@
|
|||
" 4. Random (example: `color=\"random\"`)\n",
|
||||
" 5. Complement (example: `color=\"complement\", bgcolor=\"blue\"`)\n",
|
||||
" 6. Transparent (example: `bgcolor=\"transparent\"`)\n",
|
||||
" 7. List (example: `color=[\"black\", \"#fffeef\",...]`)\n",
|
||||
"\n",
|
||||
"⚠️ **Transparent** mode is only available for background"
|
||||
"⚠️ **Transparent** mode is only available for background\n",
|
||||
"\n",
|
||||
"⚠️ **List** mode is only available for color\n",
|
||||
"\n",
|
||||
"⚠️ In **List** mode, the length of this list must be equal to the lengths of data1 and data2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Point Color\n",
|
||||
"\n",
|
||||
"You can make your custom color map and use it in Samila"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"colorarray = [\n",
|
||||
" [0.7, 0.2, 0.2, 1],\n",
|
||||
" [0.6, 0.3, 0.2, 1],\n",
|
||||
" \"black\",\n",
|
||||
" [0.4, 0.4, 0.3, 1],\n",
|
||||
" [0.3, 0.4, 0.4, 1],\n",
|
||||
" \"#ff2561\"]\n",
|
||||
"g2.generate()\n",
|
||||
"g2.plot(cmap=colorarray, color=g2.data2, projection=Projection.POLAR)\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -351,8 +382,31 @@
|
|||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.5.2"
|
||||
},
|
||||
"toc": {
|
||||
"base_numbering": 1,
|
||||
"nav_menu": {},
|
||||
"number_sections": false,
|
||||
"sideBar": true,
|
||||
"skip_h1_title": true,
|
||||
"title_cell": "Samila Demo",
|
||||
"title_sidebar": "Samila Demo",
|
||||
"toc_cell": false,
|
||||
"toc_position": {
|
||||
"height": "382px",
|
||||
"left": "10px",
|
||||
"top": "10px",
|
||||
"width": "256px"
|
||||
},
|
||||
"toc_section_display": false,
|
||||
"toc_window_display": true
|
||||
},
|
||||
"vscode": {
|
||||
"interpreter": {
|
||||
"hash": "e7370f93d1d0cde622a1f8e1c04877d8463912d04d973331ad4851f04de6915a"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
}
|
||||
|
|
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 403 KiB |
|
@ -0,0 +1,37 @@
|
|||
{% set name = "samila" %}
|
||||
{% set version = "0.9" %}
|
||||
|
||||
package:
|
||||
name: {{ name|lower }}
|
||||
version: {{ version }}
|
||||
source:
|
||||
git_url: https://github.com/sepandhaghighi/samila
|
||||
git_rev: v{{ version }}
|
||||
build:
|
||||
noarch: python
|
||||
number: 0
|
||||
script: {{ PYTHON }} -m pip install . -vv
|
||||
requirements:
|
||||
host:
|
||||
- pip
|
||||
- setuptools
|
||||
- python >=3.5
|
||||
run:
|
||||
- art >=1.8
|
||||
- matplotlib >=3.0.0
|
||||
- requests >=2.20.0
|
||||
- python >=3.5
|
||||
about:
|
||||
home: https://github.com/sepandhaghighi/samila
|
||||
license: MIT
|
||||
license_family: MIT
|
||||
summary: Generative Art Generator
|
||||
description: |
|
||||
Samila is a generative art generator written in Python, Samila let's you create arts 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.
|
||||
|
||||
Website: https://www.samila.site
|
||||
|
||||
Repo: https://github.com/sepandhaghighi/samila
|
||||
extra:
|
||||
recipe-maintainers:
|
||||
- sepandhaghighi
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Samila profile."""
|
||||
from samila import *
|
||||
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(seed=200)
|
||||
g.plot()
|
||||
g.save_image("test.png")
|
|
@ -4,7 +4,7 @@ import os
|
|||
import sys
|
||||
import codecs
|
||||
Failed = 0
|
||||
SAMILA_VERSION = "0.8"
|
||||
SAMILA_VERSION = "0.9"
|
||||
|
||||
|
||||
SETUP_ITEMS = [
|
||||
|
@ -19,9 +19,12 @@ CHANGELOG_ITEMS = [
|
|||
"https://github.com/sepandhaghighi/samila/compare/v{0}...dev",
|
||||
"[{0}]:"]
|
||||
PARAMS_ITEMS = ['SAMILA_VERSION = "{0}"']
|
||||
|
||||
META_ITEMS = ['% set version = "{0}" %']
|
||||
|
||||
FILES = {
|
||||
"setup.py": SETUP_ITEMS, "README.md": README_ITEMS, "CHANGELOG.md": CHANGELOG_ITEMS, os.path.join(
|
||||
"samila", "params.py"): PARAMS_ITEMS}
|
||||
"samila", "params.py"): PARAMS_ITEMS, os.path.join("otherfiles", "meta.yaml"): META_ITEMS}
|
||||
|
||||
TEST_NUMBER = len(FILES.keys())
|
||||
|
||||
|
|
|
@ -8,12 +8,15 @@ import re
|
|||
import json
|
||||
import random
|
||||
import matplotlib
|
||||
from matplotlib import cm
|
||||
from matplotlib.colors import ListedColormap
|
||||
from .params import DEFAULT_START, DEFAULT_STOP, DEFAULT_STEP, DEFAULT_COLOR, DEFAULT_IMAGE_SIZE, DEFAULT_DEPTH
|
||||
from .params import DEFAULT_CMAP, DEFAULT_CMAP_RANGE
|
||||
from .params import DEFAULT_BACKGROUND_COLOR, DEFAULT_SPOT_SIZE, DEFAULT_PROJECTION, DEFAULT_ALPHA, DEFAULT_LINEWIDTH
|
||||
from .params import Projection, VALID_COLORS, HEX_COLOR_PATTERN, NFT_STORAGE_API, NFT_STORAGE_LINK, OVERVIEW
|
||||
from .params import DATA_TYPE_ERROR, CONFIG_TYPE_ERROR, PLOT_DATA_ERROR, CONFIG_NO_STR_FUNCTION_ERROR
|
||||
from .params import DATA_TYPE_ERROR, DATA_FORMAT_ERROR, CONFIG_TYPE_ERROR, CONFIG_FORMAT_ERROR, PLOT_DATA_ERROR, CONFIG_NO_STR_FUNCTION_ERROR
|
||||
from .params import NO_FIG_ERROR_MESSAGE, FIG_SAVE_SUCCESS_MESSAGE, NFT_STORAGE_SUCCESS_MESSAGE, SAVE_NO_DATA_ERROR
|
||||
from .params import INVALID_COLOR_TYPE_ERROR
|
||||
from .params import INVALID_COLOR_TYPE_ERROR, COLOR_SIZE_ERROR
|
||||
from .params import BOTH_COLOR_COMPLEMENT_WARNING, COLOR_NOT_FOUND_WARNING
|
||||
from .params import DATA_SAVE_SUCCESS_MESSAGE, SEED_LOWER_BOUND, SEED_UPPER_BOUND
|
||||
from .params import ELEMENTS_LIST, ARGUMENTS_LIST, OPERATORS_LIST, RANDOM_COEF_LIST
|
||||
|
@ -27,17 +30,22 @@ def random_equation_gen():
|
|||
|
||||
:return: equation as str
|
||||
"""
|
||||
num_elements = random.randint(2, len(ELEMENTS_LIST) + 3)
|
||||
num_elements = random.randint(1, len(ELEMENTS_LIST))
|
||||
result = ""
|
||||
index = 1
|
||||
random_coef = random.choice(RANDOM_COEF_LIST)
|
||||
while(index <= num_elements):
|
||||
argument = random.choice(ARGUMENTS_LIST)
|
||||
if random.randint(0, 1) == 1:
|
||||
argument = random.choice(ELEMENTS_LIST).format(
|
||||
random_coef, argument)
|
||||
result = result + \
|
||||
random.choice(ELEMENTS_LIST).format(random_coef, argument)
|
||||
if index < num_elements:
|
||||
result = result + random.choice(OPERATORS_LIST)
|
||||
index = index + 1
|
||||
if random.randint(0, 1) == 1:
|
||||
result = random.choice(ELEMENTS_LIST).format(random_coef, result)
|
||||
return result
|
||||
|
||||
|
||||
|
@ -106,7 +114,7 @@ def is_valid_color(color):
|
|||
:type color: any format
|
||||
:return: result as bool
|
||||
"""
|
||||
if color == None:
|
||||
if color is None:
|
||||
return True
|
||||
try:
|
||||
_ = matplotlib.colors.to_hex(color)
|
||||
|
@ -154,6 +162,29 @@ def filter_color(color, bgcolor):
|
|||
return color, bgcolor
|
||||
|
||||
|
||||
def filter_cmap(cmap):
|
||||
"""
|
||||
Filter given cmap.
|
||||
|
||||
:param cmap: color map
|
||||
:type cmap: matplotlib.colors.Colormap or list of colors
|
||||
:return: filtered version of cmap
|
||||
"""
|
||||
if isinstance(cmap, str):
|
||||
cmap = cm.get_cmap(cmap, 256)
|
||||
if type(cmap) == matplotlib.colors.Colormap:
|
||||
cmap = cm.get_cmap(cmap.__getattribute__("name"))
|
||||
if isinstance(cmap, matplotlib.colors.ListedColormap):
|
||||
return cmap
|
||||
if isinstance(cmap, (matplotlib.colors.LinearSegmentedColormap)):
|
||||
cmap = cmap(range(DEFAULT_CMAP_RANGE))
|
||||
return ListedColormap(cmap)
|
||||
if isinstance(cmap, list):
|
||||
cmap = list(map(select_color, cmap))
|
||||
return ListedColormap(cmap)
|
||||
return None
|
||||
|
||||
|
||||
def select_color(color):
|
||||
"""
|
||||
Select color and return it.
|
||||
|
@ -257,6 +288,7 @@ def plot_params_filter(
|
|||
g,
|
||||
color=None,
|
||||
bgcolor=None,
|
||||
cmap=None,
|
||||
spot_size=None,
|
||||
size=None,
|
||||
projection=None,
|
||||
|
@ -271,6 +303,8 @@ def plot_params_filter(
|
|||
:type color: str
|
||||
:param bgcolor: background color
|
||||
:type bgcolor: str
|
||||
:param cmap: color map
|
||||
:type cmap: matplotlib.colors.Colormap or list of colors
|
||||
:param spot_size: point spot size
|
||||
:type spot_size: float
|
||||
:param size: figure size
|
||||
|
@ -287,7 +321,13 @@ def plot_params_filter(
|
|||
raise samilaPlotError(PLOT_DATA_ERROR.format(1))
|
||||
if g.data2 is None:
|
||||
raise samilaPlotError(PLOT_DATA_ERROR.format(2))
|
||||
color, bgcolor = filter_color(color, bgcolor)
|
||||
if isinstance(color, list):
|
||||
if len(color) != len(g.data1):
|
||||
raise samilaPlotError(COLOR_SIZE_ERROR)
|
||||
bgcolor = select_color(bgcolor)
|
||||
else:
|
||||
color, bgcolor = filter_color(color, bgcolor)
|
||||
cmap = filter_cmap(cmap)
|
||||
projection = filter_projection(projection)
|
||||
alpha = filter_float(alpha)
|
||||
linewidth = filter_float(linewidth)
|
||||
|
@ -297,6 +337,8 @@ def plot_params_filter(
|
|||
color = g.color
|
||||
if bgcolor is None:
|
||||
bgcolor = g.bgcolor
|
||||
if cmap is None:
|
||||
cmap = g.cmap
|
||||
if spot_size is None:
|
||||
spot_size = g.spot_size
|
||||
if size is None:
|
||||
|
@ -307,7 +349,8 @@ def plot_params_filter(
|
|||
alpha = g.alpha
|
||||
if linewidth is None:
|
||||
linewidth = g.linewidth
|
||||
g.color, g.bgcolor, g.spot_size, g.size, g.projection, g.alpha, g.linewidth = color, bgcolor, spot_size, size, projection, alpha, linewidth
|
||||
g.color, g.bgcolor, g.cmap, g.spot_size, g.size, g.projection, g.alpha, g.linewidth = \
|
||||
color, bgcolor, cmap, spot_size, size, projection, alpha, linewidth
|
||||
|
||||
|
||||
def generate_params_filter(
|
||||
|
@ -405,6 +448,7 @@ def _GI_initializer(g, function1, function2):
|
|||
g.data2 = None
|
||||
g.color = DEFAULT_COLOR
|
||||
g.bgcolor = DEFAULT_BACKGROUND_COLOR
|
||||
g.cmap = DEFAULT_CMAP
|
||||
g.spot_size = DEFAULT_SPOT_SIZE
|
||||
g.size = DEFAULT_IMAGE_SIZE
|
||||
g.projection = DEFAULT_PROJECTION
|
||||
|
@ -463,6 +507,7 @@ def save_data_file(g, file_adr):
|
|||
data['plot'] = {
|
||||
"color": g.color,
|
||||
"bgcolor": g.bgcolor,
|
||||
"cmap": _serialize_cmap(g.cmap),
|
||||
"spot_size": g.spot_size,
|
||||
"projection": g.projection,
|
||||
"alpha": g.alpha,
|
||||
|
@ -506,6 +551,7 @@ def save_config_file(g, file_adr):
|
|||
data['plot'] = {
|
||||
"color": g.color,
|
||||
"bgcolor": g.bgcolor,
|
||||
"cmap": _serialize_cmap(g.cmap),
|
||||
"spot_size": g.spot_size,
|
||||
"projection": g.projection,
|
||||
"alpha": g.alpha,
|
||||
|
@ -592,6 +638,7 @@ def samila_help():
|
|||
:return: None
|
||||
"""
|
||||
print(OVERVIEW)
|
||||
print("Website : https://www.samila.site")
|
||||
print("Repo : https://github.com/sepandhaghighi/samila")
|
||||
|
||||
|
||||
|
@ -613,6 +660,44 @@ def is_same_data(data1, data2, precision=10**-5):
|
|||
return all(is_same)
|
||||
|
||||
|
||||
def _serialize_color(color):
|
||||
"""
|
||||
Serialize the given color to a json serializable object.
|
||||
|
||||
:param color: given color
|
||||
:type color: str or nd.array
|
||||
:return: the serializable version of the color
|
||||
"""
|
||||
if isinstance(color, str):
|
||||
return color
|
||||
return list(color)
|
||||
|
||||
|
||||
def _serialize_cmap(cmap):
|
||||
"""
|
||||
Serialize the cmap for saving.
|
||||
|
||||
:param cmap: color map
|
||||
:type cmap: matplotlib.colors.Colormap
|
||||
:return: list of colors
|
||||
"""
|
||||
return list(map(_serialize_color, cmap.colors))
|
||||
|
||||
|
||||
def _load_cmap(config):
|
||||
"""
|
||||
Load the cmap from config.
|
||||
|
||||
:param config: plot part configuration
|
||||
:type config: dict or json
|
||||
:return: ListedColormap from cmap
|
||||
"""
|
||||
if "cmap" not in config:
|
||||
return DEFAULT_CMAP
|
||||
cmap = config["cmap"]
|
||||
return ListedColormap(cmap)
|
||||
|
||||
|
||||
def load_data(g, data):
|
||||
"""
|
||||
Load data file.
|
||||
|
@ -627,12 +712,15 @@ def load_data(g, data):
|
|||
data = json.load(data)
|
||||
g.data1 = data.get('data1')
|
||||
g.data2 = data.get('data2')
|
||||
if g.data1 is None or g.data2 is None:
|
||||
raise samilaDataError(DATA_FORMAT_ERROR)
|
||||
if 'matplotlib_version' in data:
|
||||
g.matplotlib_version = data['matplotlib_version']
|
||||
plot_config = data.get("plot")
|
||||
if plot_config is not None:
|
||||
g.color = plot_config.get("color", DEFAULT_COLOR)
|
||||
g.bgcolor = plot_config.get("bgcolor", DEFAULT_BACKGROUND_COLOR)
|
||||
g.cmap = _load_cmap(plot_config)
|
||||
g.spot_size = plot_config.get("spot_size", DEFAULT_SPOT_SIZE)
|
||||
g.projection = plot_config.get("projection", DEFAULT_PROJECTION)
|
||||
g.alpha = plot_config.get("alpha", DEFAULT_ALPHA)
|
||||
|
@ -656,6 +744,8 @@ def load_config(g, config):
|
|||
data = json.load(config)
|
||||
g.function1_str = data.get("f1")
|
||||
g.function2_str = data.get("f2")
|
||||
if g.function1_str is None or g.function2_str is None:
|
||||
raise samilaConfigError(CONFIG_FORMAT_ERROR)
|
||||
if 'matplotlib_version' in data:
|
||||
g.matplotlib_version = data['matplotlib_version']
|
||||
generate_config = data.get("generate")
|
||||
|
@ -668,6 +758,7 @@ def load_config(g, config):
|
|||
if plot_config is not None:
|
||||
g.color = plot_config.get("color", DEFAULT_COLOR)
|
||||
g.bgcolor = plot_config.get("bgcolor", DEFAULT_BACKGROUND_COLOR)
|
||||
g.cmap = _load_cmap(plot_config)
|
||||
g.spot_size = plot_config.get("spot_size", DEFAULT_SPOT_SIZE)
|
||||
g.projection = plot_config.get("projection", DEFAULT_PROJECTION)
|
||||
g.alpha = plot_config.get("alpha", DEFAULT_ALPHA)
|
||||
|
|
|
@ -79,8 +79,7 @@ class GenerativeImage:
|
|||
self.data1 = []
|
||||
self.data2 = []
|
||||
range1 = list(float_range(self.start, self.stop, self.step))
|
||||
range2 = list(float_range(self.start, self.stop, self.step))
|
||||
range_prod = list(itertools.product(range1, range2))
|
||||
range_prod = list(itertools.product(range1, range1))
|
||||
calc_exception = False
|
||||
for point in range_prod:
|
||||
if not fill_data(self, point):
|
||||
|
@ -92,6 +91,7 @@ class GenerativeImage:
|
|||
self,
|
||||
color=None,
|
||||
bgcolor=None,
|
||||
cmap=None,
|
||||
spot_size=None,
|
||||
size=None,
|
||||
projection=None,
|
||||
|
@ -104,6 +104,8 @@ class GenerativeImage:
|
|||
:type color: str
|
||||
:param bgcolor: background color
|
||||
:type bgcolor: str
|
||||
:param cmap: color map
|
||||
:type cmap: matplotlib.colors.Colormap or list of colors
|
||||
:param spot_size: point spot size
|
||||
:type spot_size: float
|
||||
:param size: figure size
|
||||
|
@ -120,6 +122,7 @@ class GenerativeImage:
|
|||
self,
|
||||
color,
|
||||
bgcolor,
|
||||
cmap,
|
||||
spot_size,
|
||||
size,
|
||||
projection,
|
||||
|
@ -134,6 +137,7 @@ class GenerativeImage:
|
|||
self.data1,
|
||||
alpha=self.alpha,
|
||||
c=self.color,
|
||||
cmap=self.cmap,
|
||||
s=self.spot_size,
|
||||
lw=self.linewidth)
|
||||
ax.set_axis_off()
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
import math
|
||||
from enum import Enum
|
||||
from matplotlib import colors as mcolors
|
||||
from matplotlib import cm
|
||||
|
||||
SAMILA_VERSION = "0.8" # pragma: no cover
|
||||
SAMILA_VERSION = "0.9" # pragma: no cover
|
||||
|
||||
OVERVIEW = '''
|
||||
Samila is a generative art generator written in Python, Samila let's you
|
||||
|
@ -18,6 +19,8 @@ DEFAULT_STOP = math.pi
|
|||
DEFAULT_STEP = 0.01
|
||||
DEFAULT_COLOR = "black"
|
||||
DEFAULT_BACKGROUND_COLOR = "white"
|
||||
DEFAULT_CMAP = cm.get_cmap("viridis", 256)
|
||||
DEFAULT_CMAP_RANGE = 256
|
||||
DEFAULT_ALPHA = 0.1
|
||||
DEFAULT_LINEWIDTH = 1.5
|
||||
DEFAULT_IMAGE_SIZE = (10, 10)
|
||||
|
@ -35,9 +38,12 @@ FIG_SAVE_SUCCESS_MESSAGE = "Everything seems good."
|
|||
DATA_SAVE_SUCCESS_MESSAGE = "Everything seems good."
|
||||
NO_FIG_ERROR_MESSAGE = "No figure was found. First run `generate` and `plot` methods."
|
||||
DATA_TYPE_ERROR = "Provided data file is not supported. It should be either file or io.IOBase."
|
||||
DATA_FORMAT_ERROR = "Provided data file is not supported. It should include data1 and data2."
|
||||
CONFIG_TYPE_ERROR = "Provided config file is not supported. It should be either file or io.IOBase."
|
||||
CONFIG_FORMAT_ERROR = "Provided config file is not supported. It should include f1 and f2."
|
||||
CONFIG_NO_STR_FUNCTION_ERROR = "Config file can't be saved. At least one of the function1_str or function2_str is None."
|
||||
PLOT_DATA_ERROR = "Plotting process can't be Done because data{0} is empty. Use generate method first."
|
||||
COLOR_SIZE_ERROR = "Color list size is not equal to the data size."
|
||||
SAVE_NO_DATA_ERROR = "Data file can't be saved. At least one of the data1 or data2 is None."
|
||||
INVALID_COLOR_TYPE_ERROR = "Given color/bgcolor type is not supported."
|
||||
MATPLOTLIB_VERSION_WARNING = "Source matplotlib version({0}) is different from yours, plots may be different."
|
||||
|
@ -98,6 +104,8 @@ ARGUMENTS_LIST = [
|
|||
"y**2",
|
||||
"(x**2)*y",
|
||||
"(y**2)*x",
|
||||
"(y**2)+(x**2)",
|
||||
"(y**2)-(x**2)",
|
||||
"(x**2)*(y**3)",
|
||||
"(x**3)*(y**2)",
|
||||
"x*(y**3)",
|
||||
|
|
8
setup.py
8
setup.py
|
@ -32,14 +32,14 @@ def read_description():
|
|||
setup(
|
||||
name='samila',
|
||||
packages=['samila'],
|
||||
version='0.8',
|
||||
version='0.9',
|
||||
description='Generative ART',
|
||||
long_description=read_description(),
|
||||
long_description_content_type='text/markdown',
|
||||
author='Samila Development Team',
|
||||
author_email='info@4r7.ir',
|
||||
url='https://github.com/sepandhaghighi/samila',
|
||||
download_url='https://github.com/sepandhaghighi/samila/tarball/v0.8',
|
||||
author_email='info@samila.site',
|
||||
url='https://www.samila.site',
|
||||
download_url='https://github.com/sepandhaghighi/samila/tarball/v0.9',
|
||||
keywords="generative-art art nft file nft-storage",
|
||||
project_urls={
|
||||
'Source': 'https://github.com/sepandhaghighi/samila',
|
||||
|
|
|
@ -24,8 +24,9 @@ Traceback (most recent call last):
|
|||
...
|
||||
samila.errors.samilaPlotError: Plotting process can't be Done because data1 is empty. Use generate method first.
|
||||
>>> with open("data.json", 'w') as fp:
|
||||
... json.dump({'data1': [0]}, fp)
|
||||
... json.dump({'data1': [0], 'data2': [0]}, fp)
|
||||
>>> g = GenerativeImage(data=open('data.json', 'r'))
|
||||
>>> g.data2 = None
|
||||
>>> g.save_data()
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
|
@ -39,6 +40,10 @@ samila.errors.samilaPlotError: Plotting process can't be Done because data2 is e
|
|||
Traceback (most recent call last):
|
||||
...
|
||||
samila.errors.samilaPlotError: Given color/bgcolor type is not supported.
|
||||
>>> g.plot(color=[0])
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
samila.errors.samilaPlotError: Color list size is not the equal to the data size.
|
||||
>>> g = GenerativeImage(lambda x,y: x, lambda x,y: y)
|
||||
>>> result = g.save_config()
|
||||
Traceback (most recent call last):
|
||||
|
@ -57,5 +62,30 @@ samila.errors.samilaPlotError: Given color/bgcolor type is not supported.
|
|||
Traceback (most recent call last):
|
||||
...
|
||||
samila.errors.samilaPlotError: Given color/bgcolor type is not supported.
|
||||
>>> with open("data.json", 'w') as fp:
|
||||
... json.dump({'data1': [0]}, fp)
|
||||
>>> g = GenerativeImage(data=open('data.json', 'r'))
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
samila.errors.samilaDataError: Provided data file is not supported. It should include data1 and data2.
|
||||
>>> with open("data.json", 'w') as fp:
|
||||
... json.dump({'data2': [0]}, fp)
|
||||
>>> g = GenerativeImage(data=open('data.json', 'r'))
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
samila.errors.samilaDataError: Provided data file is not supported. It should include data1 and data2.
|
||||
>>> with open("config.json", 'w') as fp:
|
||||
... json.dump({'f1': "x"}, fp)
|
||||
>>> g = GenerativeImage(config=open('config.json', 'r'))
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
samila.errors.samilaConfigError: Provided config file is not supported. It should include f1 and f2.
|
||||
>>> with open("config.json", 'w') as fp:
|
||||
... json.dump({'f2': "x"}, fp)
|
||||
>>> g = GenerativeImage(config=open('config.json', 'r'))
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
samila.errors.samilaConfigError: Provided config file is not supported. It should include f1 and f2.
|
||||
>>> os.remove('data.json')
|
||||
>>> os.remove('config.json')
|
||||
"""
|
||||
|
|
|
@ -88,5 +88,6 @@ create arts 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.
|
||||
<BLANKLINE>
|
||||
Website : https://www.samila.site
|
||||
Repo : https://github.com/sepandhaghighi/samila
|
||||
"""
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
>>> import pickle
|
||||
>>> import socket
|
||||
>>> import json
|
||||
>>> from matplotlib.colors import Colormap, ListedColormap
|
||||
>>> def guard(*args, **kwargs):
|
||||
... raise Exception("No internet connection!")
|
||||
>>> from samila import GenerativeImage, Projection
|
||||
|
@ -196,16 +197,6 @@ True
|
|||
>>> g.spot_size == g_.spot_size
|
||||
True
|
||||
>>> with open("config.json", 'w') as fp:
|
||||
... json.dump({'f1': 'x'}, fp)
|
||||
>>> g = GenerativeImage(config=open("config.json", 'r'))
|
||||
>>> g.function1_str
|
||||
'x'
|
||||
>>> with open("config.json", 'w') as fp:
|
||||
... json.dump({'f2': 'x'}, fp)
|
||||
>>> g = GenerativeImage(config=open("config.json", 'r'))
|
||||
>>> g.function2_str
|
||||
'x'
|
||||
>>> with open("config.json", 'w') as fp:
|
||||
... json.dump({'f1': 'y', 'f2': 'x'}, fp)
|
||||
>>> g = GenerativeImage(config=open("config.json", 'r'))
|
||||
>>> g.function1_str
|
||||
|
@ -222,6 +213,46 @@ False
|
|||
[0]
|
||||
>>> g.data2
|
||||
[1]
|
||||
>>> with open("data.json", 'w') as fp:
|
||||
... json.dump({'data1': [0], 'data2': [1], 'plot':{}}, fp)
|
||||
>>> g = GenerativeImage(data=open("data.json", 'r'))
|
||||
>>> with open("config.json", 'w') as fp:
|
||||
... json.dump({'f1': "x", 'f2': "y", 'plot':{}}, fp)
|
||||
>>> g = GenerativeImage(config=open("config.json", 'r'))
|
||||
>>> g = GenerativeImage()
|
||||
>>> g.generate()
|
||||
>>> cm = Colormap(name="Purples")
|
||||
>>> g.plot(cmap=cm)
|
||||
>>> result = g.save_config("config.json")
|
||||
>>> result["status"]
|
||||
True
|
||||
>>> g_ = GenerativeImage(config=open("config.json", 'r'))
|
||||
>>> (g_.cmap.colors == g.cmap.colors).all()
|
||||
True
|
||||
>>> cm = ["black", [0.6, 0.2, 0.2, 1], [0.5, 0.2, 0.2, 1], [0.4, 0.2, 0.2, 1], "yellow", [0.2, 0.2, 0.2, 1],]
|
||||
>>> g.plot(cmap=cm)
|
||||
>>> result = g.save_config("config.json")
|
||||
>>> result["status"]
|
||||
True
|
||||
>>> g_ = GenerativeImage(config=open("config.json", 'r'))
|
||||
>>> g_.cmap.colors == g.cmap.colors
|
||||
True
|
||||
>>> g.plot(cmap="Purples")
|
||||
>>> cm = Colormap(name="viridis")
|
||||
>>> g.plot(cmap=cm)
|
||||
>>> cmap = [[0.7, 0.2, 0.2, 1], [0.6, 0.2, 0.2, 1], [0.3, 0.2, 0.2, 1], [0.2, 0.2, 0.2, 1]]
|
||||
>>> g.plot(cmap=ListedColormap(cmap))
|
||||
>>> g = GenerativeImage()
|
||||
>>> g.generate()
|
||||
>>> g.plot(cmap=cmap, color=g.data1)
|
||||
>>> result = g.save_data("data.json")
|
||||
>>> result["status"]
|
||||
True
|
||||
>>> g_ = GenerativeImage(data=open("data.json", "r"))
|
||||
>>> g_.plot()
|
||||
>>> g_.cmap.colors == g.cmap.colors
|
||||
True
|
||||
>>> g.plot(color=g.data1)
|
||||
>>> g_ = GenerativeImage()
|
||||
>>> del(g)
|
||||
>>> del g_.data1
|
||||
|
|
Ładowanie…
Reference in New Issue