Hey @tphil10
Ok, grab a cup of coffee, and let’s step through creating a minimal working example of an app with a theme switcher, and I’ll show how all the features available in the `dash-bootstrap-templates library work together.
As you’ve noticed, the plotly figures aren’t updated based on a CSS stylesheet. You can update the figure manually like you are doing with fig.update(...)
This updates the currently selected figure template. The default template is called “plotly” Learn more about plotly figure templates and how to change them here. In any Dash app, you can choose from one of the 12 built-in plotly figure templates.
You can find an additional 26 plotly figure templates in the dash-bootstrap-templates
library. There is one for each of the themes available in the dash-bootstrap-components
library.
Here is how to load the “cyborg” themed template and make it the default template in your app:
from dash_bootstrap_templates import load_figure_template
load_figure_template("cyborg")
Now “cyborg” is the default template instead of “plotly” . If you didn’t want to include a theme switch component, then that’s all you need to do. Now all your figures would have the fonts, background color, text colors and trace colors etc based on the Bootstrap “cyborg” theme.
But since we want to make an app with a theme switch, let’s load two templates. Here is an example: This loads “minty” and “cyborg”
from dash import Dash, dcc, Input, Output
import plotly.express as px
import dash_bootstrap_components as dbc
from dash_bootstrap_templates import load_figure_template
# This loads the "cyborg" and "minty" themed figure template from dash-bootstrap-templates library,
# adds it to plotly.io and makes "cyborg" (The first template in the list) the default figure template.
load_figure_template(["cyborg", "minty"])
app = Dash(__name__, external_stylesheets=[dbc.themes.MINTY])
df = px.data.tips()
app.layout = dbc.Container([
dcc.Dropdown(
id='values',
value='total_bill',
options=[{'value': x, 'label': x}
for x in ['total_bill', 'tip', 'size']],
clearable=False
),
dcc.Graph(id="pie-chart"),
], fluid=True)
@app.callback(
Output("pie-chart", "figure"),
Input("values", "value"))
def generate_chart(value):
fig = px.pie(df, values=value, names="day", template="minty")
return fig
if __name__ == "__main__":
app.run_server(debug=True)
Now, to manually change to the Cyborg theme, change these two lines of code:
app = Dash(__name__, external_stylesheets=[dbc.themes.CYBORG])
fig = px.pie(df, values=value, names="day", template="cyborg")
Here is what the figure looks like now:
But notice how the dropdown doesn’t look good in the dark theme - it’s still white, and in some themes you can’t read the text in the dropdown at all.
So this is where the dbc_css stylesheet comes in handy. It will automatically style the dash-core-components like the dropdown with your Bootstrap theme.
So let’s add that to the app:
from dash import Dash, dcc, Input, Output
import plotly.express as px
import dash_bootstrap_components as dbc
from dash_bootstrap_templates import load_figure_template
# This loads the "cyborg" and "minty" themed figure template from dash-bootstrap-templates library,
# adds it to plotly.io and makes "cyborg" (The first template in the list) the default figure template.
load_figure_template(["cyborg", "minty"])
dbc_css = (
"https://cdn.jsdelivr.net/gh/AnnMarieW/dash-bootstrap-templates@V1.0.4/dbc.min.css"
)
app = Dash(__name__, external_stylesheets=[dbc.themes.CYBORG, dbc_css])
df = px.data.tips()
app.layout = dbc.Container(
[
dcc.Dropdown(
id="values",
value="total_bill",
options=[{"value": x, "label": x} for x in ["total_bill", "tip", "size"]],
clearable=False,
),
dcc.Graph(id="pie-chart"),
],
fluid=True,
className="dbc",
)
@app.callback(Output("pie-chart", "figure"), Input("values", "value"))
def generate_chart(value):
fig = px.pie(df, values=value, names="day", template="cyborg")
return fig
if __name__ == "__main__":
app.run_server(debug=True)
You can see the dropdown is now dark. So now when you change the theme, the dropdown is also automatically styled with the Bootstrap theme.
OK, so finally, let’s add the theme switch component. The cool thing about the theme switch components is that it automatically loads the figure templates for you, so you can skip that step from the apps above.
Here’s the app using the ThemeSwitchAIO
component from the dash-bootstrap-templates library:
from dash import Dash, dcc, Input, Output
import plotly.express as px
import dash_bootstrap_components as dbc
from dash_bootstrap_templates import ThemeSwitchAIO
dbc_css = (
"https://cdn.jsdelivr.net/gh/AnnMarieW/dash-bootstrap-templates@V1.0.4/dbc.min.css"
)
app = Dash(__name__, external_stylesheets=[dbc.themes.MINTY, dbc_css])
df = px.data.tips()
app.layout = dbc.Container(
[
ThemeSwitchAIO(aio_id="theme", themes=[dbc.themes.MINTY, dbc.themes.CYBORG]),
dcc.Dropdown(
id="values",
value="total_bill",
options=[{"value": x, "label": x} for x in ["total_bill", "tip", "size"]],
clearable=False,
),
dcc.Graph(id="pie-chart"),
],
fluid=True,
className="dbc",
)
@app.callback(
Output("pie-chart", "figure"),
Input("values", "value"),
Input(ThemeSwitchAIO.ids.switch("theme"), "value"),
)
def generate_chart(value, toggle):
template = "minty" if toggle else "cyborg"
fig = px.pie(df, values=value, names="day", template=template)
return fig
if __name__ == "__main__":
app.run_server(debug=True)
I hope that helps - let me know if you have other questions