The below code creates stacked Plotly sub plots with a shared x axis.
I would like to add a horizontal scrollbar at the bottom.
from plotly.subplots import make_subplots
import plotly.graph_objects as go
fig = make_subplots(rows=3, cols=1,
shared_xaxes=True,
vertical_spacing=0.02)
fig.add_trace(go.Scatter(x=[0, 1, 2, 3], y=[10, 11, 12, 13]),
row=3, col=1)
fig.add_trace(go.Scatter(x=[0, 1, 2, 3], y=[100, 110, 120, 130]),
row=2, col=1)
fig.add_trace(go.Scatter(x=[0, 1, 2, 3], y=[1000, 1100, 1200, 1300]),
row=1, col=1)
fig.update_layout(height=500,xaxis=dict(rangeslider=dict(visible=True), type="linear"))
fig.show()
Unfortunately it's corrupting the first sub plot and overlaying the scrollbar over the middle plot.
How do I fix this?
The thing with make_subplots()
is that each subplot has its own x/y axes pair, even with shared_xaxes
enabled. In your situation for example, it only adds a matches
constraint on xaxis
and xaxis2
so that they always match the scale of xaxis3
. Also, only xaxis3
is rendered.
So you would need to add the rangeslider to xaxis3
instead of xaxis
in the layout so that it can be properly positioned and margins be pushed for it have enough room :
fig.update_layout(height=500, xaxis3=dict(rangeslider=dict(visible=True), type="linear"))
But there is still an issue due to having these 3 distinct x axes, the rangeslider only displays traces that share the same x axis, so it will only show the third trace here :
To obtain an overview of the three traces in the rangeslider window, you would
need to create the stacked subplots "manually", ie. without make_subplots()
: basically this amounts to specifying a yaxis
reference for each trace and define the corresponding domain
in the layout and that's it, adding the rangeslider to xaxis
will work fine now since all traces belong to it by default :
fig = go.Figure()
fig.add_trace(go.Scatter(x=[0, 1, 2, 3], y=[11, 10, 12, 13], yaxis='y'))
fig.add_trace(go.Scatter(x=[0, 1, 2, 3], y=[120, 110, 130, 100], yaxis='y2'))
fig.add_trace(go.Scatter(x=[0, 1, 2, 3], y=[1300, 1200, 1000, 1100], yaxis='y3'))
fig.update_layout(
height=600,
xaxis=dict(rangeslider=dict(visible=True)),
yaxis=dict(domain=[0, 0.32]),
yaxis2=dict(domain=[0.34, 0.66]),
yaxis3=dict(domain=[0.68, 1])
)
fig.show()
See also for reference : Range Slider with Vertically Stacked Subplots.