Ashkan Taghipour (The University of Western Australia)
UI overhaul: immersive chapter-based experience
14ba315 | """Shared Plotly chart configuration and color constants for the Pangenome Atlas. | |
| Every chart-building callback should import from this module to ensure | |
| visual consistency across all plots. | |
| Exports | |
| ------- | |
| COLORS β dict of semantic color tokens. | |
| COUNTRY_COLORS β per-country color mapping (17 countries + Unknown). | |
| CLUSTER_COLORS β ordered list for the 3 optimal clusters. | |
| PLOTLY_TEMPLATE β light-background Plotly layout dict. | |
| PLOTLY_TEMPLATE_DARK β dark-background variant for globe / 3-D views. | |
| apply_template() β apply the atlas template to any ``plotly.graph_objects.Figure``. | |
| """ | |
| from __future__ import annotations | |
| from typing import TYPE_CHECKING | |
| if TYPE_CHECKING: | |
| import plotly.graph_objects as go # pragma: no cover | |
| # ===================================================================== | |
| # Color Palette | |
| # ===================================================================== | |
| COLORS: dict[str, str] = { | |
| # Gene classification | |
| "core": "#2E7D32", # forest green | |
| "shell": "#F9A825", # warm amber | |
| "cloud": "#C62828", # warm red | |
| # UI accents | |
| "selected": "#D4A017", # gold β user's selected line | |
| "accent": "#1565C0", # deep blue β links / actions | |
| # Backgrounds | |
| "bg_dark": "#1a2332", # dark navy β globe / hero header | |
| "bg_light": "#FAFAF5", # warm white β page background | |
| "bg_card": "#FFFFFF", # card surface | |
| # Text | |
| "text_primary": "#1A1A1A", | |
| "text_secondary": "#757575", | |
| "text_muted": "#94a3b8", | |
| # Structural | |
| "border": "#E0E0E0", | |
| "grid_faint": "#F0F0E8", | |
| } | |
| # Per-country colors used by the globe, UMAP, and any country legend. | |
| # 17 countries + Unknown. | |
| COUNTRY_COLORS: dict[str, str] = { | |
| "India": "#2E7D32", | |
| "Philippines": "#1565C0", | |
| "Kenya": "#C62828", | |
| "Nepal": "#D4A017", | |
| "Myanmar": "#6A1B9A", | |
| "Uganda": "#00838F", | |
| "Zaire": "#E65100", | |
| "Indonesia": "#455A64", | |
| "Jamaica": "#AD1457", | |
| "South_Africa": "#1B5E20", | |
| "Puerto_Rico": "#0277BD", | |
| "Sierra_Leone": "#BF360C", | |
| "Nigeria": "#827717", | |
| "Malawi": "#4E342E", | |
| "Italy": "#283593", | |
| "Sri_Lanka": "#00695C", | |
| "Thailand": "#FF6F00", | |
| "Unknown": "#9E9E9E", | |
| } | |
| # Cluster colors for the 3 optimal clusters (silhouette = 0.649). | |
| CLUSTER_COLORS: list[str] = ["#2E7D32", "#1565C0", "#C62828"] | |
| # ===================================================================== | |
| # Shared font stack (matches the Gradio theme) | |
| # ===================================================================== | |
| _FONT_STACK = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" | |
| # ===================================================================== | |
| # Plotly Layout Templates | |
| # ===================================================================== | |
| PLOTLY_TEMPLATE: dict = dict( | |
| layout=dict( | |
| paper_bgcolor="rgba(0,0,0,0)", | |
| plot_bgcolor="rgba(0,0,0,0)", | |
| font=dict( | |
| family=_FONT_STACK, | |
| color=COLORS["text_primary"], | |
| size=13, | |
| ), | |
| title=dict( | |
| font=dict(size=18, color=COLORS["text_primary"]), | |
| x=0.02, | |
| xanchor="left", | |
| ), | |
| xaxis=dict( | |
| showgrid=False, | |
| zeroline=False, | |
| showline=False, | |
| ), | |
| yaxis=dict( | |
| showgrid=False, | |
| zeroline=False, | |
| showline=False, | |
| ), | |
| margin=dict(l=30, r=20, t=50, b=30), | |
| hoverlabel=dict( | |
| bgcolor="white", | |
| font_size=13, | |
| font_family=_FONT_STACK, | |
| bordercolor=COLORS["border"], | |
| ), | |
| legend=dict( | |
| bgcolor="rgba(255,255,255,0.85)", | |
| bordercolor="rgba(0,0,0,0)", | |
| font=dict(size=12), | |
| ), | |
| ) | |
| ) | |
| # Dark variant for 3-D plots, globe visualisations, and hero panels. | |
| PLOTLY_TEMPLATE_DARK: dict = dict( | |
| layout=dict( | |
| paper_bgcolor=COLORS["bg_dark"], | |
| plot_bgcolor=COLORS["bg_dark"], | |
| font=dict( | |
| family=_FONT_STACK, | |
| color="#E0E0E0", | |
| size=13, | |
| ), | |
| title=dict( | |
| font=dict(size=18, color="#E0E0E0"), | |
| x=0.02, | |
| xanchor="left", | |
| ), | |
| xaxis=dict( | |
| showgrid=False, | |
| zeroline=False, | |
| showline=False, | |
| color="#E0E0E0", | |
| ), | |
| yaxis=dict( | |
| showgrid=False, | |
| zeroline=False, | |
| showline=False, | |
| color="#E0E0E0", | |
| ), | |
| margin=dict(l=30, r=20, t=50, b=30), | |
| hoverlabel=dict( | |
| bgcolor="#263245", | |
| font_size=13, | |
| font_family=_FONT_STACK, | |
| bordercolor="#3a4a60", | |
| ), | |
| legend=dict( | |
| bgcolor="rgba(26,35,50,0.85)", | |
| bordercolor="rgba(0,0,0,0)", | |
| font=dict(size=12, color="#E0E0E0"), | |
| ), | |
| ) | |
| ) | |
| # Modebar buttons to hide for a cleaner look. | |
| _MODEBAR_REMOVE = [ | |
| "toImage", | |
| "zoom2d", | |
| "pan2d", | |
| "select2d", | |
| "lasso2d", | |
| "autoScale2d", | |
| "resetScale2d", | |
| "zoomIn2d", | |
| "zoomOut2d", | |
| ] | |
| def apply_template(fig: "go.Figure", dark: bool = False) -> "go.Figure": | |
| """Apply the Atlas Plotly template to *fig* and hide the modebar. | |
| Parameters | |
| ---------- | |
| fig : plotly.graph_objects.Figure | |
| The figure to style in-place. | |
| dark : bool, optional | |
| If ``True``, use the dark-background variant suitable for globe | |
| and 3-D scenes. Defaults to ``False``. | |
| Returns | |
| ------- | |
| plotly.graph_objects.Figure | |
| The same figure, for chaining. | |
| """ | |
| template = PLOTLY_TEMPLATE_DARK if dark else PLOTLY_TEMPLATE | |
| fig.update_layout(**template["layout"]) | |
| fig.update_layout(modebar=dict(remove=_MODEBAR_REMOVE)) | |
| return fig | |