使用Plotly绘制子图时如何添加自定义误差棒(置信区间)
问题原因
使用facet_row和color参数后,Plotly Express会自动将原始数据按规则拆分为多个独立trace(本案例中会生成4个trace:foo分组下color为0、1各一个,bar分组下color为0、1各一个),每个trace仅包含对应分组的子集数据。原代码用update_traces给所有trace统一传入了整个DataFrame的全量误差数组,长度和每个trace的实际数据长度不匹配,最终导致误差值错位。
解决方案1:直接在Plotly Express接口内指定误差参数(最简便)
Plotly Express原生支持非对称误差传入,不需要后续统一更新trace,接口会自动按分组匹配对应误差值,不会出现错位问题:
import pandas as pd import plotly.express as px df = pd.DataFrame( {"x": [0, 1, 2, 3, 0, 1, 2, 3], "y": [6, 10, 2, 5, 8, 9, 10, 11], "ci_upper": [8, 11, 2.5, 4, 9, 10, 11, 12], "ci_lower": [5, 9, 1.5, 3, 7, 6, 5, 10], "state": ['foo','foo','foo','foo','bar','bar','bar','bar'], "color": ['0','0','1','1','0','0','1','1']} ) # 预计算上下误差偏移量 df["error_up"] = df["ci_upper"] - df["y"] df["error_down"] = df["y"] - df["ci_lower"] fig = px.bar( df, x="x", y="y", facet_row='state', color='color', error_y="error_up", error_y_minus="error_down" ) fig.update_yaxes(dtick=1) fig.show()
解决方案2:遍历trace单独更新误差(适合动态修改场景)
如果已经生成了图表需要调整误差,可以遍历每个trace,为其匹配对应分组的误差数据:
import pandas as pd import plotly.express as px df = pd.DataFrame( {"x": [0, 1, 2, 3, 0, 1, 2, 3], "y": [6, 10, 2, 5, 8, 9, 10, 11], "ci_upper": [8, 11, 2.5, 4, 9, 10, 11, 12], "ci_lower": [5, 9, 1.5, 3, 7, 6, 5, 10], "state": ['foo','foo','foo','foo','bar','bar','bar','bar'], "color": ['0','0','1','1','0','0','1','1']} ) fig = px.bar(df, x="x", y="y",facet_row='state',color='color') # 遍历每个trace单独设置对应分组的误差 for trace in fig.data: color_val, state_val = [i.strip() for i in trace.legendgroup.split(',')] sub_df = df[(df['color'] == color_val) & (df['state'] == state_val)].sort_values('x') trace.error_y = { "type": "data", "symmetric": False, "array": sub_df["ci_upper"] - sub_df["y"], "arrayminus": sub_df["y"] - sub_df["ci_lower"], } fig.update_yaxes(dtick=1) fig.show()
两种方案都可以让第二行第三个柱子的置信区间正确覆盖5到11的区间。
内容的提问来源于stack exchange,提问作者Johannes Wiesner
相关产品推荐
相关产品推荐

