How to Get All Plotly Themes in Streamlit
You can get around Streamlit’s restrictions and use all of the built-in themes for Plotly with a simple Streamlit component

Plotly themes are normally specified when creating a plot (e.g. template=plotly_dark
) but unfortunately, in Streamlit, this theme information gets overwritten when the chart is drawn.
Streamlit only supports the use of two themes and these are specified as an argument to the st.plotly_chart()
function. The default is Streamlit’s own theme but you can use the normal Plotly theme, too.
What can you do if you want to be different?
Answer: use a different function!
We are going to see just how easy it is to create a new function that uses a Streamlit component and which will plot your charts using any of the themes built into Plotly.
The image above is a Streamlit app that demonstrates 6 of the built-in Plotly themes that we will use. Here is a closer look at plotly_dark:

Streamlit components
Streamlit components come in two flavours: static components, which are blocks of HTML that are inserted into the Streamlit app and bi-directional components that allow values to be returned to the Streamlit app.
A dynamic component might be a user control such as a radio button or menu where the user selects a value to pass back to the program.
A static component could display text in some fancy way. Or, it could be a way of passing data to a chart library — like Plotly — and drawing a chart in HTML.
So, we are going to create a Streamlit component that will take a Plotly figure created in Python, using any theme or other feature provided by Plotly, draw it in HTML and insert it into our Streamlit app. No two-way communication is required, so a static component is fine.
Plotly in HTML/Javascript
It is very simple to draw a chart on an HTML page using Plotly. First, you need to include the Plotly Javascript library:
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>
And then you call newPlot()
from the library something like this:
Plotly.newPlot("chart", figure);
In the code above the string chart
refers to an HTML container for the chart and the argument figure
is a definition of the chart in JSON. newPlot()
is the Plotly function that creates the chart.
A complete segment of HTML would look like this:
<div id="chart"></div>
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>
<script type='text/javascript'>
var figure = JSON.parse(JSON_code_for_the_chart);
Plotly.newPlot("chart", figure);
</script>
And that is the basis for our Streamlit component.
A Plotly component
A static component is, as mentioned, a block of HTML that will be inserted into the Streamlit app. Our component will look much like the code above but we need to provide it with the JSON definition of the chart to be displayed.
We do this by generating the Plotly chart in the normal way, e.g.
fig = px.scatter(...)
And then converting fig
into JSON using the Plotly encoder function, like this:
graphJSON = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
We can now pass the JSON data into a component so that it will draw a chart in HTML. The component syntax is simple:
components.html(f"""
HTML code goes here
""",
height=height, width=width)
The HTML code will be written into an iframe that will be inserted into the Streamlit app.
The height and width arguments are optional but we shall use them to ensure that the iframe is the correct size for the image and that the image is not cropped.
Here is all of the code we have discussed combined into a function. We’ll save this as a module so that we can use it in different programs. I’ve called the module plotly_chart.py
import streamlit.components.v1 as components
import json
import plotly
def plotly_chart(fig):
graphJSON = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
components.html(f"""
<div id="chart"></div>
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>
<script type='text/javascript'>
var figure = JSON.parse('{graphJSON}');
Plotly.newPlot("chart", figure);
</script>
""",
height=fig.layout.height, width=fig.layout.width)
Listing 1: plotly_chart.py, a module containing the Streamlit component
The dimensions of the iframe are set to be the same as those of the figure by using its layout attributes.
Testing, testing…
Below we have a test program that imports plotly_chart
as pc
and invokes the new function to draw a set of charts with different Plotly themes.
The code uses the Gapminder data that is bundled with Plotly and is based on a demonstration from the Plotly documentation. Note that we have set the height and width of the figure. We must do this so that these dimensions can be read by the plot function.
import streamlit as st
import pandas as pd
import plotly.express as px
import plotly_chart as pc
st.title("Plotly themes in Streamlit")
df = px.data.gapminder()
df_2007 = df.query("year==2007")
templates = ["plotly", "plotly_white", "plotly_dark",
"ggplot2", "seaborn", "simple_white", "none"]
for template in templates:
fig = px.scatter(df_2007,
x="gdpPercap", y="lifeExp",
size="pop", color="continent",
log_x=True, size_max=60,
template=template,
title=f"Gapminder 2007: {template} theme",
width=600, height=400,)
pc.plotly_chart(fig)
Listing 2: a text program — part of this code is adapted from the Plotly template and theme documentation
And that’s about it!
As far as I can see there is no downside to using this technique to draw Plotly charts and it is more flexible than the native Streamlit function. (If you come across a problem, please let me know.)
As ever, thanks for reading. You can find more Streamlit resources on my Streamlit from Scratch website (see below) and subscribe to the Streamlit from Scratch newsletter to get updates and news about Streamlit.