我正在尝试使用Ploly将分组箱图绘制为网格,其中包含来自数据帧的数据。例如,如果我们有一个数据框,
import plotly.express as px
df = px.data.tips()
total_bill tip sex smoker day time size
0 16.99 1.01 Female No Sun Dinner 2
1 10.34 1.66 Male No Sun Dinner 3
2 21.01 3.50 Male No Sun Dinner 3
3 23.68 3.31 Male No Sun Dinner 2
4 24.59 3.61 Female No Sun Dinner 4
我可以画一个图如下(例如:日=星期五):
import plotly.graph_objects as go
import plotly.express as px
df_plot=df[df['day']== 'Fri']
fig = px.box(df_plot, x='time', y="total_bill", color="sex",width=600, height=400)
fig.show()
如果我想绘制多个次要情节,例如,每天一个,我不确定如何在情节中做到这一点。这是我尝试的:
fig = make_subplots(rows=2, cols=2)
for v in range(4):
for i, met in enumerate(df['day'].unique()): #'Sun', 'Sat', 'Thur', 'Fri'
df_plot=df[df['day']== met]
for t in px.box(df_plot, x="time", y=f"total_bill", color='sex').data:
fig.add_trace(t, row=(v//2)+1, col=(v%2)+1)
fig.update_layout(
boxmode="group", margin={"l": 0, "r": 0, "t": 20, "b": 0}
).update_traces(showlegend=True)
这给出了一个看起来很奇怪的情节。我做错了什么?此外,在带有情节的子情节网格中,我如何为每个情节绘制一个图例而不是图例。
您已经收到了一个似乎产生所需结果的答案。但是由于您似乎急于知道如何使用指定的设置来做到这一点,我想向您展示如何做到这一点。我还确保下面的完整片段也处理了图例。
你最初设置的问题似乎源于图。add_trace(t, row=(v//2)1,col2=(v%2)1)
。你的图变得奇怪的原因是在px.box中为t生成的痕迹(df_plot,x="time",y=f"total_bill",颜色='sex').data:
没有正确地向子图索引。(v//2)1
看起来不错,但是col1=(v%2)1)
有点问题。这里你需要的是一个在1和2
之间改变的索引。在下面的片段中,你可以看到我已经使用以下方法解决了这个问题:
from itertools import cycle
cols = cycle([1,2])
c = next(cols)
这可能不是最有效的方法,但我一直在其他挑战中使用它,在这种情况下它也很有用。如果你打印出c
,你会看到你得到:[1,1,2,2,1,1,1,2,2]
。这正是你需要确保第一个子图的两个第一个跟踪最终在子图1
中的row=1
和col1=1
,依此类推。
关于你关于传说的第二个问题,这是通过以下方式处理的:
fig.add_trace(t.update(showlegend=True if i == 0 else False), row=r, col=c)
import plotly.express as px
from plotly.subplots import make_subplots
from itertools import cycle
df = px.data.tips()
fig = make_subplots(rows=2, cols=2, subplot_titles = df['day'].unique())
cols = cycle([1,2])
for i, met in enumerate(df['day'].unique()): #'Sun', 'Sat', 'Thur', 'Fri'
df_plot=df[df['day']== met].sort_values(['time', 'sex'], ascending = False)
c = next(cols)
for t in px.box(df_plot, x="time", y="total_bill", color='sex').data:
r = (i//2)+1
# print(c)
fig.add_trace(t.update(showlegend=True if i == 0 else False), row=r, col=c)
fig.update_layout(
boxmode="group", margin={"l": 0, "r": 0, "t": 20, "b": 0}
)#.update_traces(showlegend=True)
fig.show()
如果您想在此设置中添加任何内容,例如y轴标题,只需添加:
titles = cycle(df['day'].unique())
fig.for_each_yaxis(lambda y: y.update(title = next(titles)))
或者如果我误解了你,你只是想将total_bill
添加到yax中,只需使用:
fig.update_yaxes(title = 'total_bill')
import plotly.express as px
df = px.data.tips()
df.loc[df["day"].eq("Sun")]
px.box(df.loc[df["day"].eq("Sun")], x='time', y="total_bill", color="sex",width=600, height=400).show()
px.box(df, x='time', y="total_bill", color="sex", facet_col="day", facet_col_wrap=2, width=600, height=400).show()