## Plotly figure templates How to style Plotly figures with a Mantine theme. Category: Theming --- ### Plotly Figure Template Basics Plotly figure templates allow you to style your figures globally or per-figure. Templates include pre-defined color schemes, font styles, and layout configurations. For more details, refer to the [Plotly templates documentation](https://plotly.com/python/templates/). Below is an example using Plotly's built-in `plotly_white` and `plotly_dark` templates. This is the same figure styled for a light and dark theme. ```python import dash_mantine_components as dmc from dash import dcc import plotly.express as px df = px.data.gapminder() dff = df[df.year == 2007] component = dmc.SimpleGrid( [ dcc.Graph(figure=px.bar(dff, x="continent", y="pop", template="plotly_white", title="plotly_white theme")), dcc.Graph(figure=px.bar(dff, x="continent", y="pop", template="plotly_dark", title="plotly_dark theme")) ], cols=2 ) ``` ### Mantine-Themed Plotly Templates To make Plotly figures consistent with Mantine's default theme, Dash Mantine Components provides two custom Plotly templates: - **`mantine_light`**: Based on `plotly_white` and styled with Mantine's light theme. - **`mantine_dark`**: Based on `plotly_dark` and styled with Mantine's dark theme. These templates are created and registered using the `add_figure_templates` function. They include: - Color palettes from Mantine’s theme. - Fonts (`Inter` by default). - Background and grid colors that match Mantine’s styles. ```python import dash_mantine_components as dmc from dash import dcc import plotly.express as px df = px.data.gapminder() dff = df[df.year == 2007] dmc.add_figure_templates() component = dmc.SimpleGrid( [ dcc.Graph(figure=px.bar(dff, x="continent", y="pop", template="mantine_light", title="mantine_light theme" )), dcc.Graph(figure=px.bar(dff, x="continent", y="pop", template="mantine_dark", title="mantine_dark theme")) ], cols=2 ) ``` ### Setting a Default Template You can globally set either `mantine_light` or `mantine_dark` as the default Plotly template. This ensures all figures use the specified template unless explicitly overridden. ```python import dash_mantine_components as dmc # Set "mantine_dark" as the default template dmc.add_figure_templates(default="mantine_dark") ``` ### Modifying Existing Plotly Templates The `mantine_light` and `mantine_dark` templates can be customized like any other Plotly template. Refer to the [Plotly templates documentation](https://plotly.com/python/templates/) for more info and examples. ```python import plotly.io as pio import plotly.express as px import dash_mantine_components as dmc dmc.add_figure_templates() # Access the registered Mantine light template template = pio.templates["mantine_light"] # Reduce the margins in the template template.layout.margin = dict(l=20, r=20, t=20, b=20) fig = px.scatter(px.data.gapminder(), x="gdpPercap", y="lifeExp", template="mantine_light") ``` ### Customizing `add_figure_templates` Function The `add_figure_templates` function is available starting in DMC version 0.15.1. If you are using an earlier version, or if you are using a custom Mantine theme, you can include your own `add_figure_templates` implementation in your project. Example Project Structure: ```bash my_project/ ├── app.py ├── my_figure_templates.py ``` In `my_figure_templates.py`: Copy the `add_figure_templates` code from the [Dash Mantine Components GitHub](https://github.com/snehilvj/dash-mantine-components/blob/master/dash_mantine_components/figure_templates.py) repository and modify it to fit your project's requirements. In `app.py`: ```python from my_figure_templates import add_figure_templates # Register custom templates add_figure_templates() ``` In the [Help Center](https://github.com/snehilvj/dmc-docs/tree/main/help_center/theme_switch_figure_templates_custom) you'll find a complete minimal example of a custom figure template with a green primary color. ### Using a Theme Switcher To update the figure when switching themes, you need to change the Plotly template in a callback. > For more information on adding a theme switcher to your app, check the [Theme Switch Component](/theme-switch) section. The example below uses this app's theme switch component in the callback. Try it out by clicking the **theme switch** in the header! See a complete minimal example in the [Help Center](https://github.com/snehilvj/dmc-docs/tree/main/help_center/theme_switch_figure_templates_simple) ```python import dash_mantine_components as dmc from dash import dcc, Input, Output, callback import plotly.express as px df = px.data.gapminder() dff = df[df.year == 2007] dmc.add_figure_templates() # Theme switch in the dmc-docs header: # dmc.ColorSchemeToggle( # lightIcon=DashIconify(icon="radix-icons:sun", width=20), # darkIcon=DashIconify(icon="radix-icons:moon", width=20), # variant="light", # color="gray", # id="docs-color-scheme-switch", # ) component = dcc.Graph(id="figure-templates-histogram") @callback( Output("figure-templates-histogram", "figure"), Input("docs-color-scheme-switch", "computedColorScheme"), ) def update_figure(color): template = "mantine_dark" if color=="dark" else "mantine_light" return px.bar(dff, x="continent", y="pop", title="Population by Continent", template=template) ``` For better performance, you can update the figure template using [Partial Property Updates.](https://dash.plotly.com/partial-properties) Here is the callback updated to use `Patch` to change the figure template. Note that when using `Patch` you must use the template object rather than just the string name. ```python from dash import Input, Output, callback, Patch import plotly.io as pio @callback( Output("figure-templates-bar", "figure"), Input("docs-color-scheme-switch", "computedColorScheme"), ) def update_figure(color): # template must be template object rather than just the template string name template = pio.templates["mantine_dark"] if color=="dark" else pio.templates["mantine_light"] patched_fig = Patch() patched_fig["layout"]["template"] = template return patched_fig ``` ### Updating multiple figures To update multiple figure when switching themes, you can use [Pattern Matching Callbacks.](https://dash.plotly.com/pattern-matching-callbacks) The example below uses this app's theme switch component in the callback. Try it out by clicking the **theme switch** in the header! See a complete minimal example in the [Help Center](https://github.com/snehilvj/dmc-docs/tree/main/help_center/theme_switch_figure_templates) ```python import dash_mantine_components as dmc from dash import dcc, Input, Output, State, callback, Patch, ALL import plotly.express as px import plotly.io as pio dmc.add_figure_templates(default="mantine_light") df = px.data.gapminder() line_fig = px.line( df.query("1952 <= year <= 1982 & continent != 'Asia'"), x="year", y="gdpPercap", color="continent", line_group="country" ) dff = df[df.year == 2007] scatter_fig = px.scatter( dff, x="gdpPercap", y="lifeExp", size="pop", color="continent", log_x=True, size_max=60, title=f"2007 GDP per Capita vs Life Expectancy, Sized by Population ", ) avg_lifeExp = (dff["lifeExp"] * dff["pop"]).sum() / dff["pop"].sum() map_fig = px.choropleth( dff, locations="iso_alpha", color="lifeExp", title="%.0f World Average Life Expectancy was %.1f years" % (2007, avg_lifeExp), ) bar_fig = px.bar(dff, x="continent", y="pop", title="Population by Continent") graphs = dmc.Grid( [ dmc.GridCol(dcc.Graph(figure=bar_fig, id={"type": "graph", "index": "bar"}), span={"base": 12, "md":6}), dmc.GridCol(dcc.Graph(figure=scatter_fig, id={"type": "graph", "index": "scatter"}), span={"base": 12, "md":6}), dmc.GridCol(dcc.Graph(figure=line_fig, id={"type": "graph", "index": "line"}), span={"base": 12, "md":6}), dmc.GridCol(dcc.Graph(figure=map_fig, id={"type": "graph", "index": "map"}), span={"base": 12, "md":6}), ], gutter="xl", ) sample_controls = dmc.Box([ dmc.Button("sample button"), dmc.Button("sample red button", color="red"), dmc.Button("sample yellow button", color="yellow"), dmc.Slider(value=25, my="lg"), ], w=600) # used in the children prop of MantinePovider([], id="m2d-mantine-provider) component = dmc.Box([sample_controls, graphs]) @callback( Output({"type": "graph", "index": ALL}, "figure"), Input("docs-color-scheme-switch", "computedColorScheme"), State({"type": "graph", "index": ALL}, "id"), ) def update_figure(color, ids): # template must be template object rather than just the template string name template = pio.templates["mantine_dark"] if color=="dark" else pio.templates["mantine_light"] patched_figures = [] for i in ids: patched_fig = Patch() patched_fig["layout"]["template"] = template patched_figures.append(patched_fig) return patched_figures ```