9

次のコードで、自分で設定したx軸とy軸のサイズの間に共通のアスペクト比を持つ同じサイズの4つのサブプロットを作成したいと思います。以下の例を参照すると、すべてのサブプロットが最初のサブプロット(左上)とまったく同じように見えるようにしたいと思います。現在間違っているのは、y軸のサイズが最大値と相関していることです。それは私が避けたい行動です。

import matplotlib.pyplot as plt
import numpy as np

def main(): 

    fig = plt.figure(1, [5.5, 3])
    for i in range(1,5):
        fig.add_subplot(221+i-1, adjustable='box', aspect=1) 
        plt.plot(np.arange(0,(i)*4,i))

    plt.show()

if __name__ == "__main__": 
    main()

驚いたことに、matplotlibはデフォルトで正しいものを生成します(下の写真):

   import  matplotlib.pyplot as plt 
   import numpy as np 

   def main(): 
       fig = plt.figure(1, [5.5, 3]) 
       for i in range(1,5): 
           fig.add_subplot(221+i-1) 
            plt.plot(np.arange(0,(i)*4,i)) 
       plt.show() 

これに、x軸とy軸の長さのアスペクト比を制御する機能を追加したいと思います。

これが私が探しているものです:

4

3 に答える 3

10

私はあなたの質問からあなたが何を望んでいるのかよくわかりません。

すべてのプロットに同じデータ制限を設定しますか?

その場合は、共有軸を使用します(subplotsここでは使用していますが、MATLABスタイルのコードに固執する場合は回避できます)。

import matplotlib.pyplot as plt
import numpy as np

fig, axes = plt.subplots(nrows=2, ncols=2, sharey=True, sharex=True)
for i, ax in enumerate(axes.flat, start=1):
    ax.set(aspect=1)
    ax.plot(np.arange(0, i * 4, i))

plt.show()

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

それらすべてに軸の制限を共有させたいが、adjustable='box'(つまり、非正方形の軸の境界を)持たせたい場合は、次を使用しますadjustable='box-forced'

import matplotlib.pyplot as plt
import numpy as np

fig, axes = plt.subplots(nrows=2, ncols=2, sharey=True, sharex=True)
for i, ax in enumerate(axes.flat, start=1):
    ax.set(aspect=1, adjustable='box-forced', xticks=range(i))
    ax.plot(np.arange(0, i * 4, i))

plt.show()

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


編集:申し訳ありませんが、私はまだ少し混乱しています。このようなものが欲しいですか?

import matplotlib.pyplot as plt 
import numpy as np 

fig, axes = plt.subplots(nrows=2, ncols=2)
for i, ax in enumerate(axes.flat, start=1):
    ax.set(adjustable='datalim', aspect=1)
    ax.plot(np.arange(0, i * 4, i))

plt.show()

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


さて、私は最終的にあなたの質問を理解したと思います。私たちは両方とも「アスペクト比」によってまったく異なることを意味しました。

matplotlibでは、プロットのアスペクト比はデータ制限の相対的なスケールを参照します。つまり、プロットのアスペクト比が1の場合、傾きが1の線が45度で表示されます。アスペクト比は、軸にプロットされたデータではなく、軸の輪郭に適用されると想定していました。

サブプロットの輪郭を正方形にしたいだけです。(この場合、matplotlibで定義されているように、すべてのアスペクト比が異なります。)

その場合、正方形の図形が必要です。(他の方法もありますが、正方形の図形を作成する方がはるかに簡単です。Matplotlib軸は、図形のサイズに比例するスペースを埋めます。)

import matplotlib.pyplot as plt 
import numpy as np 

# The key here is the figsize (it needs to be square). The position and size of
# axes in matplotlib are defined relative to the size of the figure.
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(8,8))

for i, ax in enumerate(axes.flat, start=1):
    ax.plot(np.arange(0, i * 4, i))

# By default, subplots leave a bit of room for tick labels on the left.
# We'll remove it so that the axes are perfectly square.
fig.subplots_adjust(left=0.1)

plt.show()

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

于 2013-02-16T15:34:07.423 に答える
2

ジョーキントンの答えをmatplotlibの共有軸の正方形のサブプロット用の新しいpythonicスタイルと組み合わせますか? そして、私はそれを再び見つけることができないのではないかと心配している別の投稿で、ボックスの比率を特定の値に正確に設定するためのコードを作成しました。

desired_box_ratioNが、ボックスのy辺とx辺の間の望ましい比率を示しているとします。temp_inverse_axis_ratioNは、現在のプロットのx辺とy辺の比率です。'aspect'は(軸ではなく)yスケールとxスケールの比率であるため、アスペクトをdesired_box_ratioN*temp_inverse_axis_ratioNに設定する必要があります。

import matplotlib.pyplot as plt
import numpy as np

fig, axes = plt.subplots(nrows=2, ncols=2)

desired_box_ratioN = 1
for i, ax in enumerate(axes.flat, start=1):
    ax.plot(np.arange(0, i * 4, i))
    temp_inverse_axis_ratioN = abs( (ax.get_xlim()[1] - ax.get_xlim()[0])/(ax.get_ylim()[1] - ax.get_ylim()[0]) )
    ax.set(aspect = desired_box_ratioN * temp_inverse_axis_ratioN, adjustable='box-forced')

plt.show()
于 2014-08-04T14:47:24.810 に答える
1

その理論

matplotlibにはさまざまな座標系があります。異なる座標系の違いは、多くの人を本当に混乱させる可能性があります。OPが必要としているのは、表示座標ax.set_aspect()のアスペクト比ですが、データ座標のアスペクト比を設定しています。それらの関係は次のように定式化できます。

aspect = 1.0/dataRatio*dispRatio

ここで、はメソッドでaspect使用する引数、はデータ座標でのアスペクト比、は表示座標での目的のアスペクト比です。set_aspectdataRatiodispRatio

練習

get_data_ratioコードをより簡潔にするために使用できる方法があります。作業コードスニペットを以下に示します。

import matplotlib.pyplot as plt
import numpy as np

fig, axes = plt.subplots(nrows=2, ncols=2)

dispRatio = 0.5
for i, ax in enumerate(axes.flat, start=1):
    ax.plot(np.arange(0, i * 4, i))
    ax.set(aspect=1.0/ax.get_data_ratio()*dispRatio, adjustable='box-forced')

plt.show()

私はまた、これらすべてのものについての詳細な投稿をここに書きました。

于 2018-01-08T02:02:47.833 に答える