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

JD *_*ong 105 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")
Run Code Online (Sandbox Code Playgroud)

我得到以下图表:

美丽的散点图

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

我尝试了一些事情,Line2D()但除了我之外什么也没有产生混淆.在R我只想用段()函数,这将增加线段.有没有等价的matplotlib

gca*_*tes 165

您可以通过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()
Run Code Online (Sandbox Code Playgroud)

新图表

  • @Rmano您可以通过添加以"_"开头的标签参数来避免在图例中考虑段.例如:`plt.plot([70,70],[100,250],'k - ',lw = 2,label ="_不在传说中") (6认同)
  • `90` 被同时用作 `x2` 和 `y1` 的事实导致了很多歧义。对于查看此内容的任何人,请注意 `[70, 90]` 不是指位置 `x1,y1` 处的单个点。作为参考,这里是值的含义:`[x1: 70, x2: 90], [y1: 90, y2: 200]` (4认同)
  • 小修正,上面的代码应该是`x = np.arange(1,101)`. (2认同)

lif*_*ger 56

这对新人来说还不算太晚.

plt.axvline(x, color='r')
Run Code Online (Sandbox Code Playgroud)

http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.axvline

使用ymin和ymax也需要y的范围.

  • 这非常适合想要在背景中添加横跨整个图形的注释线.如果我使用上面选择的解决方案在x = 1处绘制一条垂直线,我必须指定最小值和最大值y,然后使用缓冲区自动调整大小,因此该线不会在整个绘图中延伸,并且这很麻烦.这更优雅,不会调整情节. (3认同)

Aus*_*son 39

使用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)
Run Code Online (Sandbox Code Playgroud)

基本呼叫签名是:

vlines(x, ymin, ymax)
hlines(y, xmin, xmax)
Run Code Online (Sandbox Code Playgroud)

  • 这很棒.我没见过`vline()`或`hline()`函数.对角线怎么样?我编辑了问题,添加对角线,因为你已经向我展示了h&v线. (2认同)

Way*_*yne 6

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"),
            )
Run Code Online (Sandbox Code Playgroud)

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

从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()
Run Code Online (Sandbox Code Playgroud)

内嵌图片示例

就像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."), 
              )
Run Code Online (Sandbox Code Playgroud)

您还可以通过调整来将曲线添加到连接线connectionstyle


Qua*_*lia 6

而不是滥用plotannotate,这将是低效的多条线路,则可以使用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()
Run Code Online (Sandbox Code Playgroud)

通过 LineCollection 绘制两条线的图

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

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