使用 Plotly 在手动生成的子图中添加 "facet_row labels"
Add "facet_row labels" in manually produced subplots with Plotly
考虑一个带有子图的图形,for example 像这样:
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()
我们得到这个
如何以与 plotly.express
相同的方式添加(手动)标签:
如果您检查 plotly express 示例中的 fig.layout
,您会发现这些文本是 annotations。
所以你可以做的是对每条轨迹使用 add_annotation
。
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()
在上面的示例中,图例向右移动了一些,因此它没有覆盖注释。
要缩短代码,您可以将跟踪放在一个列表中并循环遍历它。对于每次迭代,您可以添加跟踪和注释,其中每个注释的 x 和 y 位置是相对于行(和列)的。
你的问题不是很清楚。您问的是标记由 go.Scatter()
条线组成的手动生成的子图。然后您请求使用 go.Histogram2d
和 Plotly Express 但 不是 fig.add_annotations()
的解决方案。对我来说,听起来你可以问四个截然不同的问题。不过,对我来说,您似乎更愿意使用 px.density_hetmap()
来生成类似于 go.Histogram2d
的图。然后这一切都归结为拥有正确的数据结构并指定正确的 facet_row labels
.
下面是 example 使用数据集``px.data.tips 生成此图:
如果我的假设是正确的,那么这正是您的目标。
完整代码:
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()
编辑:每一行可以有不同的 y-binning 吗?
是的,我想是的。当然有点取决于你的意思。但是您可以通过以下方式自由定义所有轴的分箱:
fig.data[n].update(xbins = {'end': 155, 'size': 5, 'start': 0}, ybins = {'end': 11, 'size': 1, 'start': 0})
其中 n 在这种情况下是 [0,3]
中的一个元素,对应于子图的数量。您还必须指定:
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})
情节 2:
情节 2 的完整代码:
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()
考虑一个带有子图的图形,for example 像这样:
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()
我们得到这个
如何以与 plotly.express
相同的方式添加(手动)标签:
如果您检查 plotly express 示例中的 fig.layout
,您会发现这些文本是 annotations。
所以你可以做的是对每条轨迹使用 add_annotation
。
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()
在上面的示例中,图例向右移动了一些,因此它没有覆盖注释。
要缩短代码,您可以将跟踪放在一个列表中并循环遍历它。对于每次迭代,您可以添加跟踪和注释,其中每个注释的 x 和 y 位置是相对于行(和列)的。
你的问题不是很清楚。您问的是标记由 go.Scatter()
条线组成的手动生成的子图。然后您请求使用 go.Histogram2d
和 Plotly Express 但 不是 fig.add_annotations()
的解决方案。对我来说,听起来你可以问四个截然不同的问题。不过,对我来说,您似乎更愿意使用 px.density_hetmap()
来生成类似于 go.Histogram2d
的图。然后这一切都归结为拥有正确的数据结构并指定正确的 facet_row labels
.
下面是 example 使用数据集``px.data.tips 生成此图:
如果我的假设是正确的,那么这正是您的目标。
完整代码:
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()
编辑:每一行可以有不同的 y-binning 吗?
是的,我想是的。当然有点取决于你的意思。但是您可以通过以下方式自由定义所有轴的分箱:
fig.data[n].update(xbins = {'end': 155, 'size': 5, 'start': 0}, ybins = {'end': 11, 'size': 1, 'start': 0})
其中 n 在这种情况下是 [0,3]
中的一个元素,对应于子图的数量。您还必须指定:
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})
情节 2:
情节 2 的完整代码:
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()