Imshow:範囲と側面


85

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

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

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

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

回答:


141

これを行うには、画像のアスペクトを手動で設定します(または、自動スケーリングして図の範囲を埋めます)。

デフォルトで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()

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


ありがとう。面白いドキュメントはscalarオプションについて何も言っていません。y-axis与えられたスカラーでスケーリングしているように見えます。
orodbhen 2018

@JoeKingtonは、個々のピクセルのサイズを取得することができます。このサイズはデータセットのサイズに依存し、タイルのパッチワークを形成して、あなたの場合のように連続プロットにすることができます。
アレクサンダーCska

4

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

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であっても)!必要な場合にのみアスペクトを変更してください。

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