在ipython notebook中的matplotlib图中添加任意一行

时间:2012-10-12 17:32:40

标签: matplotlib ipython

我对python / matplotlib都很陌生,并通过ipython笔记本使用它。我正在尝试向现有图形添加一些注释线,我无法弄清楚如何在图形上渲染线条。因此,例如,如果我绘制以下内容:

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")

我得到以下图表:

beautiful scatter plot

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

我尝试了Line2D()的一些事情,但我只会产生混淆。在R中,我只使用segments()函数来添加线段。 matplotlib中有等价物吗?

5 个答案:

答案 0 :(得分:160)

您可以通过将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()

new chart

答案 1 :(得分:50)

对于newcomers来说还不算太晚。

plt.axvline(x, color='r')

使用ymin和ymax也取y的范围。

答案 2 :(得分:38)

使用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)

答案 3 :(得分:5)

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"),
            )

the documentation中,它表示您只能绘制一个带有空字符串的箭头作为第一个参数。

来自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()

Example inline image

就像在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

将曲线添加到连接线

答案 4 :(得分:3)

您可以使用matplotlib.collections.LineCollection

而不是滥用dataSource.clear(); dataSource.add(featureCollection); plot(对于许多行而言效率低下)
annotate

Figure with two lines plotted via 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() 的列表,其中每行是 N 个坐标的序列( N 可以大于两个)。

标准格式关键字可用,可以接受单个值(在这种情况下该值适用于每行),也可以接受序列 M [l1, l2, ...],在这种情况下,第 i 行是values