2011-10-29 5 views
23

Rには、切片(第1引数)の傾き(第2引数)の指定に基づいてプロット上に線を描くことができるablineという関数があります。例えば、matplotlibの傾きと切片に基づいて行を追加しますか?

plot(1:10,1:10) 
abline(0,1) 

0の切片と1の傾斜を有するラインは、プロットの全範囲に及ぶ場合。そのような機能はmatplotlib.pyplotにありますか?

+2

いいえ、ありません。これは便利な機能です。同様の縦横関数である 'axvline'、' axvspan'、 'axhline'、' axhspan'がありますが、matplotlibの一般的な方法は与えられた勾配に線を描くことです。インタラクティブに作業している場合は、それを超えてズームしてください)。フレームワーク( 'matplotlib.transforms')はそこにありますが、"正しい "方法(つまり、どこにズームしても常に軸に広がるように)は少し複雑です。 –

+1

はい、残念です... Matlabにはこの機能がありません。一方、Rのプロットは静的( 'abline'が存在する' base'グラフィックスシステム)ですので、そこでは心配する必要はありません(それは私が推測すると良いことです)。 – hatmatrix

答えて

4

(intercept, slope)(0, 1)の場合、次の機能を使用して他のスロープとインターセプトに対応することができますが、軸のリミットを変更したり、オートスケールをオンに戻したりすると再調整されません。

def abline(): 
    gca = plt.gca() 
    gca.set_autoscale_on(False) 
    gca.plot(gca.get_xlim(),gca.get_ylim()) 

import matplotlib.pyplot as plt 
plt.scatter(range(10),range(10)) 
abline() 
plt.draw() 
+1

ズームインしても、左下隅から右上隅に向かう線が必要な場合は、単にplt.plot([0,1]、[0,1 ]、transform = plt.gca()。transAxes) 'を実行します。しかし、これはデータ座標の1対1の傾きにはならないでしょう。ズームインするとどこでも左下から右上に移動します...あなたが言ったように、より一般的な 'アブライン'交換はインタラクティブな使用のためにもっと難しいです... –

+0

ああ、これはtransAxesがかなり面白いです。私はある時点でそれを利用していると想像することができます(私は多くの場合、xlim = ylimのところに多くのプロットがあります)。 – hatmatrix

8

私はコールバックに頼らずにこれを行う方法を見つけられませんでしたが、これはかなりうまくいくようです。

import numpy as np 
from matplotlib import pyplot as plt 


class ABLine2D(plt.Line2D): 

    """ 
    Draw a line based on its slope and y-intercept. Additional arguments are 
    passed to the <matplotlib.lines.Line2D> constructor. 
    """ 

    def __init__(self, slope, intercept, *args, **kwargs): 

     # get current axes if user has not specified them 
     if not 'axes' in kwargs: 
      kwargs.update({'axes':plt.gca()}) 
     ax = kwargs['axes'] 

     # if unspecified, get the current line color from the axes 
     if not ('color' in kwargs or 'c' in kwargs): 
      kwargs.update({'color':ax._get_lines.color_cycle.next()}) 

     # init the line, add it to the axes 
     super(ABLine2D, self).__init__([], [], *args, **kwargs) 
     self._slope = slope 
     self._intercept = intercept 
     ax.add_line(self) 

     # cache the renderer, draw the line for the first time 
     ax.figure.canvas.draw() 
     self._update_lim(None) 

     # connect to axis callbacks 
     self.axes.callbacks.connect('xlim_changed', self._update_lim) 
     self.axes.callbacks.connect('ylim_changed', self._update_lim) 

    def _update_lim(self, event): 
     """ called whenever axis x/y limits change """ 
     x = np.array(self.axes.get_xbound()) 
     y = (self._slope * x) + self._intercept 
     self.set_data(x, y) 
     self.axes.draw_artist(self) 
+0

小さな改善:行をスワップ ax.figure.canvas.draw()と self._update_lim(なし) プロットは実際にはウィンドウをクリックすることなく更新されます – tal

+0

@tal最後に私のバージョンのmatplotlib( 1.4.3) 'self.axes.draw_artist(self)'を呼び出す前に親軸を少なくとも1回レンダリングする必要があります。そうでなければ 'Axesの' assert self._cachedRenderer is None'行に 'AssertionError'を取得します。 draw_artist'。 '_update_lim'が呼び出された後、いつでも追加の描画を挿入することができます。私は通常、それを直接インスタンス化するのではなく、私のために行う便利な関数の内部から 'ABLine'を初期化します。 –

26

私はこの質問が数年前であることを知っていますが、受け入れられた答えがないので、私は何が私のために追加されます。

グラフに値をプロットしてから、元のグラフよりも最適な線とプロットの座標の別の値を生成することができます。たとえば、次のコードを参照してください。これらのソリューションの多くは、データをフィットプロットに行を追加することに注力してい

import matplotlib.pyplot as plt 
import numpy as np 

# Some dummy data 
x = [1, 2, 3, 4, 5, 6, 7] 
y = [1, 3, 3, 2, 5, 7, 9] 

# Find the slope and intercept of the best fit line 
slope, intercept = np.polyfit(x, y, 1) 

# Create a list of values in the best fit line 
abline_values = [slope * i + intercept for i in x] 

# Plot the best fit line over the actual values 
plt.plot(x, y, '--') 
plt.plot(x, abline_values, 'b') 
plt.title(slope) 
plt.show() 
5
X = np.array([1, 2, 3, 4, 5, 6, 7]) 
Y = np.array([1.1,1.9,3.0,4.1,5.2,5.8,7]) 

scatter (X,Y) 
slope, intercept = np.polyfit(X, Y, 1) 
plot(X, X*slope + intercept, 'r') 
16

。ここでは、傾きと切片に基づいてプロットに任意の線を追加する簡単な方法を示します。

def abline(slope, intercept): 
    """Plot a line from slope and intercept""" 
    axes = plt.gca() 
    x_vals = np.array(axes.get_xlim()) 
    y_vals = intercept + slope * x_vals 
    plt.plot(x_vals, y_vals, '--') 
関連する問題