在图表上标记数据点

97
如果你想使用Python的Matplotlib来标记你的图表数据点,你可以使用以下代码。
from matplotlib import pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)

A = anyarray
B = anyotherarray

plt.plot(A,B)
for i,j in zip(A,B):
    ax.annotate('%s)' %j, xy=(i,j), xytext=(30,0), textcoords='offset points')
    ax.annotate('(%s,' %i, xy=(i,j))

plt.grid()
plt.show()

我知道xytext=(30,0)textcoords一起使用,你可以使用这些30,0的值来定位数据标签点,使其位于自己的小区域上的y=0x=30
你需要同时绘制ij两条线,否则只会绘制xy的数据标签。
你会得到类似下面这样的结果(注意只有标签):

My own plot with data points labeled

这不是理想的,还有一些重叠。

1
为什么不直接使用 ax.annotate('(%s, %s)' % (i, j), ...) 呢?(或者如果你正在使用新的字符串格式化方式,可以使用 '({}, {})'.format(i, j)。) - Joe Kington
1
请查看以下链接:https://matplotlib.org/users/annotations.html - ashley
pyplot.text似乎是annotate的一种替代方法:https://www.pythonmembers.club/2018/05/08/matplotlib-scatter-plot-annotate-set-text-at-label-each-point/ 不确定它是否有任何不同。 - 10762409
我是 pythonmembers.club 的维护者。作为一个初学者,这让我感到非常恼火。但那篇文章后来变得足够受欢迎,被包括在斯坦福大学的 NLP 课程中(这是一篇直接链接到该文章的大胆文章)。 - Abdur-Rahmaan Janhangeer
3个回答

122

一次性打印 (x, y) 怎么样。

from matplotlib import pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)

A = -0.75, -0.25, 0, 0.25, 0.5, 0.75, 1.0
B = 0.73, 0.97, 1.0, 0.97, 0.88, 0.73, 0.54

ax.plot(A,B)
for xy in zip(A, B):                                       # <--
    ax.annotate('(%s, %s)' % xy, xy=xy, textcoords='data') # <--

ax.grid()
plt.show()

输入图片描述


4
对于任何使用该代码的人,需要注意一点:textcoords='offset points' 在图表的比例尺度不同时会产生不同的效果(对我而言,大多数标签都显示在了图外)。 - Eric G
1
是的,你应该使用textcoords='data'。 - navari
@navari,谢谢你提供的信息。我已经相应地更新了答案。 - falsetru
@EricG - 我相信 textcoords='offset points' 也需要 xytext 参数。换句话说,为偏移设置 xytext=(x 点数,y 点数),然后 textcoords='offset points' 将按预期工作。 - DaveL17
一个小问题,你能只注释选择性的数据点吗?以上图为例,只注释那些x值大于等于0.25的点即可。 - Prasanta Bandyopadhyay
1
@PrasantaBandyopadhyay,使用if语句;根据x值有条件地进行注释。 - falsetru

10

我也有过类似的问题,最终找到了这个解决方法:

在此输入图片描述

使用这种方式有一个好处,即数据和注释不会重叠。

from matplotlib import pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(111)

A = -0.75, -0.25, 0, 0.25, 0.5, 0.75, 1.0
B = 0.73, 0.97, 1.0, 0.97, 0.88, 0.73, 0.54

plt.plot(A,B)

# annotations at the side (ordered by B values)
x0,x1=ax.get_xlim()
y0,y1=ax.get_ylim()
for ii, ind in enumerate(np.argsort(B)):
    x = A[ind]
    y = B[ind]
    xPos = x1 + .02 * (x1 - x0)
    yPos = y0 + ii * (y1 - y0)/(len(B) - 1)
    ax.annotate('',#label,
          xy=(x, y), xycoords='data',
          xytext=(xPos, yPos), textcoords='data',
          arrowprops=dict(
                          connectionstyle="arc3,rad=0.",
                          shrinkA=0, shrinkB=10,
                          arrowstyle= '-|>', ls= '-', linewidth=2
                          ),
          va='bottom', ha='left', zorder=19
          )
    ax.text(xPos + .01 * (x1 - x0), yPos,
            '({:.2f}, {:.2f})'.format(x,y),
            transform=ax.transData, va='center')

plt.grid()
plt.show()
.annotate中使用text参数会导致文本位置不利。 在图例和数据点之间绘制线条很麻烦,因为图例的位置很难处理。

1
如果不需要箭头,text()也可以用来标记点。
import matplotlib.pyplot as plt

A = [-0.75, -0.25, 0, 0.25, 0.5, 0.75, 1.0]
B = [0.73, 0.97, 1.0, 0.97, 0.88, 0.73, 0.54]

fig, ax = plt.subplots()
ax.plot(A,B)

for x, y in zip(A, B):
    ax.text(x, y, f"({x}, {y})", fontsize=8)

plot1


您还可以通过有条件地注释点来注释一些点或更改标签相对于点的位置。此外,您可以分配任意标签。

例如,以下代码在点的左侧绘制标签,如果x>0则在右侧绘制标签。此外,annotate()允许使用其他kwargs来美化标签。

A = -0.75, -0.25, 0, 0.25, 0.5, 0.75, 1.0
B = 0.73, 0.97, 1.0, 0.97, 0.88, 0.73, 0.54
labels = 'ABCDEFG'

fig, ax = plt.subplots()
ax.plot(A,B)

# annotator function that draws a label and an arrow 
# that points from the label to its corresponding point
def annotate(ax, label, x, y, xytext):
    ax.annotate(label, xy=(x,y), 
                xytext=xytext, textcoords='offset points', 
                fontsize=15, 
                arrowprops={'arrowstyle': '-|>', 'color': 'black'})

# conditionally position labels
for label, x, y in zip(labels, A, B):
    if y > 0.9:
        annotate(ax, label, x, y, (-5, -40))
    else:
        annotate(ax, label, x, y, (-5, 30))

plot2


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接