Black Lives Matter. Please consider donating to Black Girls Code today.
Dash HoloViews is now available! Check out the docs.

Can Subplot support multiple y-axes?


I would like to plot multiple graphs, one of the graph involves multiple y-axes. In the subplot point of view, what is the y-axis sequence? I tried many combination but the y-axis2 - y-axis4 are still missing.

Below is the sample code for reference:

import plotly.graph_objects as go

fig = go.Figure()
fig = make_subplots(
rows=1, cols=4,
specs=[[{“rowspan”: 1, “colspan”: 2}, None, {“rowspan”: 1, “colspan”: 2}, None]],
horizontal_spacing =0.1, vertical_spacing =0.09)

fig.add_trace(go.Scatter(x=[1, 2, 3], y=[2, 52, 62]), row=1, col=1)

fig.add_trace(go.Bar(x=[[‘A’, ‘A’, ‘A’], [1, 2, 3]], y=[4, 5, 60000], name=“yaxis1 data”, yaxis=“y2”), row=1, col=3)
fig.add_trace(go.Bar(x=[[‘B’, ‘B’, ‘B’], [2, 3, 4]], y=[40, 50, 60], name=“yaxis2 data”, yaxis=“y5”), row=1, col=3)
fig.add_trace(go.Bar(x=[[‘C’, ‘C’, ‘C’], [4, 5, 6]], y=[40000, 50000, 60000], name=“yaxis3 data”, yaxis=“y6”), row=1, col=3)
fig.add_trace(go.Bar(x=[[‘D’, ‘D’, ‘D’], [5, 6, 7]], y=[400000, 500000, 600000], name=“yaxis4 data”, yaxis=“y7”), row=1, col=3)

# Create axis objects

fig.update_layout(xaxis2=dict(domain=[0.6, 0.9]),
yaxis2=dict(title=“yaxis1 title”, titlefont=dict(color="#1f77b4"), tickfont=dict(color="#1f77b4")),
yaxis5=dict(title=“yaxis2 title”,titlefont=dict(color="#ff7f0e"),tickfont=dict(color="#ff7f0e"), anchor=“free”, overlaying=“y2”, side=“left”, position=0.5),
yaxis6=dict(title=“yaxis3 title”,titlefont=dict(color="#d62728"),tickfont=dict(color="#d62728"), anchor=“x2”,overlaying=“y2”, side=“right”),
yaxis7=dict(title=“yaxis4 title”,titlefont=dict(color="#9467bd"),tickfont=dict(color="#9467bd"), anchor=“free”,overlaying=“y2”, side=“right”,position=1))

fig.update_layout(width=1600, height=500)

Thanks for your advice.

Jason Tam

Hi, and thanks for using the forum!

I think that you might be able to take advantage of the shared_yaxes attribute of the make_subplots() function, which is documented at

from plotly.subplots import make_subplots
import plotly.graph_objects as go

fig = make_subplots(rows=2, cols=2, shared_yaxes=True)

fig.add_trace(go.Scatter(x=[1, 2, 3], y=[2, 3, 4]),
              row=1, col=1)

fig.add_trace(go.Scatter(x=[20, 30, 40], y=[5, 5, 5]),
              row=1, col=2)

fig.add_trace(go.Scatter(x=[2, 3, 4], y=[600, 700, 800]),
              row=2, col=1)

fig.add_trace(go.Scatter(x=[4000, 5000, 6000], y=[7000, 8000, 9000]),
              row=2, col=2)

fig.update_layout(height=600, width=600,
                  title_text="Multiple Subplots with Shared Y-Axes")

I hope this helps!

Hi @Jason.Tam

When you define a figure with make_subplots() it is recommended to display fig.layout to inspect the axes name for each subplot:
(see also my answer, Can Plotly support 2 x-axis and 2 y-axis in one graph?, to your question related to secondary yaxis):

fig = make_subplots(
          rows=1, cols=4,
          specs=[[{'rowspan': 1, 'colspan': 2}, None, {'rowspan': 1, 'colspan': 2}, None]],
          horizontal_spacing =0.1)


You’ll get:

    'template': '...',
    'xaxis': {'anchor': 'y', 'domain': [0.0, 0.45]},
    'xaxis2': {'anchor': 'y2', 'domain': [0.55, 1.0]},
    'yaxis': {'anchor': 'x', 'domain': [0.0, 1.0]},
    'yaxis2': {'anchor': 'x2', 'domain': [0.0, 1.0]}

When you add traces you don’t have to set xaxis or yaxis for each subplot. It is sufficient to give the row and col for that subplot because the axes
have been already assigned by make_subplots().

Hence in your next lines of code remove yaxis=‘y4’, ‘y5’, because they DO NOT EXIST in your subplots!!!

From now on, please, paste here on forum formatted code, because copying your code and pasting it in my notebook requires a lot of wrong character replacement.
Just check it!!!

Here are details on how to include a code block on this forum:

Hi @empet and @joseph.damiba,

Thanks for your advice.

Actually I would like to plot a multiple y-axes graph in subplot. I have checked many examples in subplot graphs, all examples in subplot graphs are related to secondary y-axes only, I am not sure whether subplot can support multiple y-axes like this-

Below is my sample code in subplot, I don’t know how to declare y-axis3, y-axis4 and y-axis5:

import plotly.graph_objects as go

fig = go.Figure()
fig = make_subplots(
    rows=1, cols=2,
    specs=[[{"rowspan": 1, "colspan": 1}, {"rowspan": 1, "colspan": 1}]],
    horizontal_spacing =0.1)

fig.add_trace(go.Scatter(x=[1, 2, 3], y=[2, 52, 62]), row=1, col=1)

fig.add_trace(go.Bar(x=[['A', 'A', 'A'], [1, 2, 3]], y=[4, 5, 6000], name="A"), row=1, col=2)
fig.add_trace(go.Bar(x=[['B', 'B', 'B'], [2, 3, 4]], y=[40, 50, 60], name="B"), row=1, col=2)
fig.add_trace(go.Bar(x=[['C', 'C', 'C'], [4, 5, 6]], y=[40000, 50000, 60000], name="C"), row=1, col=2)
fig.add_trace(go.Bar(x=[['D', 'D', 'D'], [5, 6, 7]], y=[400000, 500000, 600000], name="D"), row=1, col=2)

# # Create axis objects
fig.update_layout(xaxis2=dict(domain=[0.6, 0.9]),
    yaxis2=dict(title="yaxis1 title",titlefont=dict(color="red"), tickfont=dict(color="red")),
    yaxis3=dict(title="yaxis2 title",titlefont=dict(color="orange"),tickfont=dict(color="orange"), anchor="free", overlaying="y2", side="left", position=0.5),
    yaxis4=dict(title="yaxis3 title",titlefont=dict(color="pink"),tickfont=dict(color="pink"), anchor="x2",overlaying="y2", side="right"),
    yaxis5=dict(title="yaxis4 title",titlefont=dict(color="cyan"),tickfont=dict(color="cyan"), anchor="free",overlaying="y2", side="right",position=1))

fig.update_layout(width=1600, height=400)


1 Like


Yes, you can define such a subplot. Later I’ll post an example (approx 3 hours).

Without the posted image I couldn’t deduce from your question that you are referring to attaching more yaxes to the same plot window.

1 Like


make_subplots was not devised to define subplots that can be referenced to multiple left and right yaxes.
Hence such subplots can be defined only with a low level code.

This is the Jupyter Notebook that defines subplots of rows=1, cols>1:

and this one defines subplots of rows>1, cols=1:


Hi @empet,

Thanks for your solution.


1 Like

Thank you very much for the solution

1 Like