繁体   English   中英

如何在 matplotlib 条形图上注释错误值

[英]How to annotate error values on matplotlib bar plot

我有以下问题:

我想用条形高度(y 值)和错误线高度(错误值)注释我的条形图 -它有标准错误线

我找到了这个链接来注释条形图Annotate bars with values on Pandas bar plots 建议的策略迭代 Axes Patches 并获取补丁高度以检索 y 值,但我没有找到任何可以提取错误值的内容。

我想获得以下结果:

我的目标

下面,考虑到非对称 yerrors,我重新设计了bar_label以执行类似于您所要求的操作。

编辑代码末尾的'%d[%d,%d]' % (value,err[0,1],err[1,1])以显示您想要的任何格式的错误。 即,使用'%.2f$\\pm$%.2f' % (value,err[0,1])来显示对称错误。 通过调整 err 矩阵索引,也可以轻松地考虑 xerrors。

import itertools
def bar_label(container, labels=None, *, fmt="%g", label_type="edge",
              padding=0, **kwargs):

    # want to know whether to put label on positive or negative direction
    # cannot use np.sign here because it will return 0 if x == 0
    def sign(x):
        return 1 if x >= 0 else -1

    bars = container.patches
    errorbar = container.errorbar
    datavalues = container.datavalues
    orientation = container.orientation

    if errorbar:
        # check "ErrorbarContainer" for the definition of these elements
        lines = errorbar.lines  # attribute of "ErrorbarContainer" (tuple)
        barlinecols = lines[2]  # 0: data_line, 1: caplines, 2: barlinecols
        barlinecol = barlinecols[0]  # the "LineCollection" of error bars
        errs = barlinecol.get_segments()
    else:
        errs = []

    if labels is None:
        labels = []

    annotations = []

    for bar, err, dat, lbl in itertools.zip_longest(
        bars, errs, datavalues, labels
    ):
        (x0, y0), (x1, y1) = bar.get_bbox().get_points()
        xc, yc = (x0 + x1) / 2, (y0 + y1) / 2

        if orientation == "vertical":
            extrema = max(y0, y1) if dat >= 0 else min(y0, y1)
            length = abs(y0 - y1)
        elif orientation == "horizontal":
            extrema = max(x0, x1) if dat >= 0 else min(x0, x1)
            length = abs(x0 - x1)

        if err is None:
            endpt = extrema
        elif orientation == "vertical":
            endpt = err[:, 1].max() if dat >= 0 else err[:, 1].min()
        elif orientation == "horizontal":
            endpt = err[:, 0].max() if dat >= 0 else err[:, 0].min()

        if label_type == "center":
            value = sign(dat) * length
        elif label_type == "edge":
            value = extrema

        if label_type == "center":
            xy = xc, yc
        elif label_type == "edge" and orientation == "vertical":
            xy = xc, endpt
        elif label_type == "edge" and orientation == "horizontal":
            xy = endpt, yc

        if orientation == "vertical":
            xytext = 0, sign(dat) * padding
        else:
            xytext = sign(dat) * padding, 0

        if label_type == "center":
            ha, va = "center", "center"
        elif label_type == "edge":
            if orientation == "vertical":
                ha = 'center'
                va = 'top' if dat < 0 else 'bottom'  # also handles NaN
            elif orientation == "horizontal":
                ha = 'right' if dat < 0 else 'left'  # also handles NaN
                va = 'center'

        if np.isnan(dat):
            lbl = ''

        annotation = plt.annotate('%d[%d,%d]' % (value,err[0,1],err[1,1]), #fmt % value if lbl is None else lbl,
                                  xy, xytext, textcoords="offset points",
                                  ha=ha, va=va, **kwargs)
        annotations.append(annotation)

    return annotations

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM