
Combining Plotly Charts
Intro
I get a lot of questions about building and assembling Plotly charts, and I wanted to include a few Python-only examples below.
Other libraries:
I don’t use Plotly exclusively, but I do use it a lot. I also use bokeh, seaborn, and, less frequently, altair/vega.
Combining Charts with Plotly
Plotly provides two APIs, the simple plotly.express and more comprehensive graph_objects
plotly.express is ultimately the same as graph_objects; it’s just a much simpler interface that does much of what you’ll need.
In most cases, we’ll build chart(s) in plotly.express and then fine-tune or merge them in graph_objects. A few reasons:
- Aligning the X axis: separate px figures may end up with unaligned X axes, making things look visually weird.
- Tiling: Sometimes, you might want to show a grid of charts rather than a single chart
- Overlay two chart elements, such as a line and a bar chart.
- Using secondary_y axes: a different Y axis for specific series
plotly_combining.ipynb
Import Required Libraries¶
import plotly.express as px
import pandas as pd
from plotly.subplots import make_subplots
import plotly.io as pio
pio.renderers.default = "plotly_mimetype+notebook"
pio.templates["iqmo"] = pio.templates["plotly"]
pio.templates["iqmo"].layout.margin = dict(l=50, r=50, t=50, b=50)
pio.templates["iqmo"].layout.height = 250
pio.templates.default = "iqmo"
# Create a DataFrame for the Tests
df = pd.DataFrame({"A": range(100), "B": range(1000, 1100), "C": range(-100, 0)})
Starting Point¶
Let's say you have two charts that you want to combine: fig1 and fig2
fig1 = px.line(df, x="A", y="B")
fig2 = px.bar(df, x="A", y="C")
display(fig1)
display(fig2)
The Easy Way?¶
Make them all the same type, a line or bar
fig1 = px.bar(df, x="A", y=["B", "C"])
fig1
Or, Combine into One Figure¶
fig1 = px.line(df, x="A", y="B")
fig2 = px.bar(df, x="A", y="C")
fig1.add_traces(fig2.data)
display(fig1)
Add a Legend¶
Plotly doesn't show the legend for single data series, so we need to give the series names.
fig1 = px.line(df, x="A", y="B")
fig2 = px.bar(df, x="A", y="C")
fig1.data[0].name = "Line Plot"
fig1.data[0].showlegend = True
fig2.data[0].name = "Bar Chart"
fig2.data[0].showlegend = True
fig1.add_traces(fig2.data)
display(fig1)
Or, Show with Different Y Axes (left and right)¶
sfig1 = px.line(df, x="A", y="B")
sfig2 = px.bar(df, x="A", y="C")
sfig1.data[0].name = "Line Plot"
sfig1.data[0].showlegend = True
sfig2.data[0].name = "Bar Chart"
sfig2.data[0].showlegend = True
fig = make_subplots(rows=1, cols=1, specs=[[{"secondary_y": True}]])
fig.add_traces(sfig1.data)
fig.add_traces(sfig2.data, secondary_ys=[True])
display(fig)
Or, show as two separate subplots¶
With a shared X axes
fig1 = px.line(df, x="A", y="B")
fig2 = px.bar(df, x="A", y="C")
fig = make_subplots(
rows=2,
cols=1,
shared_xaxes=True,
subplot_titles=("Top", "Bottom"),
row_heights=[0.8, 0.2],
)
fig.add_traces(fig1.data, rows=[1], cols=[1])
fig.add_traces(fig2.data, rows=[2], cols=[1])
fig
Bonus: Show different labels in place of X Axis Ticks¶
df["A_labels"] = df["A"].astype(str) + " Some text"
df = df.head(10)
fig1 = px.line(df, x="A", y="B")
fig1.update_xaxes(tickvals=df["A"], ticktext=df["A_labels"])
fig1