ipythonノートブックのmatplotlibプロットに任意の行を追加する


119

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

次のグラフが表示されます。

美しい散布図

では、(70,100)から(70,250)までの垂直線を追加するにはどうすればよいでしょうか。(70,100)から(90,200)までの対角線はどうですか?

私はいくつかのことを試しましたが、私の側ではLine2D()混乱しか生じませんでした。ではR、segments()関数を使用して、線分を追加します。に同等のものはありmatplotlibますか?

回答:


185

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

新しいチャート


優れた完全なイラストによる素晴らしい答え!大変感謝します!
JDロング

2
マイナーな修正x = np.arange(1, 101)。上記のコードはを読んでください。
WP McNeill

これは線ではなく、線分のみを描画します。どのように線を引くかという問題は、与えられた2つの点を投げます。
Alexey

6
@Rmanoでは、「_」で始まるラベル引数を追加することで、凡例でセグメントが考慮されないようにすることができます。例:plt.plot([70, 70], [100, 250], 'k-', lw=2, label="_not in legend")
gcalmettes

1
との90両方で使用されるという事実は、多くのあいまいさx2y1もたらします。これを表示している人にとっては、[70, 90]は場所の1つのポイントを指していないことに注意してくださいx1,y1。参考のため、ここでの値の意味は次のとおり[x1: 70, x2: 90], [y1: 90, y2: 200]
pookie

61

初心者には遅すぎません。

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

yminとymaxを使用して、yの範囲も取得します。


1
axhlineおよびaxvlineの最小/最大パラメーターは、プロットのエッジを基準に線をプロットする0から1までのスカラー値です。良いツールではありますが、それはおそらく作者の注釈線の描画に関する問題の説明に対する最良の解決策ではありません。
binarysubstrate 2014

3
これは、グラフ全体にわたる背景に注釈線を追加したい場合に最適です。上記で選択したソリューションを使用してx = 1で垂直線を描画する場合、最小と最大のyを指定する必要があります。その後、プロットはバッファーで自動的にサイズ変更されるため、線はプロット全体に広がりません。それは面倒です。これはよりエレガントで、プロットのサイズを変更しません。
ボニー

40

使用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ラインを表示したので、斜めのビットを追加しました。
JDロング

DataFrameX、Y座標を含むを作成して、それらをプロットしてみてくださいstyle='k-'
オースティンリチャードソン、

ありがとう、それはとても便利です
Alex

6

Matplolibは、OPが求めていた「注釈線」を許可するようになりました。このannotate()関数は、いくつかの形式の接続パスを可能にし、ヘッドレスおよびテイルス矢印、つまり単純な線はその1つです。

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の答えのアプローチと同様に、色、線幅、線のスタイルなどを選択できます。

ここでは、2つのサンプル行の1つを赤く太くし、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ます。


1
これが結局必要になったものです。プロットの境界線の外に線を引きたかったのですが、.plot()できません。
Nick S

5

多くの行で非効率になる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で2本の線をプロットした図

これは、ラインのリストを受け取ります[l1, l2, ...]。各ラインは、N座標のシーケンスです(Nは2を超える場合があります)。

標準のフォーマットキーワードが使用可能であり、単一の値(この場合、値はすべての行に適用されます)または一連のM values(この場合、i番目の行の値は)を受け入れますvalues[i % M]

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.