python - 更改绘图箱线图悬停数据
问题描述
我想更改 python plotly boxplot 的悬停文本和悬停数据。我想要一个用于中位数、平均值、IQR 和日期的浓缩悬停框,而不是 5 个单独的悬停框用于最大值、q3、中值、q1 和最小值。我玩弄了每个“悬停”变量,但没有运气。我的示例代码如下所示。
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()
在这种情况下,我尝试使用“hover_data”,它不会引发错误,但也不会改变绘图,如上所示。我试过 express 和 graph_objects 都没有运气。我的情节版本是 4.9.0。谢谢!
解决方案
- 使用了在箱线图迹线上覆盖条形迹线的技术
- 可以配置条形跟踪以显示您想要的信息
- 为了演示,我设置了不透明度,
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)
推荐阅读
- javascript - beforeShowDay 不工作
- c++ - 引用 std::cout 导致段错误
- php - Json 到 php 数组(json_decode())不起作用
- jms - Weblogic JMS 桥 weblogic.transaction.RollbackException
- c - 避免暴露已编译 C 模块的细节
- c# - 我从 api 检索到的 json 有问题
- javascript - 遍历angularjs中的字符串化json数据返回未定义
- javascript - 我们可以在一个 node.js 中使用 app.use 两次吗
- html - 根据另一个 div 的子元素中的类隐藏 div 的子元素
- jsf - 在 JSF 页面的页面加载期间未调用 @PostConstruct