簡體   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