Skip to main content

Cinematic matplotlib styles inspired by iconic films, plus a reusable-brand API

Project description

cinestyle

CI Python License Code style: black Linter: ruff

Cinematic data-viz theming, done with color science. Twenty-four film-inspired themes that are beautiful, correct, and accessible, defined once and applied to matplotlib, Plotly, or Altair, plus an API for defining your own brand.

Twenty-four film looks, one per frame

Every theme plots data from its own film. Same data, cinematic finish:

Before and after

Why this exists

Most "pretty matplotlib" packages pick colors by eye and only look right on the one chart in their README. cinestyle is built differently:

  • Perceptually derived. Each theme's categorical palette and its sequential and diverging colormaps are computed in a perceptual color space (OKLCH, with CIEDE2000 distances) from a few sourced "hero" colors, not hand-waved. Sequential maps have monotonic lightness; diverging maps are symmetric.
  • One spec, three backends. Define a theme once and apply it to matplotlib, Plotly, or Altair. The palette, the sequential/diverging colormaps, and the chrome all travel; you stop caring which plotting library wins.
  • Works on every chart type. On matplotlib it only sets rcParams and registers colormaps. Lines, bars, scatter, hist, boxplots, pies, heatmaps, errorbars: all themed. You never switch themes mid-deck.
  • Accessible by design. audit() any palette (or theme) for color-vision deficiency and contrast; repair() turns it into a colorblind-safe variant.
  • Reproducible. Themes ship their fonts (SIL OFL), so a matplotlib chart looks the same on every machine.
  • Cinematic extras (matplotlib). A neon glow for the dark themes, and film-look LUTs you can apply to image plots and export as .cube.

Install

pip install cinestyle

Latest unreleased build: pip install git+https://github.com/Burton-David/cinematic-matplotlib.git.

Optional extras: cinestyle[plotly], cinestyle[altair] (the other backends), cinestyle[a11y] (color-vision checks), cinestyle[luts] (reading external .cube LUTs). For development: pip install -e ".[dev]". Requires Python 3.10+.

Quick start

import matplotlib.pyplot as plt
import numpy as np
import cinestyle

x = np.linspace(0, 12, 200)

# 1. Scoped: styling is restored when the block exits
with cinestyle.use("blade_runner"):
    fig, ax = plt.subplots()
    for i in range(4):
        ax.plot(x, np.sin(x + i * 0.6) + i * 0.4)
    cinestyle.add_glow(ax)          # the neon glow

# 2. Registered style sheet: use it like any matplotlib style
cinestyle.register()
plt.style.use("cinestyle-dune")

# 3. The Theme object itself: palette, colormaps, and more
theme = cinestyle.get_theme("ghibli")
plt.imshow(data, cmap=theme.sequential)

Other backends

The same theme drives Plotly and Altair. The palette, colormaps, and chrome carry over; glow and LUTs stay matplotlib-only.

import cinestyle

# Plotly
cinestyle.register_plotly()
fig.update_layout(template="cinestyle-blade_runner")   # or use_plotly("dune")

# Altair
cinestyle.register_altair(enable="dune")               # enables the theme

See docs/gallery.md for the same theme rendered across all three backends side by side.

Gallery

Each card plots something from its own film: Blade Runner's "Tears in Rain", the Bride's kill count, the Balance of the Force. All regenerated from deterministic data by python scripts/generate_gallery.py (add --reel to rebuild the GIF).

noir ghibli
wes_anderson blade_runner
star_wars matrix
dune fury_road
kill_bill in_the_mood
sin_city akira
the_fall tron
amelie the_shining
drive grand_budapest
nolan hero
suspiria moonlight
blade_runner_2049 her

The themes

Theme Film Font
noir Film noir / chiaroscuro Oswald
ghibli Studio Ghibli EB Garamond
wes_anderson Wes Anderson Jost
blade_runner Blade Runner (neon-noir) Share Tech Mono
star_wars Star Wars Oswald
matrix The Matrix Share Tech Mono
dune Dune (Villeneuve) Space Grotesk
fury_road Mad Max: Fury Road Anton
kill_bill Kill Bill Bebas Neue
in_the_mood In the Mood for Love EB Garamond
sin_city Sin City Anton
akira Akira Share Tech Mono
the_fall The Fall (Tarsem) EB Garamond
tron Tron: Legacy Share Tech Mono
amelie Amélie EB Garamond
the_shining The Shining (Kubrick) Bebas Neue
drive Drive Share Tech Mono
grand_budapest The Grand Budapest Hotel Jost
nolan Nolan (Interstellar, Inception) Space Grotesk
hero Hero (Zhang Yimou) Oswald
suspiria Suspiria Anton
moonlight Moonlight Jost
blade_runner_2049 Blade Runner 2049 Space Grotesk
her Her EB Garamond

