shades package
Submodules
shades.canvas module
canvas
contains functions/classes relating to Shades’ canvas object
- shades.canvas.Canvas(height: int = 700, width: int = 700, color: List[int] = (240, 240, 240), color_mode: str = 'RGB') <module 'PIL.Image' from '/home/docs/checkouts/readthedocs.org/user_builds/shades/envs/latest/lib/python3.7/site-packages/PIL/Image.py'>[source]
Returns an blank image to draw on. A function due to PIL library restrictions Although in effect used as class so follows naming conventions for color_mode ‘RGB’ and ‘HSB’ supported (‘RGBA’ and ‘HSBA’ accepted, but may produce unexpected results)
- shades.canvas.grid_shuffle(canvas: <module 'PIL.Image' from '/home/docs/checkouts/readthedocs.org/user_builds/shades/envs/latest/lib/python3.7/site-packages/PIL/Image.py'>, x_grids: int, y_grids: int)[source]
Returns and image, with grid sections shuffled
- shades.canvas.pixel_sort(canvas: <module 'PIL.Image' from '/home/docs/checkouts/readthedocs.org/user_builds/shades/envs/latest/lib/python3.7/site-packages/PIL/Image.py'>, key: typing.Callable = <built-in function sum>, interval: typing.Optional[int] = None) <module 'PIL.Image' from '/home/docs/checkouts/readthedocs.org/user_builds/shades/envs/latest/lib/python3.7/site-packages/PIL/Image.py'>[source]
Returns a color sorted version of canvas. Accepts a custom function for sorting color tuples in key
shades.noise_fields module
noise_fields
Functions and classes relating to Shades’ NoiseField
- class shades.noise_fields.NoiseField(scale: float = 0.002, seed: Optional[int] = None)[source]
Bases:
objectAn object to calculate and store perlin noise data.
Initialisation takes float (recommend very low number < 0.1) and random seed
- fade(t_array: Union[Sequence[Sequence[Sequence[Sequence[Sequence[Any]]]]], numpy.typing._array_like._SupportsArray[numpy.dtype], Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]], Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]], Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]], Sequence[Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]]], bool, int, float, complex, str, bytes, Sequence[Union[bool, int, float, complex, str, bytes]], Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]], Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]], Sequence[Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]]]]) Union[Sequence[Sequence[Sequence[Sequence[Sequence[Any]]]]], numpy.typing._array_like._SupportsArray[numpy.dtype], Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]], Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]], Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]], Sequence[Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]]], bool, int, float, complex, str, bytes, Sequence[Union[bool, int, float, complex, str, bytes]], Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]], Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]], Sequence[Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]]]][source]
6t^5 - 15t^4 + 10t^3
- gradient(h_array: Union[Sequence[Sequence[Sequence[Sequence[Sequence[Any]]]]], numpy.typing._array_like._SupportsArray[numpy.dtype], Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]], Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]], Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]], Sequence[Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]]], bool, int, float, complex, str, bytes, Sequence[Union[bool, int, float, complex, str, bytes]], Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]], Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]], Sequence[Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]]]], x_array: Union[Sequence[Sequence[Sequence[Sequence[Sequence[Any]]]]], numpy.typing._array_like._SupportsArray[numpy.dtype], Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]], Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]], Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]], Sequence[Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]]], bool, int, float, complex, str, bytes, Sequence[Union[bool, int, float, complex, str, bytes]], Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]], Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]], Sequence[Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]]]], y_array: Union[Sequence[Sequence[Sequence[Sequence[Sequence[Any]]]]], numpy.typing._array_like._SupportsArray[numpy.dtype], Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]], Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]], Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]], Sequence[Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]]], bool, int, float, complex, str, bytes, Sequence[Union[bool, int, float, complex, str, bytes]], Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]], Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]], Sequence[Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]]]]) Union[Sequence[Sequence[Sequence[Sequence[Sequence[Any]]]]], numpy.typing._array_like._SupportsArray[numpy.dtype], Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]], Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]], Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]], Sequence[Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]]], bool, int, float, complex, str, bytes, Sequence[Union[bool, int, float, complex, str, bytes]], Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]], Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]], Sequence[Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]]]][source]
grad converts h to the right gradient vector and return the dot product with (x,y)
- lerp(a_array: Union[Sequence[Sequence[Sequence[Sequence[Sequence[Any]]]]], numpy.typing._array_like._SupportsArray[numpy.dtype], Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]], Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]], Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]], Sequence[Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]]], bool, int, float, complex, str, bytes, Sequence[Union[bool, int, float, complex, str, bytes]], Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]], Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]], Sequence[Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]]]], b_array: Union[Sequence[Sequence[Sequence[Sequence[Sequence[Any]]]]], numpy.typing._array_like._SupportsArray[numpy.dtype], Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]], Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]], Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]], Sequence[Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]]], bool, int, float, complex, str, bytes, Sequence[Union[bool, int, float, complex, str, bytes]], Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]], Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]], Sequence[Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]]]], x_array: Union[Sequence[Sequence[Sequence[Sequence[Sequence[Any]]]]], numpy.typing._array_like._SupportsArray[numpy.dtype], Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]], Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]], Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]], Sequence[Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]]], bool, int, float, complex, str, bytes, Sequence[Union[bool, int, float, complex, str, bytes]], Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]], Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]], Sequence[Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]]]]) Union[Sequence[Sequence[Sequence[Sequence[Sequence[Any]]]]], numpy.typing._array_like._SupportsArray[numpy.dtype], Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]], Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]], Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]], Sequence[Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]]], bool, int, float, complex, str, bytes, Sequence[Union[bool, int, float, complex, str, bytes]], Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]], Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]], Sequence[Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]]]][source]
linear interpolation
- noise(xy_coords: Tuple[int, int])[source]
Returns noise of xy coords Also manages noise_field (will dynamically recalcuate as needed)
- perlin_field(x_lin: List[float], y_lin: List[float]) Union[Sequence[Sequence[Sequence[Sequence[Sequence[Any]]]]], numpy.typing._array_like._SupportsArray[numpy.dtype], Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]], Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]], Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]], Sequence[Sequence[Sequence[Sequence[numpy.typing._array_like._SupportsArray[numpy.dtype]]]]], bool, int, float, complex, str, bytes, Sequence[Union[bool, int, float, complex, str, bytes]], Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]], Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]], Sequence[Sequence[Sequence[Sequence[Union[bool, int, float, complex, str, bytes]]]]]][source]
generate field from x and y linear points
credit to tgirod for stack overflow on numpy perlin noise (most of this code from answer) https://stackoverflow.com/questions/42147776/producing-2d-perlin-noise-with-numpy
- shades.noise_fields.noise_fields(scale: Union[List[float], float] = 0.002, seed: Optional[Union[List[int], int]] = None, channels: int = 3) List[shades.noise_fields.NoiseField][source]
Create multiple NoiseField objects in one go. This is a quality of life function, rather than adding new behaviour shades.noise_fields(scale=0.2, channels=3) rather than [shades.NoiseField(scale=0.2) for i in range(3)]
shades.shades module
shades
contains classes and functions relating to Shades’ shade object
- class shades.shades.BlockColor(color: typing.Tuple[int, int, int] = (0, 0, 0), warp_noise: typing.Tuple[shades.noise_fields.NoiseField] = [<shades.noise_fields.NoiseField object>, <shades.noise_fields.NoiseField object>], warp_size: float = 0)[source]
Bases:
shades.shades.ShadeType of shade that will always fill with defined color without variation.
- class shades.shades.DomainWarpGradient(color: typing.Tuple[int, int, int] = (0, 0, 0), warp_noise: typing.Tuple[shades.noise_fields.NoiseField, shades.noise_fields.NoiseField] = [<shades.noise_fields.NoiseField object>, <shades.noise_fields.NoiseField object>], warp_size: int = 0, color_variance: int = 70, color_fields: typing.Tuple[shades.noise_fields.NoiseField, shades.noise_fields.NoiseField, shades.noise_fields.NoiseField] = [<shades.noise_fields.NoiseField object>, <shades.noise_fields.NoiseField object>, <shades.noise_fields.NoiseField object>], depth: int = 2, feedback: float = 0.7)[source]
Bases:
shades.shades.ShadeType of shade that will produce varying gradient based on recursive noise fields.
Unique Parameters: color_variance: How much noise is allowed to affect the color from the central shade color_fields: A noise field for each channel (r,g,b) depth: Number of recursions within noise to make feedback: Affect of recursive calls, recomended around 0-2
- class shades.shades.HorizontalGradient(color_points: typing.List[typing.Tuple[int, typing.Tuple[int, int, int]]], warp_noise: typing.Tuple[shades.noise_fields.NoiseField, shades.noise_fields.NoiseField] = [<shades.noise_fields.NoiseField object>, <shades.noise_fields.NoiseField object>], warp_size: int = 0)[source]
Bases:
shades.shades.LinearGradientType of shade that will determine color based on transition between various ‘color_points’
Unique Parameters: color_points: Groups of colours and coordinate at which they should appear
Here’s an example of color_points in this, anything before 50 (on x axis) will be black, anything after 100 will be white between 50 and 100 will be grey, with tone based on proximity to 50 or 100
- class shades.shades.LinearGradient(color_points: typing.List[typing.Tuple[int, typing.Tuple[int, int, int]]], axis: int = 0, warp_noise: typing.Tuple[shades.noise_fields.NoiseField, shades.noise_fields.NoiseField] = [<shades.noise_fields.NoiseField object>, <shades.noise_fields.NoiseField object>], warp_size: int = 0)[source]
Bases:
shades.shades.ShadeType of shade that will determine color based on transition between various ‘color_points’
Unique Parameters: color_points: Groups of colours and coordinate at which they should appear axis: 0 for horizontal gradient, 1 for vertical
Here’s an example of color_points in this, anything before 50 (on whichever axis specified) will be black, anything after 100 will be white between 50 and 100 will be grey, with tone based on proximity to 50 or 100 [((0, 0, 0), 50), ((250, 250, 250), 100)]
- class shades.shades.NoiseGradient(color: typing.Tuple[int, int, int] = (0, 0, 0), warp_noise: typing.Tuple[shades.noise_fields.NoiseField, shades.noise_fields.NoiseField, shades.noise_fields.NoiseField] = [<shades.noise_fields.NoiseField object>, <shades.noise_fields.NoiseField object>, <shades.noise_fields.NoiseField object>], warp_size: int = 0, color_variance: int = 70, color_fields: typing.Tuple[shades.noise_fields.NoiseField, shades.noise_fields.NoiseField, shades.noise_fields.NoiseField] = [<shades.noise_fields.NoiseField object>, <shades.noise_fields.NoiseField object>, <shades.noise_fields.NoiseField object>])[source]
Bases:
shades.shades.ShadeType of shade that will produce varying gradient based on noise fields.
Unique Parameters: color_variance: How much noise is allowed to affect the color from the central shade color_fields: A noise field for each channel (r,g,b)
- class shades.shades.Shade(color: typing.Tuple[int, int, int] = (0, 0, 0), warp_noise: typing.Tuple[shades.noise_fields.NoiseField] = [<shades.noise_fields.NoiseField object>, <shades.noise_fields.NoiseField object>], warp_size: float = 0)[source]
Bases:
abc.ABCAn Abstract base clase Shade. Methods are used to mark shapes onto images according to various color rules.
Initialisation parameters of warp_noise takes two noise_fields affecting how much a point is moved across x and y axis.
warp_size determines the amount that a warp_noise result of 1 (maximum perlin value) translates as
- adjust_point(xy_coords: Tuple[int, int]) Tuple[int, int][source]
If warp is applied in shade, appropriately adjusts location of point.
- circle(canvas: <module 'PIL.Image' from '/home/docs/checkouts/readthedocs.org/user_builds/shades/envs/latest/lib/python3.7/site-packages/PIL/Image.py'>, center: typing.Tuple[int, int], radius: int) None[source]
Draws a circle on the image.
- circle_outline(canvas: <module 'PIL.Image' from '/home/docs/checkouts/readthedocs.org/user_builds/shades/envs/latest/lib/python3.7/site-packages/PIL/Image.py'>, center: typing.Tuple[int, int], radius: int, weight: int = 2) None[source]
Draws a circle outline on the image.
- circle_slice(canvas: <module 'PIL.Image' from '/home/docs/checkouts/readthedocs.org/user_builds/shades/envs/latest/lib/python3.7/site-packages/PIL/Image.py'>, center: typing.Tuple[int, int], radius: int, start_angle: int, degrees_of_slice: int) None[source]
Draws a partial circle based on degrees. (will have the appearance of a ‘pizza slice’ or ‘pacman’ depending on degrees).
- abstract determine_shade(xy_coords: Tuple[int, int]) Tuple[int, int, int][source]
Determines the shade/color for given xy coordinate.
- fill(canvas: <module 'PIL.Image' from '/home/docs/checkouts/readthedocs.org/user_builds/shades/envs/latest/lib/python3.7/site-packages/PIL/Image.py'>) None[source]
Fills the entire image with color.
- get_circle_edge(center: Tuple[int, int], radius: int) List[Tuple[int, int]][source]
Returns the edge coordinates of a circle
- get_shape_edge(list_of_points: List[Tuple[int, int]]) List[Tuple][source]
Returns list of coordinates making up the edge of a shape
- in_bounds(canvas: <module 'PIL.Image' from '/home/docs/checkouts/readthedocs.org/user_builds/shades/envs/latest/lib/python3.7/site-packages/PIL/Image.py'>, xy_coords: typing.Tuple[int, int]) bool[source]
determined whether xy_coords are within the size of canvas image
- line(canvas: <module 'PIL.Image' from '/home/docs/checkouts/readthedocs.org/user_builds/shades/envs/latest/lib/python3.7/site-packages/PIL/Image.py'>, xy_coords_1: typing.Tuple[int, int], xy_coords_2: typing.Tuple[int, int], weight: int = 2) None[source]
Draws a weighted line on the image.
- pixels_between_two_points(xy_coord_1: Tuple, xy_coord_2: Tuple) List[source]
Returns a list of pixels that form a straight line between two points.
Parameters: xy_coord_1 (int iterable): Coordinates for first point. xy_coord_2 (int iterable): Coordinates for second point.
Returns: pixels (int iterable): List of pixels between the two points.
- pixels_inside_edge(edge_pixels: List) List[source]
Returns a list of pixels from inside a edge of points using ray casting algorithm https://en.wikipedia.org/wiki/Point_in_polygon vertex correction requires improvements, unusual or particularly angular shapes may cause difficulties
- point(canvas: <module 'PIL.Image' from '/home/docs/checkouts/readthedocs.org/user_builds/shades/envs/latest/lib/python3.7/site-packages/PIL/Image.py'>, xy_coords: typing.Tuple[int, int]) None[source]
Determines colour and draws a point on an image.
- rectangle(canvas: <module 'PIL.Image' from '/home/docs/checkouts/readthedocs.org/user_builds/shades/envs/latest/lib/python3.7/site-packages/PIL/Image.py'>, top_corner: typing.Tuple[int, int], width: int, height: int) None[source]
Draws a rectangle on the image.
- shape(canvas: <module 'PIL.Image' from '/home/docs/checkouts/readthedocs.org/user_builds/shades/envs/latest/lib/python3.7/site-packages/PIL/Image.py'>, points: typing.List[typing.Tuple[int, int]]) None[source]
Draws a shape on an image based on a list of points.
- shape_outline(canvas: <module 'PIL.Image' from '/home/docs/checkouts/readthedocs.org/user_builds/shades/envs/latest/lib/python3.7/site-packages/PIL/Image.py'>, points: typing.List[typing.Tuple[int, int]], weight: int = 2) None[source]
Draws a shape outline on an image based on a list of points.
- square(canvas: <module 'PIL.Image' from '/home/docs/checkouts/readthedocs.org/user_builds/shades/envs/latest/lib/python3.7/site-packages/PIL/Image.py'>, top_corner: typing.Tuple[int, int], size: int) None[source]
Draws a square on the canvas
- triangle(canvas, xy1: Tuple[int, int], xy2: Tuple[int, int], xy3: Tuple[int, int]) None[source]
Draws a triangle on the image. This is the same as calling Shade.shape with a list of three points.
- class shades.shades.SwirlOfShades(shades: typing.List[typing.Tuple[float, float, shades.shades.Shade]], warp_noise: typing.Tuple[shades.noise_fields.NoiseField, shades.noise_fields.NoiseField] = [<shades.noise_fields.NoiseField object>, <shades.noise_fields.NoiseField object>], warp_size: int = 0, color_variance: int = 70, swirl_field: shades.noise_fields.NoiseField = <shades.noise_fields.NoiseField object>, depth: int = 1, feedback: float = 0.7)[source]
Bases:
shades.shades.ShadeType of shade that will select from list of other shades based on recursive noise field.
Unique Parameters: swirl_field: a NoiseField from which the selection of the shade is made depth: Number of recursive calls to make from swirl_field.noise (defaults to 0) feedback: Affect of recursive calls from swirl_field.noise shades: this one is very specific, and determines when shades are used.
must be list of tuples of this form: (lower_bound, upper_bound, Shade)
because the ‘shades’ arguments potentially confusing, here’s an example. The below will color white when noise of 0 - 0.5 is returned, and black if noise of 0.5 - 1 [(0, 0.5, shades.BlockColor((255, 255, 255)), (0.5, 1, shades.BlockColor((0, 0, 0)))]
- class shades.shades.VerticalGradient(color_points: typing.List[typing.Tuple[int, typing.Tuple[int, int, int]]], warp_noise: typing.Tuple[shades.noise_fields.NoiseField, shades.noise_fields.NoiseField] = [<shades.noise_fields.NoiseField object>, <shades.noise_fields.NoiseField object>], warp_size: int = 0)[source]
Bases:
shades.shades.LinearGradientType of shade that will determine color based on transition between various ‘color_points’
Unique Parameters: color_points: Groups of colours and coordinate at which they should appear
Here’s an example of color_points in this, anything before 50 (on y axis) will be black, anything after 100 will be white between 50 and 100 will be grey, with tone based on proximity to 50 or 100
shades.utils module
utils
contains general purpose functions for use within or outside module
- shades.utils.color_clamp(color: Tuple[int, int, int]) Tuple[int, int, int][source]
Ensures a three part iterable is a properly formatted color (i.e. all numbers between 0 and 255)
- shades.utils.distance_between_points(xy1: Tuple[int, int], xy2: Tuple[int, int]) float[source]
Returns the euclidean distance between two points. https://en.wikipedia.org/wiki/Euclidean_distance
- shades.utils.randomly_shift_point(xy_coords: Tuple[int, int], movement_range: Union[Tuple[int, int], Tuple[Tuple[int, int], Tuple[int, int]]]) Tuple[int, int][source]
Randomly shifts a point within defined range
movement range of form: (min amount, max amount)
you can give two movement ranges for: [(min amount on x axis, max amount on x axis), (min amount on y axis, max amount on y axis)] or just one, if you want equal ranges
Module contents
Shades is a python module for generative 2d image creation.
Because of the relatively small level of classes and functions everything is imported into ‘shades’ name space to avoid long import commands for single items.