2012-10-12 97 views
77

我對python/matplotlib和通過ipython筆記本使用它都頗爲陌生。我試圖添加一些註釋行到現有的圖形,我無法弄清楚如何渲染圖形上的線條。因此,舉例來說,如果我繪製如下:向ipython筆記本中的matplotlib圖添加一條任意線

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

所以,我怎麼會從(70100)添加一條垂直線達(70250) ?那麼從(70,100)到(90,200)的對角線呢?

我試過幾件事,Line2D()導致我的一部分,但沒有任何混淆。在R我會簡單地使用segments()函數來添加線段。 matplotlib中是否有相同的內容?

回答

131

您可以直接通過餵養與相應數據的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

+0

優秀和完整的插圖!非常感謝! –

+2

稍作修改,上面的代碼應該讀取'x = np.arange(1,101)'。 –

+0

這不會畫出一條線,而只是一條線段。如何畫出一條線來拋出兩個給定的問題仍然沒有答案。 – Alexey

30

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

很好。我沒有看到'vline()'或'hline()'函數。那對角線呢?我編輯了這個問題來添加對角線位,現在您已經向我顯示了h&v行。 –

+0

試着製作一個包含x,y座標的'DataFrame',並用'style ='k-''繪製它們。 –

+0

謝謝你,非常方便 – Alex

35

這還不算太晚的新人。

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

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

它需要y的範圍爲好,使用YMIN與YMAX。

+1

axhline和axvline的最小/最大參數是介於0和1之間的標量值,即參考繪圖邊緣繪製線條。雖然這是一個很好的工具,但它可能不是作者繪圖註釋行問題描述的最佳解決方案。 – binarysubstrate

+1

這是完美的想要在跨越整個圖形的背景中添加註釋行。如果我使用上面選擇的解決方案在x = 1處繪製垂直線,則必須指定最小值和最大值y,然後使用緩衝區自動調整大小,以便線不會在整個繪圖上延伸,並且這是一個麻煩。這更優雅,不會調整劇情。 – Bonnie

1

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向連接線添加曲線。