Py.Cafe

amward/

updated-mantine-themed-figure-templates

Figure templates with styled buttons in both light and dark themes

DocsPricing
  • app.py
  • requirements.txt
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

import dash_mantine_components as dmc
from dash import Dash, dcc, Input, Output, State, callback, _dash_renderer, Patch
import plotly.graph_objects as go
import pandas as pd
import plotly.io as pio
from dash_iconify import DashIconify
_dash_renderer._set_react_version("18.2.0")

dmc.add_figure_templates(default="mantine_dark")


def make_range_buttons():
    # Load data
    df = pd.read_csv(
        "https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv")
    df.columns = [col.replace("AAPL.", "") for col in df.columns]

    # Create figure
    fig = go.Figure()

    fig.add_trace(
        go.Scatter(x=list(df.Date), y=list(df.High)))

    # Set title
    fig.update_layout(
        title_text="Time series with range slider and selectors"
    )

    # Add range slider
    fig.update_layout(
        xaxis=dict(
            rangeselector=dict(
                buttons=list([
                    dict(count=1,
                         label="1m",
                         step="month",
                         stepmode="backward"),
                    dict(count=6,
                         label="6m",
                         step="month",
                         stepmode="backward"),
                    dict(count=1,
                         label="YTD",
                         step="year",
                         stepmode="todate"),
                    dict(count=1,
                         label="1y",
                         step="year",
                         stepmode="backward"),
                    dict(step="all")
                ])
            ),
            rangeslider=dict(
                visible=True
            ),
            type="date"
        )
    )
    return fig



theme_toggle = dmc.ActionIcon(
    [
        dmc.Paper(DashIconify(icon="radix-icons:sun", width=25), darkHidden=True),
        dmc.Paper(DashIconify(icon="radix-icons:moon", width=25), lightHidden=True),
    ],
    variant="transparent",
    color="yellow",
    id="color-scheme-toggle",
    size="lg",
)


layout = dmc.Container([
    dmc.Group([
        dmc.Title("Figure Template Demo", my="md"),
        theme_toggle,
    ], justify="space-between"),
    dcc.Graph(figure=make_range_buttons(), id="graph")
], fluid=True)


app= Dash(external_stylesheets=dmc.styles.ALL)

app.layout = dmc.MantineProvider(
    layout,
    forceColorScheme="dark",
    id="mantine-provider"
)


@callback(
    Output("mantine-provider", "forceColorScheme"),
    Input("color-scheme-toggle", "n_clicks"),
    State("mantine-provider", "forceColorScheme"),
    prevent_initial_call=True,
)
def switch_theme(_, theme):
    return "dark" if theme == "light" else "light"

@callback(
    Output("graph", "figure"),
    Input("mantine-provider", "forceColorScheme"),
)
def update_figure(theme):
    # template must be template object rather than just the template string name
    template = pio.templates["mantine_light"] if theme == "light" else pio.templates["mantine_dark"]
    patched_fig = Patch()
    patched_fig["layout"]["template"] = template
    return patched_fig

if __name__ == "__main__":
    app.run(debug=True)