Reputation: 3115
Consider a figure with subplots, for example like this:
from plotly.subplots import make_subplots
import plotly.graph_objects as go
fig = make_subplots(rows=3, cols=1)
fig.append_trace(go.Scatter(
x=[3, 4, 5],
y=[1000, 1100, 1200],
), row=1, col=1)
fig.append_trace(go.Scatter(
x=[2, 3, 4],
y=[100, 110, 120],
), row=2, col=1)
fig.append_trace(go.Scatter(
x=[0, 1, 2],
y=[10, 11, 12]
), row=3, col=1)
fig.update_layout(height=600, width=600, title_text="Stacked Subplots")
fig.show()
and we obtain this
How do I add (manually) labels in the same way as plotly.express
would place here:
Upvotes: 1
Views: 2717
Reputation: 61164
Your question is not very clear. You're asking about labelling manually produced subplots consisting of go.Scatter()
traces. And then you're requestion a solution using go.Histogram2d
and Plotly Express but not fig.add_annotations()
. To me, it sounds like you could have asked four very different questions. Still, to me it seems like you'd like to use px.density_hetmap()
which will produce plots similar to go.Histogram2d
. And then it all boils down to having the correct data structure and specifying the right facet_row labels
.
Below is an example using the dataset ``px.data.tips to produce this plot:
And if my assumptions are right, this hould be exactly what you're aiming to do.
import plotly.express as px
df = px.data.tips()
fig = px.density_heatmap(df, x="total_bill", y="tip", facet_row="sex", facet_col="smoker")
fig.show()
Yes, I think so. Of course depending a bit on what you mean. But you can freely define the binnings of all axes through:
fig.data[n].update(xbins = {'end': 155, 'size': 5, 'start': 0}, ybins = {'end': 11, 'size': 1, 'start': 0})
Where n in this case is an element in [0,3]
and corresponds to the number of subplots. You will also have to specify:
fig.update_xaxes(matches=None)
fig.update_yaxes(matches=None)
Or you'll get some very funky results.
Compare the following plot and corresponding code snippet with those above to see an example with:
fig.data[3].update(xbins = {'end': 75, 'size': 5, 'start': 0}, ybins = {'end': 25, 'size': 1, 'start': 0})
import plotly.express as px
df = px.data.tips()
fig = px.density_heatmap(df, x="total_bill", y="tip", facet_row="sex", facet_col="smoker")
fig.update_xaxes(matches=None)
fig.update_yaxes(matches=None)
fig.data[3].update(xbins = {'end': 75, 'size': 5, 'start': 0}, ybins = {'end': 25, 'size': 1, 'start': 0})
fig.for_each_yaxis(lambda yax: yax.update(showticklabels = True))
fig.show()
Upvotes: 1
Reputation: 15462
If you inspect the fig.layout
in the plotly express example you can see that these texts are annotations.
So what you could do is use add_annotation
for each trace.
from plotly.subplots import make_subplots
import plotly.graph_objects as go
fig = make_subplots(rows=3, cols=1)
fig.append_trace(go.Scatter(x=[3, 4, 5], y=[1000, 1100, 1200]), row=1, col=1)
fig.append_trace(go.Scatter(x=[2, 3, 4], y=[100, 110, 120]), row=2, col=1)
fig.append_trace(go.Scatter(x=[0, 1, 2], y=[10, 11, 12]), row=3, col=1)
fig.add_annotation(
showarrow=False,
text="smoker=Yes",
textangle=90,
x=1,
xanchor='left',
xref="paper",
y=0.875,
yanchor='middle',
yref="paper",
)
fig.add_annotation(
showarrow=False,
text="smoker=No",
textangle=90,
x=1,
xanchor='left',
xref="paper",
y=0.5,
yanchor='middle',
yref="paper",
)
fig.add_annotation(
showarrow=False,
text="smoker=Maybe",
textangle=90,
x=1,
xanchor='left',
xref="paper",
y=0.125,
yanchor='middle',
yref="paper",
)
fig.update_layout(
height=600,
width=600,
title_text="Stacked Subplots",
legend=dict(yanchor="top", y=1, xanchor="right", x=1.3)
)
fig.show()
In the example above the legend is moved somewhat to the right so it doesn't cover the annotations.
To shorten the code you could put the traces in a list and loop through it. For each iteration you could add the trace and the annotation where the x and y position of each annotation are relative to the row (and column).
Upvotes: 1