135

我对 python/matplotlib 和通过 ipython notebook 使用它都很陌生。我正在尝试向现有图形添加一些注释线,但我不知道如何在图形上呈现这些线。因此,例如,如果我绘制以下内容:

import numpy as np
np.random.seed(5)
x = arange(1, 101)
y = 20 + 3 * x + np.random.normal(0, 60, 100)
p =  plot(x, y, "o")

我得到以下图表:

美丽的散点图

那么如何添加从 (70,100) 到 (70,250) 的垂直线?从 (70,100) 到 (90,200) 的对角线呢?

我已经尝试了一些事情,Line2D()但结果却是我的困惑。在R我将简单地使用将添加线段的segments() 函数。中是否有等价物matplotlib

4

5 回答 5

211

您可以通过向plot命令提供相应的数据(线段的边界)来直接绘制所需的线:

plot([x1, x2], [y1, y2], color='k', linestyle='-', linewidth=2)

(当然你可以选择颜色、线宽、线型等)

从你的例子:

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(5)
x = np.arange(1, 101)
y = 20 + 3 * x + np.random.normal(0, 60, 100)
plt.plot(x, y, "o")


# draw vertical line from (70,100) to (70, 250)
plt.plot([70, 70], [100, 250], 'k-', lw=2)

# draw diagonal line from (70, 90) to (90, 200)
plt.plot([70, 90], [90, 200], 'k-')

plt.show()

新图表

于 2012-10-12T19:43:42.340 回答
71

对于新人来说,现在还为时不晚。

plt.axvline(x, color='r') # vertical
plt.axhline(x, color='r') # horizontal

它的范围也y为 ,使用yminymax

于 2014-11-21T22:27:38.840 回答
42

使用vlines

import numpy as np
np.random.seed(5)
x = arange(1, 101)
y = 20 + 3 * x + np.random.normal(0, 60, 100)
p =  plot(x, y, "o")
vlines(70,100,250)

基本的调用签名是:

vlines(x, ymin, ymax)
hlines(y, xmin, xmax)
于 2012-10-12T17:46:35.077 回答
9

Matplolib 现在允许 OP 正在寻找的“注释行”。该annotate()功能允许多种形式的连接路径和无头无尾箭头,即简单的线,是其中之一。

ax.annotate("",
            xy=(0.2, 0.2), xycoords='data',
            xytext=(0.8, 0.8), textcoords='data',
            arrowprops=dict(arrowstyle="-",
                      connectionstyle="arc3, rad=0"),
            )

文档中它说您只能绘制一个带有空字符串的箭头作为第一个参数。

从OP的例子:

%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(5)
x = np.arange(1, 101)
y = 20 + 3 * x + np.random.normal(0, 60, 100)
plt.plot(x, y, "o")


# draw vertical line from (70,100) to (70, 250)
plt.annotate("",
              xy=(70, 100), xycoords='data',
              xytext=(70, 250), textcoords='data',
              arrowprops=dict(arrowstyle="-",
                              connectionstyle="arc3,rad=0."), 
              )

# draw diagonal line from (70, 90) to (90, 200)
plt.annotate("",
              xy=(70, 90), xycoords='data',
              xytext=(90, 200), textcoords='data',
              arrowprops=dict(arrowstyle="-",
                              connectionstyle="arc3,rad=0."), 
              )

plt.show()

示例内联图像

就像gcalmettes答案中的方法一样,您可以选择颜色、线宽、线型等。

这是对部分代码的更改,它会使两个示例行之一变为红色、更宽且不是 100% 不透明。

# draw vertical line from (70,100) to (70, 250)
plt.annotate("",
              xy=(70, 100), xycoords='data',
              xytext=(70, 250), textcoords='data',
              arrowprops=dict(arrowstyle="-",
                              edgecolor = "red",
                              linewidth=5,
                              alpha=0.65,
                              connectionstyle="arc3,rad=0."), 
              )

您还可以通过调整 为连接线添加曲线connectionstyle

于 2017-08-23T20:17:47.597 回答
7

而不是滥用plotor annotate,这对于许多行来说效率很低,您可以使用matplotlib.collections.LineCollection

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection

np.random.seed(5)
x = np.arange(1, 101)
y = 20 + 3 * x + np.random.normal(0, 60, 100)
plt.plot(x, y, "o")

# Takes list of lines, where each line is a sequence of coordinates
l1 = [(70, 100), (70, 250)]
l2 = [(70, 90), (90, 200)]
lc = LineCollection([l1, l2], color=["k","blue"], lw=2)

plt.gca().add_collection(lc)

plt.show()

通过 LineCollection 绘制两条线的图

它需要一个行列表[l1, l2, ...],其中每行是N个坐标的序列(N可以超过两个)。

标准格式关键字可用,接受单个值,在这种情况下,该值适用于每一行,或一系列M values,在这种情况下,第i行的值为values[i % M]

于 2019-09-03T20:41:09.097 回答