VegaAltairStyle#

Download this notebook from GitHub (right-click to download).


import altair as alt
import panel as pn

from vega_datasets import data


pn.extension("vega", sizing_mode="stretch_width", template="fast")

Styling Vega and Altair for Panel#

In this example we will show how to style Vega and Altair charts with Panel supporting the default and the dark theme.

VegaAltairStyle.gif

Get or set the theme#

When we use the Fast templates the theme will be available from the query args

def get_theme():
    return pn.state.session_args.get("theme", [b'default'])[0].decode()
theme=get_theme()
theme
'default'

Select a nice accent color#

Below we create some functionality to cycle through a list of nice accent colors.

nice_accent_colors = [
    ("#00A170", "white"), # Mint
    ("#DAA520", "white"), # Golden Rod
    ("#F08080", "white"), # Light Coral
    ("#4099da", "white"), # Summery Sky
    ("#2F4F4F", "white"), # Dark Slate Grey
    ("#A01346", "white"), # Fast
]
def get_nice_accent_color():
    """Returns the 'next' nice accent color"""
    if not "color_index" in pn.state.cache:
        pn.state.cache["color_index"]=0
    elif pn.state.cache["color_index"]==len(nice_accent_colors)-1:
        pn.state.cache["color_index"]=0
    else:
        pn.state.cache["color_index"]+=1
    return nice_accent_colors[pn.state.cache["color_index"]]
accent_color, color = get_nice_accent_color()
pn.pane.Markdown(f"# Color: {accent_color}", background=accent_color, height=70, margin=0, style={"color": color, "padding": "10px"})

Vega and Vega-lite#

You can configure the style of vega and vega-lite via the config key. Please note that only vega-lite supports responsive behaviour by setting width and height to container. vega requires the width and height to be integers.

See Vega Themes and the Vega Themes Explorer App for more examples.

def get_vega_plot(theme="default", accent_color="blue"):
    vegalite = {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "description": "A simple bar chart with rounded corners at the end of the bar.",
      "width": "container",
      "height": "container",
      "data": {
        "values": [
          {"a": "A", "b": 28},
          {"a": "B", "b": 55},
          {"a": "C", "b": 43},
          {"a": "D", "b": 91},
          {"a": "E", "b": 81},
          {"a": "F", "b": 53},
          {"a": "G", "b": 19},
          {"a": "H", "b": 87},
          {"a": "I", "b": 52}
        ]
      },
      "mark": {"type": "bar", "cornerRadiusEnd": 4, "tooltip": True},
      "encoding": {
        "x": {"field": "a", "type": "ordinal"},
        "y": {"field": "b", "type": "quantitative"},
        "color": {"value": accent_color},
      }
    }

    if theme == "dark":
        vegalite["config"] = {
            "background": "#333",
            "title": {"color": "#fff"},
            "style": {"guide-label": {"fill": "#fff"}, "guide-title": {"fill": "#fff"}},
            "axis": {"domainColor": "#fff", "gridColor": "#888", "tickColor": "#fff"},
        }
    return vegalite
vega_plot = get_vega_plot(theme=theme, accent_color=accent_color)
vega_pane = pn.pane.Vega(vega_plot, height=500, sizing_mode="stretch_both", name="VEGA")
vega_pane

Altair#

You can select the theme of Altair plots using altair.themes.enable and the color using the configure_mark method.

For more details see the

def get_altair_plot(theme="default", accent_color="blue"):
    if theme == "dark":
        alt.themes.enable("dark")
    else:
        alt.themes.enable("default")
    return (
        alt.Chart(data.cars())
        .mark_circle(size=200)
        .encode(
            x='Horsepower:Q',
            y='Miles_per_Gallon:Q',
            tooltip=["Name", "Origin", "Horsepower", "Miles_per_Gallon"],
        )
        .configure_mark(
            color=accent_color
        )
        .properties(
            height="container",
            width="container",
        )
        .interactive()
    )
altair_plot = get_altair_plot(theme=theme, accent_color=accent_color)
altair_pane = pn.pane.Vega(altair_plot, height=500, sizing_mode="stretch_both", name="ALTAIR")
altair_pane

Layout and style the data app#

Note how we mark this component .servable() so that it shows up in our data app.

pn.Tabs(vega_pane, altair_pane).servable(title="Panel - Vega/ Altair with custom styling")
pn.state.template.param.update(accent_base_color=accent_color, header_background=accent_color)

You can serve the app via panel serve VegaAltairStyle.ipynb and find it at http://localhost:5006/VegaAltairStyle. You should add the --autoreload flag while developing for hot reloading.

This web page was generated from a Jupyter notebook and not all interactivity will work on this website. Right click to download and run locally for full Python-backed interactivity.

Download this notebook from GitHub (right-click to download).