matplotlib:如何在自动放置的散点箭头上注释点?

2024-05-16 16:11:48 发布

您现在位置:Python中文网/ 问答频道 /正文

如果使用matplotlib绘制散点图:

plt.scatter(randn(100),randn(100))
# set x, y lims
plt.xlim([...])
plt.ylim([...])

我想用一个箭头和一个标签来注释一个给定的点(x, y)。我知道这可以通过annotate来实现,但我希望箭头及其标签以“最佳”的方式放置,以便在可能的情况下(给定当前轴比例/限制),箭头和标签不会与其他点重叠。如果你想标记一个异常点。有办法吗?它不一定非得是完美的,但只要给定要标记的点的(x,y)坐标,就可以智能地放置箭头/标签。谢谢。


Tags: 标记matplotlib方式绘制情况plt标签箭头
2条回答

使用adjustText(完全公开,我写的)。

我们把前10个点标出来。我唯一改变的参数是降低对这些点的排斥力,因为它们太多了,我们希望算法花费更多的时间,更仔细地放置注释。

import numpy as np
import matplotlib.pyplot as plt
from adjustText import adjust_text
np.random.seed(1)
x, y = np.random.random((2,500))

fig, ax = plt.subplots()
ax.plot(x, y, 'bo')
ts = []
for i in range(10):
    ts.append(plt.text(x[i], y[i], 'Something'+str(i)))
adjust_text(ts, x=x, y=y, force_points=0.1, arrowprops=dict(arrowstyle='->', 
color='red'))
plt.show()

enter image description here 这并不理想,但这里的点非常密集,有时无法将文本放在靠近目标的位置而不重叠其中任何一个。但它是全自动的,易于使用,也不让标签相互重叠。

聚苯乙烯 它使用了边界框交叉点,但我认为它相当成功!

基本上,没有

处理放置类似地图标签的布局引擎异常复杂,超出了matplotlib的范围。(边界框交点实际上是决定标签放置位置的一种相当糟糕的方法。为1000种情况中只有一种情况有效的东西编写大量代码有什么意义

除此之外,由于matplotlib所做的复杂文本呈现量(例如乳胶),如果不首先完全呈现文本,则无法确定文本的范围(这相当慢)。

但是,在许多情况下,您会发现在标签后面放置带注释的透明框是一种合适的解决方法。

例如

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(1)
x, y = np.random.random((2,500))

fig, ax = plt.subplots()
ax.plot(x, y, 'bo')

# The key option here is `bbox`. I'm just going a bit crazy with it.
ax.annotate('Something', xy=(x[0], y[0]), xytext=(-20,20), 
            textcoords='offset points', ha='center', va='bottom',
            bbox=dict(boxstyle='round,pad=0.2', fc='yellow', alpha=0.3),
            arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0.5', 
                            color='red'))

plt.show()

enter image description here

相关问题 更多 >