99

私は、3Dデータセットを介してスライスと投影を視覚化するソフトウェアシステムを書いています。私は、分析コードから取得した画像バッファーを視覚化するために使用matplotlibしています。imshow

プロット軸で画像に注釈を付けたいので、imshow提供するextentキーワードを使用して、画像バッファのピクセル座標をデータ空間座標系にマップします。

残念ながら、matplotlibユニットについては知りません。の寸法で画像をプロットしたいと(人為的な例を挙げて)言い1000 m X 1 kmます。その場合、範囲はのようになります[0, 1000, 0, 1]。画像配列が正方形であっても、extentキーワードによって示されるアスペクト比は1000であるため、結果のプロット軸のアスペクト比も1000になります。

範囲キーワードを使用して取得した自動生成された主要な目盛りとラベルを維持しながら、プロットのアスペクト比を強制することは可能ですか?

4

2 に答える 2

159

これを行うには、画像のアスペクトを手動で設定します(または、自動拡大縮小して図の範囲を埋めます)。

デフォルトでimshowは、プロットのアスペクトを1に設定します。これは、多くの場合、人々が画像データに求めるものだからです。

あなたの場合、あなたは次のようなことをすることができます:

import matplotlib.pyplot as plt
import numpy as np

grid = np.random.random((10,10))

fig, (ax1, ax2, ax3) = plt.subplots(nrows=3, figsize=(6,10))

ax1.imshow(grid, extent=[0,100,0,1])
ax1.set_title('Default')

ax2.imshow(grid, extent=[0,100,0,1], aspect='auto')
ax2.set_title('Auto-scaled Aspect')

ax3.imshow(grid, extent=[0,100,0,1], aspect=100)
ax3.set_title('Manually Set Aspect')

plt.tight_layout()
plt.show()

ここに画像の説明を入力してください

于 2012-11-15T02:36:17.230 に答える
8

公式ガイドからplt.imshow()、アスペクトが軸のアスペクト比を制御することがわかります。私の言葉では、アスペクトは正確にx単位とy単位の比率です。意図せずに数字を歪めたくないので、ほとんどの場合、1のままにしておきます。ただし、実際には、アスペクトを1以外の値で指定する必要がある場合があります。質問者は、x軸とy軸の物理単位が異なる可能性があるという良い例を示しました。xがkmで、yがmであると仮定しましょう。したがって、10x10データの場合、範囲は[0,10km、0,10m] = [0、10000m、0、10m]である必要があります。このような場合、デフォルトのアスペクト= 1を使い続けると、フィギュアの品質は非常に悪くなります。したがって、アスペクト= 1000を指定して、図を最適化できます。次のコードは、この方法を示しています。

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
rng=np.random.RandomState(0)
data=rng.randn(10,10)
plt.imshow(data, origin = 'lower',  extent = [0, 10000, 0, 10], aspect = 1000)

ここに画像の説明を入力してください

それでも、質問者の要求を満たすことができる代替案があると思います。範囲を[0,10,0,10]として設定し、単位を示すためにxy軸ラベルを追加するだけです。次のようにコーディングします。

plt.imshow(data, origin = 'lower',  extent = [0, 10, 0, 10])
plt.xlabel('km')
plt.ylabel('m')

ここに画像の説明を入力してください

正しい数字を作るために、私たちは常にそれと、を心に留めておく必要がありx_max-x_min = x_res * data.shape[1]ます。デフォルトでは、、は単位ピクセルが正方形であることを意味します。このデフォルトの動作は、値が異なるx_resとy_resでも正常に機能します。前の例を拡張して、x_resが1.5で、y_resが1であると仮定します。したがって、エクステントは[0,15,0,10]に等しくなります。デフォルトのアスペクトを使用すると、長方形のカラーピクセルを使用できますが、単位ピクセルは正方形のままです。y_max - y_min = y_res * data.shape[0]extent = [x_min, x_max, y_min, y_max]aspect = 1

plt.imshow(data, origin = 'lower',  extent = [0, 15, 0, 10])
# Or we have similar x_max and y_max but different data.shape, leading to different color pixel res.
data=rng.randn(10,5)
plt.imshow(data, origin = 'lower',  extent = [0, 5, 0, 5])

ここに画像の説明を入力してください ここに画像の説明を入力してください

カラーピクセルのアスペクトはですx_res / y_res。そのアスペクトを単位ピクセルのアスペクトに設定すると(つまりaspect = x_res / y_res = ((x_max - x_min) / data.shape[1]) / ((y_max - y_min) / data.shape[0]))、常に正方形のカラーピクセルが得られます。x軸の単位がy軸の単位の1.5倍になるように、アスペクト= 1.5を変更できます。これにより、正方形のカラーピクセルと正方形の全体像が得られますが、長方形のピクセル単位になります。どうやら、それは通常受け入れられていません。

data=rng.randn(10,10)
plt.imshow(data, origin = 'lower',  extent = [0, 15, 0, 10], aspect = 1.5)

ここに画像の説明を入力してください

最も望ましくないケースは、アスペクトを1.2などの任意の値に設定することです。これにより、正方形の単位ピクセルも正方形のカラーピクセルも生成されません。

plt.imshow(data, origin = 'lower',  extent = [0, 15, 0, 10], aspect = 1.2)

ここに画像の説明を入力してください

簡単に言えば、正しい範囲を設定し、matplotlibに残りの処理を任せるだけで十分です(x_res!= y_resであっても)!必要な場合にのみアスペクトを変更してください。

于 2019-10-28T22:31:18.413 に答える