使用 plotly 子图时绘制自定义误差线

Drawing custom error bars when using plotly subplots

这个问题与密切相关。我想使用数据框中两列的信息描述每个置信区间的上限和下限,为图形的子图中的每个条形图绘制置信区间。我尝试使用之前 post 的解决方案,但当有人想使用不同的颜色 and/or 不同的行来绘制图中的子图时,它似乎并不适用。

例如,以下代码不会生成正确的置信区间。例如,第二行第 3 个柱的 CI 应该从 11 变为 5:

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').update_traces(
    error_y={
        "type": "data",
        "symmetric": False,
        "array": df["ci_upper"] - df["y"],
        "arrayminus": df["y"] - df["ci_lower"],
    }
)


fig.update_yaxes(dtick=1)
fig.show(renderer='png')

  • 这是相同的技术,但解决方案需要考虑它的多条轨迹(本例中为 4 条)
  • 在每个轨迹的 hovertemplate 中编码的是 facetcolor。提取这些并将数据过滤到适当的行
  • 然后像更简单的条件一样为误差条构建指令
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")
fig.update_yaxes(dtick=1)

def error_facet(t):
    # filter data frame based on contents of hovertemplate
    d = df.query(
        " and ".join(
            [
                f"{q.split('=')[0]}==\"{q.split('=')[1]}\""
                for q in t.hovertemplate.split("<br>")[0:2]
            ]
        )
    )
    t.update(
        {
            "error_y": {
                "type": "data",
                "symmetric": False,
                "array": d["ci_upper"] - d["y"],
                "arrayminus": d["y"] - d["ci_lower"],
            }
        }
    )
fig.for_each_trace(error_facet)


fig