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.
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:
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)
| File | Size | Uploaded | |
|---|---|---|---|
| polytope_theme-0.3.0.tar.gz | 20.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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 logRelease 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