Skip to content

visualdynamics.theme

theme

Light/dark theme colors shared by the 3D view, 2D plots, and the GUI.

Qt's native style already follows the OS appearance for widgets; the things visualdynamics draws itself (the VTK scene and pyqtgraph plots) have to be told, which is what these colors are for.

Functions:

Name Description
theme

Resolve a theme name (or a colors dict) to a colors dict.

colormap

values in 0..1 as an (N, 3) array of RGB, on VIRIDIS.

system_scheme

'dark' or 'light' from the OS appearance, via Qt.

Functions:

theme

theme(
    name: str | Mapping[str, str] | None = None,
) -> dict[str, str]

Resolve a theme name (or a colors dict) to a colors dict.

Source code in src/visualdynamics/theme.py
def theme(name: str | Mapping[str, str] | None = None) -> dict[str, str]:
    """Resolve a theme name (or a colors dict) to a colors dict."""
    if isinstance(name, dict):
        return name
    if name is None:
        return THEMES[DEFAULT]
    try:
        return THEMES[name]
    except KeyError:
        raise ValueError(f"Unknown theme {name!r}; choose from {sorted(THEMES)}")

colormap

colormap(values: Any) -> Any

values in 0..1 as an (N, 3) array of RGB, on VIRIDIS.

Source code in src/visualdynamics/theme.py
def colormap(values: Any) -> Any:
    """`values` in 0..1 as an (N, 3) array of RGB, on `VIRIDIS`."""
    import numpy as np

    stops = np.asarray(VIRIDIS, dtype=float)
    t = np.clip(np.asarray(values, dtype=float), 0.0, 1.0) * (len(stops) - 1)
    low = np.clip(t.astype(int), 0, len(stops) - 2)
    f = (t - low)[..., None]
    return stops[low] * (1.0 - f) + stops[low + 1] * f

system_scheme

system_scheme(app: Any = None) -> str

'dark' or 'light' from the OS appearance, via Qt.

Falls back to the default theme when Qt or an application instance is unavailable (e.g. plain scripting use).

Source code in src/visualdynamics/theme.py
def system_scheme(app: Any = None) -> str:
    """'dark' or 'light' from the OS appearance, via Qt.

    Falls back to the default theme when Qt or an application instance is
    unavailable (e.g. plain scripting use).
    """
    try:
        from PySide6.QtCore import Qt
        from PySide6.QtWidgets import QApplication
    except ImportError:
        return DEFAULT
    app = app or QApplication.instance()
    if app is None:
        return DEFAULT
    scheme = app.styleHints().colorScheme()
    if scheme == Qt.ColorScheme.Dark:
        return 'dark'
    if scheme == Qt.ColorScheme.Light:
        return 'light'
    palette = app.palette()  # Qt could not tell: judge by palette lightness
    return ('dark' if palette.color(palette.ColorRole.Window).lightness() < 128
            else 'light')