[英]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.