web-dev-qa-db-ja.com

matplotlibで(高さと幅が等しい)正方形のサブプロットを作成する

このコードを実行すると

from pylab import *

figure()
ax1 = subplot(121)
plot([1, 2, 3], [1, 2, 3])
subplot(122, sharex=ax1, sharey=ax1)
plot([1, 2, 3], [1, 2, 3])
draw()
show()

X次元で「押しつぶされた」2つのサブプロットが表示されます。両方のサブプロットについて、Y軸の高さがX軸の幅と等しくなるようにこれらのサブプロットを取得するにはどうすればよいですか?

Ubuntu 10.04でmatplotlib v.0.99.1.2を使用しています。

pdate 2010-07-08:機能しないものをいくつか見てみましょう。

一日中ググリングした後、自動スケーリングに関連しているのではないかと思いました。だから私はそれをいじってみました。

from pylab import *

figure()
ax1 = subplot(121, autoscale_on=False)
plot([1, 2, 3], [1, 2, 3])
subplot(122, sharex=ax1, sharey=ax1)
plot([1, 2, 3], [1, 2, 3])
draw()
show()

matplotlibは自動スケーリングを要求します。

from pylab import *

figure()
ax1 = subplot(121, autoscale_on=False)
plot([1, 2, 3], [1, 2, 3])
subplot(122, sharex=ax1, sharey=ax1, autoscale_on=False)
plot([1, 2, 3], [1, 2, 3])
draw()
show()

これでは、データは完全に消えます。 WTF、matplotlib?ただWTF?

さて、たぶんアスペクト比を修正したら?

from pylab import *

figure()
ax1 = subplot(121, autoscale_on=False)
plot([1, 2, 3], [1, 2, 3])
axes().set_aspect('equal')
subplot(122, sharex=ax1, sharey=ax1)
plot([1, 2, 3], [1, 2, 3])
draw()
show()

これにより、最初のサブプロットが完全に消えます。それは陽気です!誰がそれを思いついたのですか?

真剣に、今...これは本当に達成するのがとても難しいことでしょうか?

23
gotgenes

プロットのアスペクトを設定する際の問題は、sharexとshareyを使用しているときに発生します。

1つの回避策は、共有軸を使用しないことです。たとえば、次のようにできます。

from pylab import *

figure()
subplot(121, aspect='equal')
plot([1, 2, 3], [1, 2, 3])
subplot(122, aspect='equal')
plot([1, 2, 3], [1, 2, 3])
show()

ただし、より適切な回避策は、「調整可能な」キーワーグを変更することです... Adjustable = 'box'が必要ですが、共有Axesを使用している場合は、それを調整可能にする必要があります= 'datalim'(および 'box 'エラーが発生します)。

ただし、adjustableがこのケースを正確に処理するための3番目のオプションがあります:adjustable="box-forced"

例えば:

from pylab import *

figure()
ax1 = subplot(121, aspect='equal', adjustable='box-forced')
plot([1, 2, 3], [1, 2, 3])
subplot(122, aspect='equal', adjustable='box-forced', sharex=ax1, sharey=ax1)
plot([1, 2, 3], [1, 2, 3])
show()

またはよりモダンなスタイルで(注:回答のこの部分は2010年には機能しなかったでしょう):

import matplotlib.pyplot as plt

fig, axes = plt.subplots(ncols=2, sharex=True, sharey=True)
for ax in axes:
    ax.plot([1, 2, 3], [1, 2, 3])
    ax.set(adjustable='box-forced', aspect='equal')

plt.show()

どちらの方法でも、次のようなものが得られます。

enter image description here

21
Joe Kington

これを試してみてください:

_from pylab import *

figure()
ax1 = subplot(121, autoscale_on=False, aspect='equal', xlim=[1,3], ylim=[1,3])
plot([1, 2, 3], [1, 2, 3])
##axes().set_aspect('equal')
ax2 = subplot(122, autoscale_on=False, aspect='equal', xlim=[1,3], ylim=[1,3])
plot([1, 2, 3], [1, 2, 3])
draw()
show()
_

axes()行をコメントアウトしました。これにより、計算された位置を持つプレハブのaxesではなく、任意の場所に新しいsubplotが作成されます。

subplotを呼び出すと、実際にAxesインスタンスが作成されます。つまり、Axesと同じプロパティを使用できます。

これが役に立てば幸いです:)

2
Kit