Matplotlib utilities and color palettes for publication-ready figures
Project description
waxwing
Matplotlib utilities and color palettes for publication-ready figures.
Waxwing applies sensible defaults—clean spines, print-quality DPI, editable PDF fonts, bundled typefaces—so you spend less time fighting Matplotlib and more time on your figures.
Installation
pip install waxwing
Quick start
import matplotlib.pyplot as plt
import waxwing
waxwing.set_default_styles() # apply all defaults at once
fig, ax = plt.subplots()
ax.plot([1, 2, 3], color=waxwing.palettes.clay[1])
waxwing.trim_spines(ax)
plt.savefig("figure.pdf")
Styling
set_default_styles()
Applies the full waxwing style in one call:
| Setting | Value |
|---|---|
| Font | Source Sans 3, 9 pt |
| Figure size | 6.5 × 3 in (single column, papers) |
| Screen DPI | 150 |
| Save DPI | 300 |
| Save bbox | tight |
| PDF/PS font type | 42 (editable in Illustrator) |
| Top/right spines | removed |
| Axis margins | 0 |
You can also set individual properties:
waxwing.set_font("Literata") # switch to a serif font
waxwing.set_figsize(3.25, 2.5) # half-column width
trim_spines(ax=None, keep_right=False, keep_top=False)
Clips the left and bottom spines to the outermost tick marks, giving a clean floating-axis look. Call after all data and tick configuration is done.
fig, ax = plt.subplots()
ax.plot(x, y)
waxwing.trim_spines(ax)
Fonts
Four variable-weight typefaces are bundled and registered automatically on import:
| Name | Style |
|---|---|
"Source Sans 3" |
Neutral sans-serif (default) |
"Noto Sans" |
Wide-coverage sans-serif |
"Source Serif 4" |
Optical-size serif |
"Literata" |
Literary serif |
print(waxwing.list_fonts())
# ['Noto Sans', 'Source Sans 3', 'Source Serif 4', 'Literata']
waxwing.set_font("Source Serif 4")
Color palettes
All palettes live in waxwing.palettes and are plain Python lists of hex strings, so they work anywhere Matplotlib accepts a color sequence. YOu can also use them with seaborn.
from waxwing import palettes
ax.plot(x, y, color=palettes.clay[1])
ax.set_prop_cycle(color=palettes.spring)
# seaborn:
sns.color_palette(palettes.savanna)
# reversed colormap:
palettes.waxwing[::-1]
Categorical
| Palette | Colors | Character |
|---|---|---|
wax |
6 | yellow, red, green, gold, blue, violet |
clay |
5 | warm earth tones |
fruit |
5 | vibrant warm hues |
matcha |
5 | muted purples and pastels |
earth |
5 | dark browns and teal |
lichen |
8 | greens, ochre, and lavender |
solid |
5 | bold primaries |
sport |
5 | vivid cyan, purple, gold |
Sequential (dark → light)
| Palette | Colors | Character |
|---|---|---|
waxwing |
7 | warm taupe → off-white |
twilight |
6 | navy → lavender → grey |
canopy |
6 | forest green → cream |
glacier |
6 | deep blue → near-white |
Diverging
| Palette | Colors | Character |
|---|---|---|
savanna |
6 | brown ↔ olive green |
heath |
6 | warm brown ↔ cool green |
coastline |
6 | slate blue ↔ mauve |
Large categorical cycle: spring
spring contains 31 colors organized in five tonal cycles (vivid → pale → dark → mid → near-black, plus greys). It is designed to support figures with many series while maintaining visual coherence.
ax.set_prop_cycle(color=palettes.spring)
Requirements
- Python ≥ 3.8
- matplotlib
Development
Creating image in readme of current color palettes:
python create_palettes.py
Adding a new font:
Only add fonts with licenses that allow distribution.
- Obtain the Variable font or each weight as separate ttf. I select 350 i.e. 'Book' as the default font weight, which is typically not provided but can be created from Variable fonts.
- If needed, instance the font into a static .ttf:
pip install fonttools
fonttools varLib.instancer \
SourceSans3-VariableFont_wght.ttf \
wght=350 \
-o SourceSans3-Book.ttf
- Save copies under fonts/Name/static/[Name]-Light.ttf (or Medium, Regular, etc)
- Update
waxwing.py:_font_filesandFontNamevariables with Name and paths to the static font weight files
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
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file waxwing-0.1.0.tar.gz.
File metadata
- Download URL: waxwing-0.1.0.tar.gz
- Upload date:
- Size: 3.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb73ad03d6b67c2b468a90ebccfdb45beb3edebab5f8f60f8b003a0f49024300
|
|
| MD5 |
781a5618de62c4a7875d8db4e2012c6c
|
|
| BLAKE2b-256 |
e577e06f3378d447b29506057ba078b45e473b19aa2d708dfaf0abb279f67260
|
File details
Details for the file waxwing-0.1.0-py3-none-any.whl.
File metadata
- Download URL: waxwing-0.1.0-py3-none-any.whl
- Upload date:
- Size: 3.2 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c565c05bce29a49afcee3766ba1c45b55bc7737d343823c464a7333245b8d81d
|
|
| MD5 |
579b8967b45dc07c21a11c2c8a40006c
|
|
| BLAKE2b-256 |
134532f8799c1b979085edd94368dab7aa7bd7b7b18860a422d8d54d7282c6bd
|