Spaces:
Sleeping
Sleeping
| """Catppuccin Plotly template installer.""" | |
| import plotly.graph_objects as go | |
| import plotly.io as pio | |
| import streamlit as st | |
| from catppuccin import PALETTE | |
| def active_base() -> str: | |
| """Return the live theme flavor ("light"/"dark"). | |
| Reflects the user's choice in Streamlit's built-in Settings-menu theme | |
| toggle, falling back to the configured ``theme.base`` default. | |
| """ | |
| return st.context.theme.type or st.get_option("theme.base") | |
| def _flavor(base: str | None): | |
| return PALETTE.latte if base == "light" else PALETTE.mocha | |
| def install_catppuccin_theme(base: str | None = None) -> None: | |
| """Register a Catppuccin template and alias it as ``plotly_white``. | |
| Call once at startup. Persona-vectors pins ``template="plotly_white"`` on | |
| every figure, so replacing that entry themes all plots without any | |
| per-figure code. | |
| """ | |
| c = _flavor(base).colors | |
| bg, text, subtext = c.base.hex, c.text.hex, c.subtext1.hex | |
| if base == "light": | |
| # Latte's surface0/1 are heavy grays; use lighter slots so the grid | |
| # stays subtle, the legend isn't a gray block, and diverging plots | |
| # fade through near-white instead of mud. | |
| surface, line, mid = c.mantle.hex, c.surface0.hex, c.base.hex | |
| else: | |
| surface, line, mid = c.surface0.hex, c.surface1.hex, c.surface0.hex | |
| axis = dict( | |
| gridcolor=line, | |
| zerolinecolor=line, | |
| linecolor=line, | |
| tickcolor=line, | |
| tickfont=dict(color=subtext), | |
| title=dict(font=dict(color=text)), | |
| ) | |
| scene_axis = dict( | |
| backgroundcolor=bg, | |
| gridcolor=line, | |
| zerolinecolor=line, | |
| showbackground=True, | |
| color=text, | |
| tickfont=dict(color=subtext), | |
| ) | |
| template = go.layout.Template( | |
| layout=dict( | |
| paper_bgcolor=bg, | |
| plot_bgcolor=bg, | |
| font=dict(color=text), | |
| colorway=[ | |
| c.blue.hex, | |
| c.mauve.hex, | |
| c.green.hex, | |
| c.peach.hex, | |
| c.teal.hex, | |
| c.pink.hex, | |
| c.yellow.hex, | |
| c.sapphire.hex, | |
| c.lavender.hex, | |
| c.red.hex, | |
| c.sky.hex, | |
| c.maroon.hex, | |
| ], | |
| xaxis=axis, | |
| yaxis=axis, | |
| scene=dict(xaxis=scene_axis, yaxis=scene_axis, zaxis=scene_axis), | |
| legend=dict(bgcolor=surface, bordercolor=line, font=dict(color=text)), | |
| colorscale=dict( | |
| diverging=[[0.0, c.blue.hex], [0.5, mid], [1.0, c.red.hex]], | |
| ), | |
| ) | |
| ) | |
| pio.templates["catppuccin"] = template | |
| pio.templates["plotly_white"] = template | |
| pio.templates.default = "catppuccin" | |
| def style_plotly_layer_controls(fig: go.Figure, base: str | None = None) -> go.Figure: | |
| """Theme persona-vectors layer sliders/buttons for this Streamlit app.""" | |
| c = _flavor(base).colors | |
| surface = c.surface0.hex | |
| overlay = c.surface1.hex | |
| text = c.text.hex | |
| primary = c.blue.hex | |
| for slider in fig.layout.sliders: | |
| slider.bgcolor = surface | |
| slider.activebgcolor = primary | |
| slider.bordercolor = overlay | |
| slider.borderwidth = 1 | |
| slider.font = dict(color=text, size=11) | |
| slider.tickcolor = primary | |
| slider.currentvalue = dict( | |
| slider.currentvalue.to_plotly_json(), | |
| font=dict(color=text, size=13), | |
| ) | |
| for menu in fig.layout.updatemenus: | |
| if menu.type != "buttons": | |
| continue | |
| menu.bgcolor = surface | |
| menu.bordercolor = overlay | |
| menu.font = dict(color=text, size=13) | |
| return fig | |