A Python library for creating, managing, and visualizing custom color palettes using 'natural' color models (RYB, HSL). The original purpose was to use them in some microcontroller projects, where the naive fiddling with RGB-tuples typically produces ugly colors on OLED- and LCD-display. The tools help to predefine matching color list in RYB- or HSL-color spaces and then transform them into RGB-space for display.
- Convert between RGB, HSL, and RYB (Red-Yellow-Blue) color models
- Create monochromatic palettes and color wheel distributions
- Uses RYB color wheel for more natural color mixing
- Save and load palettes in CSV format
from ColorTools import ColorTools
from palettes import Palette
# Create a monochromatic blue palette
colors = ColorTools.monochrome(8, hue=240, sat=0.9, low=0.1, lhi=0.95) # blue color in 8 luminace values
greys = ColorTools.monochrome(4, hue=240, sat=0.04, low=0.1, lhi=0.95) # very low saturation generates grey
my_blues = Palette('MyBlues', 'A blue monochrome palette', colors, greys)
# Access colors
print(palette.colors) # List of hex color strings
print(palette.grey) # List of hex strings of greys
print(palette(0)) # First color: '#1a1aff'Step the hue value (angle) on the color wheel, while keeping saturation and luminance constant.
from ColorTools import ColorTools
# Create 12 evenly distributed colors around the color wheel
colors = ColorTools.color_wheel(
N=12, # Number of colors
anchor=0, # Starting hue (0-360 degrees)
step=30, # Degrees between colors
sat=0.8, # Saturation (0.0-1.0)
lum=0.5, # Lightness (0.0-1.0)
wheel='RYB' # Use RYB color model (or 'RGB')
)For keeping the color hue constant and stepping the luminace/lightness use ColorTools.monochrome()
The predefined palettes are holding lists of RGB-colorcodes with 16 values (typically 12 colors and 4 grey).
from palettes import Palettes_16c
# Access predefined 16-color palettes
berry_pal = Palettes_16c.get('Berry') # Get a specific palette
# Get available palettes as list
all_palettes = list(Palettes_16c.keys())The library includes the palettes shown in the doc/ folder:
| Name | Description |
|---|---|
| *** Full Color Wheels | |
| Prime | Red, Yellow, Green, Blue; 3 levels |
| RGB_60 | 12 RGB color, 60% saturation, 4 greys |
| RGB_80 | 12 RGB color, 80% saturation, 4 greys |
| RGB_100 | 12 RGB color, 100% saturation, 4 greys |
| RYB_60 | 12 natural colors, 60% saturation, 4 greys |
| RYB_80 | 12 natural colors, 80% saturation, 4 greys |
| RYB_100 | 12 natural colors, 100% saturation, 4 greys |
| Square | 4 tones, ~90° delta in hue |
| Ternary | 3 tones, ~120° delta in hue |
| LED | 6 colors in 2 levels (on/off), pure grey |
| *** Color segments | |
| Red | Red segment of color wheel |
| Orange | Bright orange |
| Yellow | Yellow segment of color wheel |
| Blue | Blue segment of color wheel |
| Grey | 16 shades of grey |
| *** Monochromes | |
| MonoBlue | Blue 8 levels, blueish grey |
| MonoGreen | Green in 8 levels, greenish grey |
| MonoRed | Red in 8 levels, pure greys |
| MonoYellow | Yellow in 8 levels, beige grey |
| *** Themes | |
| Aqua | Blue dark colors, blueish grey |
| Berry | Violet saturated colors, blueish grey |
| Dune | Beige light colors |
| Frozen | Blueish colors from RGB wheel |
| Gotham | Daaark |
| Retro | Light colors, beige grey |
| Sunflower | Yellow bright colors, greenish grey |
| Sweden | Yellow & Blue |
| Tomato | Red & Green |
Use plot_palettes in show_palettes.py to plot a palette. If you set save=True, the plot will be saved as .png in ./palette_images
from show_palettes import plot_palette
from palettes import Palette
sunset = Palette('Sunset', 'warm colors',
['#FF5733', '#FFC300', '#FF8D1A'],
['#808080', '#606060'])
# Create visualization (saved to palette_images/)
plot_palette(sunset, save=True)Generate N evenly spaced values between start and stop.
Clamp value(s) to a specified range.
Convert RGB floats (0.0-1.0) to hexadecimal color string.
Convert hexadecimal color string to RGB floats.
Convert RYB (Red-Yellow-Blue) artistic color space to RGB.
Args:
r,y,b: Color components (0.0-1.0)
Returns: RGB tuple (r, g, b)
Convert HSL (Hue, Saturation, Lightness) to RGB.
Args:
hue: Hue angle in degrees (0-360)sat: Saturation (0.0-1.0)lum: Lightness (0.0-1.0)wheel: 'RYB' for artistic colors or 'RGB' for standard
Returns: RGB tuple (r, g, b)
Convert RGB to HSL color space.
Args:
r,g,b: RGB components (0.0-1.0)
Returns: List [hue (0-360), saturation (0.0-1.0), lightness (0.0-1.0)]
Generate a monochromatic color palette with varying lightness.
Args:
N: Number of colors to generatehue: Hue angle in degrees (0-360)sat: Base saturation (0.0-1.0)low: Minimum lightness (0.0-1.0)lhi: Maximum lightness (0.0-1.0)wheel: Color wheel type ('RYB' or 'RGB')
Returns: List of hex color strings
Example:
# Create 8 shades of red from light to dark
reds = ColorTools.monochrome(8, hue=0, sat=0.95, low=0.1, lhi=0.95)Generate colors evenly distributed around the color wheel.
Args:
N: Number of colors to generateanchor: Starting hue angle in degrees (0-360)step: Hue increment in degrees between adjacent colorssat: Saturation level (0.0-1.0)lum: Lightness level (0.0-1.0)wheel: Color wheel type ('RYB' or 'RGB')
Returns: List of hex color strings
Example:
# Create complementary colors (opposite sides of wheel)
complementary = ColorTools.color_wheel(2, anchor=0, step=180, sat=0.8, lum=0.5)name: Palette name (str)note: Palette description (str)colors: Main colors excluding grey shades (list[str])grey: Grey shade colors (list[str])length: Total size of color list (colors+grey) (int)
Create a new palette with two sections for colors and greys.
Access colors by index or get all colors.
palette = Palette('test', 'some colors', ['#FF0000', '#00FF00'])
palette() # Returns all colors
palette(0) # Returns '#FF0000'Export palette as CSV string.
Create palette from CSV string (class method).
This library supports both RYB (Red-Yellow-Blue) and RGB color wheels:
-
RYB Color Wheel: Based on traditional artistic color theory. Better for creating natural-looking color schemes and mimicking how paint colors mix. Default for most operations.
-
RGB Color Wheel: Based on additive light mixing. Better for screen displays and when you need precise RGB color control.
Example comparing both:
# RYB wheel - more natural for design
ryb_colors = ColorTools.color_wheel(6, wheel='RYB')
# RGB wheel - standard computer graphics
rgb_colors = ColorTools.color_wheel(6, wheel='RGB')from ColorTools import ColorTools
# Start with orange (30°) and get its complement (210°)
complementary = ColorTools.color_wheel(
N=2, anchor=30, step=180, sat=0.85, lum=0.5
)# Three colors equally spaced (120° apart)
triadic = ColorTools.color_wheel(
N=3, anchor=0, step=120, sat=0.9, lum=0.5
)# Base color plus two colors adjacent to its complement
base = ColorTools.color_wheel(1, anchor=30, sat=0.9, lum=0.5)
adjacent = ColorTools.color_wheel(2, anchor=180, step=30, sat=0.8, lum=0.5)
split_comp = base + adjacent# Colors adjacent on the color wheel
analogous = ColorTools.color_wheel(
N=5, anchor=200, step=15, sat=0.8, lum=0.6
)- 0° = Red
- 60° = Yellow
- 120° = Green
- 180° = Cyan
- 240° = Blue
- 300° = Magenta
- 0.0 = Grayscale
- 0.5 = Muted colors
- 1.0 = Fully saturated
- 0.0 = Black
- 0.5 = Pure color
- 1.0 = White
Roman Dischler
Copyright © 2025 Roman Dischler
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.