Skip to main content

polytope-theme

Chart and app themes for the Polytope design system, covering matplotlib, plotly, gradio and streamlit. Colors and fonts come from tokens/tokens.json at the repository root, and scripts/build.mjs writes them into this package.

Synthetic example, light style

Install

pip install polytope-theme

The package has no required dependencies. Each integration has an extra that pulls in its library: matplotlib, plotly, gradio, streamlit, or all.

pip install "polytope-theme[matplotlib,plotly]"

Palette

import polytope_theme as ply

ply.colors("light")["accent"]   # "#D9412B"
ply.categorical("dark", n=3)    # first three series colors for dark mode
ply.SEQUENTIAL                  # cobalt ramp, light to dark
ply.DIVERGING                   # cobalt, gray midpoint, tomato
ply.STATUS                      # good, warning, serious, critical
ply.SURFACE, ply.FONTS

Series get categorical colors in a fixed order, and the colors never repeat. categorical() raises ValueError for more than 8 series; fold the extra series into an "Other" group or split the chart into small multiples. Scatter plots and small multiples use only the first 3 slots (ply.SCATTER_SLOTS). Use SEQUENTIAL for magnitudes and DIVERGING for values around a meaningful center. The four STATUS colors are reserved for states and always appear next to a label or marker.

matplotlib

import matplotlib.pyplot as plt
import polytope_theme as ply
from polytope_theme.mpl import label_lines

ply.use("light")  # or "dark"

fig, ax = plt.subplots()
for name, ys in runs.items():
    ax.plot(epochs, ys, label=name)
ax.legend()
label_lines(ax)  # writes each series name at the right end of its line

label_lines uses the text color for labels, spreads labels that would overlap, and draws a thin leader line for any label it had to move.

ply.use() also registers the colormaps ply-sequential and ply-diverging, with _r reversed versions, and makes ply-sequential the default for images.

from matplotlib.colors import TwoSlopeNorm

ax.imshow(delta, cmap="ply-diverging", norm=TwoSlopeNorm(vcenter=0))

To apply the style to one block of code, use plt.rc_context(polytope_theme.mpl.rc_params("dark")).

matplotlib only finds Libre Franklin if it is installed as a system font (TTF or OTF from Google Fonts). Without it, text falls back to Franklin Gothic, Helvetica Neue, Arial and then DejaVu Sans.

examples/make_examples.py renders the figures in this README. The dark version:

Synthetic example, dark style

plotly

import plotly.express as px
from polytope_theme import plotly_theme

plotly_theme.register(default="light")  # adds "polytope" and "polytope_dark"

fig = px.line(df, x="epoch", y="accuracy", color="model")
fig.update_layout(template="polytope_dark")  # override for one figure

plotly_theme.template(mode) returns the Template object directly if you would rather leave plotly.io.templates alone.

gradio

import gradio as gr
from polytope_theme.gradio_theme import theme

with gr.Blocks() as demo:
    gr.Textbox(label="Graph ID")
    gr.Button("Run", variant="primary")

demo.launch(theme=theme("light"))

Gradio 6 takes the theme in launch(). On gradio 4 and 5, pass it as gr.Blocks(theme=theme()). The mode can be "light", "dark", or "auto", which follows the browser setting. Corners are square, primary buttons are black and turn tomato on hover, and fonts load from Google Fonts.

streamlit

from polytope_theme.streamlit_theme import config_toml, write_config

write_config(".streamlit/config.toml", mode="light")
print(config_toml("dark"))

Run write_config once from the app folder. It will not replace a config.toml that it did not write itself; pass overwrite=True, or paste the output of config_toml() into your existing file. The font settings need streamlit 1.50 or newer. For older versions or offline apps, use config_toml(mode, google_fonts=False).

Development

uv venv .venv
uv pip install --python .venv/bin/python -e ".[matplotlib,plotly]" pytest
.venv/bin/python -m pytest

src/polytope_theme/_tokens.py and the files in src/polytope_theme/styles/ are generated. To change them, edit tokens/tokens.json at the repository root and run node scripts/build.mjs.

Metadata

Release files for polytope-theme 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for polytope-theme 0.3.0
File Size Uploaded
polytope_theme-0.3.0.tar.gz 20.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for polytope-theme 0.3.0
File Interpreter ABI Platform
polytope_theme-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 42.2 kB

Release files / polytope_theme-0.3.0.tar.gz

Download URL polytope_theme-0.3.0.tar.gz
Size 20.4 kB
Tags Source
SHA-256 checksum
How to use checksums
c693cb2124e9157749c9dbc509d787acc9ee3103688b7c951aafc00a3b6f5306
BLAKE2b-256 checksum
How to use checksums
39f3c5f7f3e8d6d48232867c4f3bd59b027782fa3e014214fa95e9bc365ef85f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

Release files / polytope_theme-0.3.0-py3-none-any.whl

Download URL polytope_theme-0.3.0-py3-none-any.whl
Size 21.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5be4f308b6dd269ec2a14cfa7dec7a6e2db183c5bb9e7b2d054c70f39e15c39c
BLAKE2b-256 checksum
How to use checksums
1a78b7f74125e116680b903666cf3dfa8cb5a770551b2bcb6cfff98477141364
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

Release history Release notifications | RSS feed

0.4.0

2 release files

This release

0.3.0 This release

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.4

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page