更改 Plotly 盒形图悬停数据

3
我想要更改Python Plotly箱线图的悬停文本和悬停数据。我希望将最大值、第三四分位数、中位数、第一四分位数和最小值的5个单独的悬停框替换为一个压缩的悬停框,其中包括中位数、平均数、IQR和日期。我已经尝试了每个“hover”变量,但没有成功。我的示例代码如下所示。
import numpy as np
import plotly.express as px

lst = [['2020'], ['2021']] 
numbers = [20 , 25]
r = [x for i, j in zip(lst, numbers) for x in i*j]

df = pd.DataFrame(r, columns=['year'])
df['obs'] = np.arange(1,len(df)+1) * np.random.random()

mean = df.groupby('year').mean()[['obs']]
median = df.groupby('year').median()[['obs']]
iqr = df.groupby('year').quantile(0.75)[['obs']] - df.groupby('year').quantile(0.25)[['obs']]

stats = pd.concat([mean,median,iqr], axis=1)
stats.columns = ['Mean','Median','IQR']
tot_df = pd.merge(df,stats, right_index=True, left_on='year', how = 'left')

fig = px.box(tot_df, x="year", y="obs", points=False, hover_data=['year','Mean','Median','IQR'])
fig.show()

enter image description here

在这种情况下,我尝试使用“hover_data”,它不会引发错误,但也不会改变上面显示的图形。 我已经尝试了express和graph_objects,但没有成功。我的plotly版本是4.9.0。谢谢!
1个回答

3
  • 使用了在箱线图上叠加柱状图的技术
  • 柱状图可以配置显示所需信息
  • 为了演示,我将透明度设置为0.05,可以将其设置为0使其完全不可见
  • 此代码基于plotly 5.2.1构建,未在4.9.0上进行测试
import numpy as np
import plotly.express as px
import pandas as pd

lst = [['2020'], ['2021']] 
numbers = [20 , 25]
r = [x for i, j in zip(lst, numbers) for x in i*j]

df = pd.DataFrame(r, columns=['year'])
df['obs'] = np.arange(1,len(df)+1) * np.random.random()

mean = df.groupby('year').mean()[['obs']]
median = df.groupby('year').median()[['obs']]
iqr = df.groupby('year').quantile(0.75)[['obs']] - df.groupby('year').quantile(0.25)[['obs']]

stats = pd.concat([mean,median,iqr], axis=1)
stats.columns = ['Mean','Median','IQR']
tot_df = pd.merge(df,stats, right_index=True, left_on='year', how = 'left')

fig = px.box(tot_df, x="year", y="obs", points=False)

fig2 = px.bar(
    tot_df.groupby("year", as_index=False)
    .agg(base=("obs", "min"), bar=("obs", lambda s: s.max() - s.min()))
    .merge(
        tot_df.groupby("year", as_index=False).agg(
            {c: "first" for c in tot_df.columns if c not in ["year", "obs"]}
        ),
        on="year",
    ),
    x="year",
    y="bar",
    base="base",
    hover_data={
        **{c: True for c in tot_df.columns if c not in ["year", "obs"]},
        **{"base": False, "bar": False},
    },
).update_traces(opacity=0.05)

fig.add_traces(fig2.data)

fig2没有使用命名聚合函数

在此输入图片描述

fig2 = px.bar(
    tot_df.groupby("year", as_index=False)["obs"]
    .apply(lambda s: pd.Series({"base": s.min(), "bar": s.max() - s.min()}))
    .merge(
        tot_df.groupby("year", as_index=False).agg(
            {c: "first" for c in tot_df.columns if c not in ["year", "obs"]}
        ),
        on="year",
    ),
    x="year",
    y="bar",
    base="base",
    hover_data={
        **{c: True for c in tot_df.columns if c not in ["year", "obs"]},
        **{"base": False, "bar": False},
    },
).update_traces(opacity=0.05)


我的pandas版本是0.24.2,因此,这个用于groupby的命名聚合实现不起作用。鉴于我不确定px.bar的第一个参数正在构建什么,你能否建议如何修改这个groupby语句以与pandas 0.24.2兼容?谢谢。 - undefined
这是Pandas的古老版本,名为“aggregations”,介绍了https://pandas-docs.github.io/pandas-docs-travis/whatsnew/v0.25.0.html在0.25中。我的环境无法降级到0.24.2,因为无法构建轮子。您能否将Pandas升级到不到2年的版本? - undefined
已更新答案,提供了另一种在不使用命名聚合的情况下构建图2的方法。我无法验证这是否适用于非常旧版本的pandas。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接