A version of the Flexoki color scheme that works with matplotlib and other python visualization packages
Project description
flexoki-py
Documentation: See the rest of this readme, as well as the docs
folder.
Source Code: Available on GitHub
Introduction
flexoki-py is a Python library that provides easy access to Flexoki, an "inky color scheme for prose and code".
The intent behind this package is to make the colors from Flexoki accessible to other Python packages centered around graphics, especially matplotlib.
Key features:
- Access to full library of Flexoki 2.0 colors
- Shortcuts to collections of colors (referred to as "Palettes")
- Robust filtering of colors based on hue and lightness
- Ability to register colors and palettes with matplotlib (as named colors and colormaps, respectively)
Quick Start
Install and Import
flexoki-py can be installed via pip:
pip install flexoki-py
This package requires python>=3.9.0
and matplotlib>=3.9.0
, mainly because those are the two versions that I used in its development. It might work with older version, but no guarantees.
Once installed, the following import structure is recommended:
from flexoki import Flexoki
This will import an instantiated variable (Flexoki
) from which the colors and palettes can be access (via Flexoki.colors
and Flexoki.palettes
, respectively).
You may also choose to import the main class directly, like so:
from flexoki import FlexokiSchema
...
your_variable = FlexokiSchema() # No arguments are taken
Doing so will allow you to create your own instances of the FlexokiSchema
class, which can be useful if you want to name it something different or have different settings for each.
Concepts and Framework
This package relies on three custom classes/objects to function:
-
Color
: corresponds to a single color with a specifiedhue
andlightness
; also has properties forname
,hex
(code), andrgb
. Currently, these are hardcoded based on the definitions from Flexoki 2.0, but could eventually be manipulated programmatically if I learn how to represent the OKLab colorspace in Python. -
Palette
: corresponds to a collection ofColor
objects, with a specifiedname
andcolors
(a list ofColor
objects). It also has properties forhex
(a list of hex codes) andrgb
(a list of RGB tuples). Usually, either a monochromatic array of colors (i.e. same hue at different lightness values) or a "monolightness" array (i.e. different hues at the same lightness value). -
FlexokiSchema
: This is the main object that will be used to access the colors and palettes. It has subclasses forcolors
(to accessColor
objects;FlexokiSchema.colors
) andpalettes
(to accessPalette
objects;FlexokiSchema.palettes
), as well as a variety of other functions for helping splice and filter the colors as needed.
As a note, this package has, in many ways, been over-engineered, mainly because I was using this as a learning opportunity. Thus, several methods are available for accomplishing the same task.
Accessing Colors
Individual colors are primarily accessed in one of two ways: via dictionary-retrieval, or via attribute calling.
Dictionary retrieval example
from flexoki import Flexoki
# Both of these work in the same way
Flexoki.colors["red-50"]
Flexoki["red-50"]
Attribute calling example
from flexoki import Flexoki
# This method only works on the colors subclass
Flexoki.colors.red_50
Note the difference between the names: dictionary retrieval uses dashes (-
), while the attribute calling must use underscores instead (_
).
This will return a Color
object, with its own attributes such as hex
and rgb
. Accessing these is possible like so:
from flexoki import Flexoki
Flexoki.colors.red_50.hex
Flexoki.colors.red_50.rgb
For more information on the Color
object, see the documentation in docs/colors.ipynb
Accessing Palettes
Palettes (groups of colors) can only be accessed as attributes of the palettes
subclass, like so:
from flexoki import Flexoki
Flexoki.palettes.reds # will return all the red hues, ordered from lightest to darkest
Flexoki.palettes.l150 # will return all the hues that have a lightness value of 150 (these palettes always start with l followed by 2 or 3 numbers)
Similar to Color
objects, Palette
objects allow for easy accessing of the names, hex codes, and rgb values of the underlying colors. See the documentation in docs/palettes.ipynb
for examples on how to do so.
Setting a Theme
For convenience, this package also allows you to pick a single "default" lightness value to use for all colors, so that lightness values do not have to be specified.
As an example, if you are exclusively working in hues with a lightness value of 150, then running this code...
from flexoki import Flexoki
Flexoki.lightness(150)
... would allow you to get red-150
, by using the shorthand red
instead:
Flexoki.colors.red # red-150
Flexoki.colors.purple # purple-150
Flexoki.palettes.defaults # all the colors at a lightness value of 150
See the documentation in docs/theme.ipynb
for more examples on how this works.
Filtering for Colors
While many palettes are pre-generated and bundled with the FlexokiSchema
, the filter()
function allows users to select subsets of hues and lightness values and generate palettes that best suit their needs.
from flexoki import Flexoki
# Can also be accessed via Flexoki.colors.filter()
Flexoki.filter(h=["red","blue","green"], # only return reds, blues, and greens
l=range(150,300), # only return colors with a lightness value between 150 and 300 (inclusive)
order="h_l", # order the colors by hue, and then by lightness
returns="palette") # return a Palette object
For more details on each of the accepted arguments, see the documentation in docs/filters.ipynb
.
Integration with matplotlib
Colors
Most matplotlib
plotting functions will accept either hex codes or rgb(a) arrays as an argument for color; therefore, basic compatibility with matplotlib is achieved using the hex
and rgb
attributes of a Color
object:
import matplotlib.pyplot
import pandas
from flexoki import Flexoki
...
# Assuming a Pandas dataframe (df), and a matplotlib Figure (fig) and Axis (ax)
...
df.plot(ax=ax, color=Flexoki.colors.cyan_500.hex, ...)
This package also includes a function, register_matplotlib()
, which adds each of the colors in the schema to matplotlib
's named color directory, allowing them to be used in the same way as the package's bundled colors.
import matplotlib.pyplot
import pandas
from flexoki import Flexoki
# Registering the colors with matplotlib, using the prefix "flexoki"
Flexoki.register_matplotlib()
# Now these colors can be accessed via string
df.plot(ax=ax, color="flexoki:cyan-500", ...)
Additional options for limiting which colors are registered, and customizing the prefix, are available; see the docs/matplotlib
section for details.
Palettes
Palette
objects, both the defaults and ones create by the user, can be turned into colormaps
with the function to_colormap()
, allowing them to be used anywhere a colormap would be used:
from flexoki import Flexoki
Flexoki.reds.to_colormap(kind="smooth") # will make a LinearSegmentedColormap (smooth gradient between colors)
Flexoki.l700.to_colormap(kind="discrete") # will make a ListedColormap (discrete colors visible)
These colormaps can also be named and registered with the colormap repository of matplotlib
as part of this function: see the docs/matplotlib
section for examples of usage. Note that register_matplotlib()
(shown above), does not register palettes, only colors.
Example Usage
Using individual colors with matplotlib
import matplotlib.pyplot
from flexoki import Flexoki
# Creating a simple line plot
fig, ax = matplotlib.pyplot.subplots(1,1, figsize=(5,5))
ax.plot([0,4],[1,1], color=Flexoki.colors.red_400.hex, linewidth=30) # dot notation
ax.plot([0,4],[2,2], color=Flexoki.colors["green-500"].hex, linewidth=30) # dict notation
ax.plot([0,4],[3,3], color=Flexoki.colors.blue.hex, linewidth=30) # using a default value
Using a palette with matplotlib
import random
import matplotlib.pyplot
from flexoki import Flexoki
# Creating a bar chart with multiple categories and random values
fig, ax = matplotlib.pyplot.subplots(1,1, figsize=(10,5))
ax.bar(range(0,9,1), height=[random.randint(2,10) for x in range(0,9)], color=Flexoki.palettes.l300.hex())
Roadmap
I expect the next major update to this package to occur only if/when the main Flexoki framework is updated. Otherwise, I might make small tweaks there and there based on my own use of this package, as well as feedback from other users (if any).
Some things I am considering:
-
Registering colormaps with matplotlib using the
register_matplotlib()
function -
Easy re-ordering of monolightness palettes
-
Ability to append paper/black colors to monochromatic palettes
-
Allowing default colors to be accessed directly from the
FlexokiSchema
object
License
The license is the same as Flexoki's (MIT).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file flexoki-2.0.0.tar.gz
.
File metadata
- Download URL: flexoki-2.0.0.tar.gz
- Upload date:
- Size: 18.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
a7c458b4bb241d0b073ef6536f83fd845d8c7512910dc2f7f55ab3eb8cafbfb7
|
|
MD5 |
d9213b331ae35384ad93dc85d260732b
|
|
BLAKE2b-256 |
9424ce7287c5e84063fa4fe09f1104a1503ea35d8abcba5287fe436129173e7d
|
File details
Details for the file flexoki-2.0.0-py3-none-any.whl
.
File metadata
- Download URL: flexoki-2.0.0-py3-none-any.whl
- Upload date:
- Size: 14.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
b44f827a427cd0b3191f7d7b7562cf8655cf3a4fc2398d1a7474cd5594745688
|
|
MD5 |
af486aa8c892177b5f6de7546f9ffe81
|
|
BLAKE2b-256 |
e4793d2e51ef6f53dcccb2e4e66f5f2ef559f13ef0e0800cb908f528a36851c7
|