Each Theme exposes its palette, sequential and diverging colormaps, heroes, and chrome. cinestyle.list_themes() lists them all.

Color, done right

The palette and colormaps are derived from the hero colors, preserving the film's mood (hue identity and chroma) while spacing colors perceptually:

theme = cinestyle.get_theme("dune")
theme.palette       # categorical cycle, perceptually separated
theme.sequential    # monotonic-lightness sequential colormap
theme.diverging     # symmetric diverging colormap

Accessibility

audit() and repair() work on any palette, theme name, or Theme, not just ours:

cinestyle.audit("blade_runner").summary()   # CIEDE2000 under protan/deutan/tritan + contrast
cinestyle.audit(["#D62728", "#2CA02C"])      # check your own colors
safe = cinestyle.repair("blade_runner")      # a colorblind-safe version

accessibility

Checks simulate the palette under each color-vision deficiency and flag any pair that collapses (CIEDE2000), plus WCAG non-text contrast against the background. The repair keeps the film's mood where it can and borrows from known-safe palettes (Okabe-Ito, Paul Tol) where it must.

Film looks

look = cinestyle.get_look("teal_orange")
im = ax.imshow(image)
look.apply_to_image(im)          # grade an image plot / heatmap
look.to_cube("teal_orange.cube") # export a 3D LUT for video tools

Looks are original parametric grades (lift/gamma/gain, saturation, split-tone). They matter most for image and heatmap plots; flat bar/line charts are carried by the palette and chrome.

Define your own brand

brand = cinestyle.define_brand(
    "acme",
    palette=["#0B5FFF", "#FF6B00", "#00B5AD"],
    background="#FBFBFD",
    foreground="#1A1A2E",
)
with brand.use():
    ...
brand.register()                  # plt.style.use("cinestyle-acme")
brand.to_matplotlibrc("acme.mplstyle")

Development

pip install -e ".[dev]"
black --check . && ruff check . && mypy cinestyle && pytest
python scripts/generate_gallery.py   # regenerate the gallery

Tests run headless (Agg) and assert that styling is actually applied: rcParams change, artist colors match the palette, colormaps are monotonic/symmetric, the scoped context restores global state, palettes pass the accessibility checks.

Credits

cinestyle is an independent, inspired-by tribute and is not affiliated with or endorsed by any rights holder; film titles are trademarks of their owners. See NOTICE.md for palette sources (incl. the wesanderson and ghibli palette projects) and bundled-font licenses.

License

MIT. See LICENSE.

Author

David Burton, databurton.com

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cinestyle-0.2.0.tar.gz (795.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cinestyle-0.2.0-py3-none-any.whl (802.0 kB view details)

Uploaded Python 3

File details

Details for the file cinestyle-0.2.0.tar.gz.

File metadata

  • Download URL: cinestyle-0.2.0.tar.gz
  • Upload date:
  • Size: 795.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for cinestyle-0.2.0.tar.gz
Algorithm Hash digest
SHA256 1aabf1dab51e02718b6dcb062614ee541724a0a322614ca66d34c65d1163ed7d
MD5 f80a96994362ba3ea45f53685c9a5309
BLAKE2b-256 edae5775ec90974b4934c231d59978234597efeca494671a039762866bfb510c

See more details on using hashes here.

Provenance

The following attestation bundles were made for cinestyle-0.2.0.tar.gz:

Publisher: release.yml on Burton-David/cinematic-matplotlib

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cinestyle-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: cinestyle-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 802.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for cinestyle-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 97f871360e034b7029696bede7df157a496f423de1077db3c501e69f8f59c023
MD5 71b676ff710c22c099b8167af24bba18
BLAKE2b-256 8a756e4b635e45554e11419f8fe2aee5d252335bf2d5aff38071e118a4774c9a

See more details on using hashes here.

Provenance

The following attestation bundles were made for cinestyle-0.2.0-py3-none-any.whl:

Publisher: release.yml on Burton-David/cinematic-matplotlib

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page