web-dev-qa-db-ja.com

matplotlibには、軸座標に対角線を描く機能がありますか?

Matplotlib Axesには、Axesのデータスケールに関係なく、特定のy座標またはx座標で(それぞれ)水平線または垂直線を描画するための関数axhlineおよびaxvlineがあります。

一定の対角線をプロットするための同様の関数はありますか?たとえば、類似したドメインの変数の散布図がある場合、変数が_y = x_の行より上にあるか下にあるかを知ることはしばしば役立ちます。

_mean, cov = [0, 0], [(1, .6), (.6, 1)]
x, y = np.random.multivariate_normal(mean, cov, 100).T
y += x + 1
f, ax = plt.subplots(figsize=(6, 6))
ax.scatter(x, y, c=".3")
ax.plot([-3, 3], [-3, 3], ls="--", c=".3")
ax.set(xlim=(-3, 3), ylim=(-3, 3))
_

enter image description here

これはもちろん、軸の制限(ax.get_xlim()など)をつかむことによってプログラムで行うことができますが、a)いくつかの余分なステップが必要であり、b)より多くのデータが最終的に制限をプロットしてシフトします。 (実際には、一定の線自体を追加するだけで軸が伸びる場合があります)。

単にax.axdline(ls="--", c=".3")を実行することが望ましいですが、matplotlibコードベースにこのようなものが存在するかどうかは明確ではありません。あなたがする必要があるのは、axhlinexの両方のaxes座標で_[0, 1]_からプロットするようにyコードを修正することだけです。

34
mwaskom

画面の左下から右上への対角線のプロットは非常に簡単で、単にax.plot(ax.get_xlim(), ax.get_ylim(), ls="--", c=".3")を使用できます。メソッドax.get_xlim()は、単にx軸の現在の値を返します(y軸についても同様)。

ただし、グラフを使用してズームできるようにするには、プロットした対角線が新しいxlimとylimに一致するように変更されないため、少し複雑になります。

この場合、コールバックを使用してxlims(またはylims)がいつ変更されたかを確認し、それに応じて対角線のデータを変更できます(以下を参照)。 この例 でコールバックのメソッドを見つけました。さらに情報を見つけることもできます here

import numpy as np
import matplotlib.pyplot as plt

mean, cov = [0, 0], [(1, .6), (.6, 1)]
x, y = np.random.multivariate_normal(mean, cov, 100).T
y += x + 1

f, ax = plt.subplots(figsize=(6, 6))

ax.scatter(x, y, c=".3")
ax.set(xlim=(-3, 3), ylim=(-3, 3))

# Plot your initial diagonal line based on the starting
# xlims and ylims.
diag_line, = ax.plot(ax.get_xlim(), ax.get_ylim(), ls="--", c=".3")

def on_change(axes):
    # When this function is called it checks the current
    # values of xlim and ylim and modifies diag_line
    # accordingly.
    x_lims = ax.get_xlim()
    y_lims = ax.get_ylim()
    diag_line.set_data(x_lims, y_lims)

# Connect two callbacks to your axis instance.
# These will call the function "on_change" whenever
# xlim or ylim is changed.
ax.callbacks.connect('xlim_changed', on_change)
ax.callbacks.connect('ylim_changed', on_change)

plt.show()

対角線をズームで変更したくない場合は、diag_line, = ax.plot(...

31
Ffisegydd

プロットの左下から右上隅に対角線を描くには、次のようにします。

ax.plot([0, 1], [0, 1], transform=ax.transAxes)

transform=ax.transAxesを使用すると、提供されたxおよびy座標は、data座標ではなくaxes座標として解釈されます。

これは、@ [fqq]が指摘したように、xyの制限が等しい場合のID行のみです。常にプロットの限界まで延びるようにy=x線を描画するには、@ Ffisegyddで指定されたアプローチと同様のアプローチが機能し、次の関数として記述できます。

def add_identity(axes, *line_args, **line_kwargs):
    identity, = axes.plot([], [], *line_args, **line_kwargs)
    def callback(axes):
        low_x, high_x = axes.get_xlim()
        low_y, high_y = axes.get_ylim()
        low = max(low_x, low_y)
        high = min(high_x, high_y)
        identity.set_data([low, high], [low, high])
    callback(axes)
    axes.callbacks.connect('xlim_changed', callback)
    axes.callbacks.connect('ylim_changed', callback)
    return axes

使用例:

import numpy as np
import matplotlib.pyplot as plt

mean, cov = [0, 0], [(1, .6), (.6, 1)]
x, y = np.random.multivariate_normal(mean, cov, 100).T
y += x + 1

f, ax = plt.subplots(figsize=(6, 6))
ax.scatter(x, y, c=".3")
add_identity(ax, color='r', ls='--')

plt.show()
27
JaminSore

軸が[0,1]の範囲にある場合、次の方法で解決できます。

ident = [0.0, 1.0]
plt.plot(ident,ident)
3
volperossa