簡體   English   中英

具有不同y軸的子圖中的縱橫比

[英]Aspect ratio in subplots with various y-axes

我希望以下代碼生成4個相同大小的子圖,其中我設置的x軸和y軸的大小之間有一個共同的縱橫比。 參考下面的例子,我希望所有的子圖看起來都像第一個(左上角)。 現在的錯誤是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軸長度之間縱橫比的能力。

這是我正在尋找的:

我無法從你的問題中說出你想要的東西。

您是否希望所有圖表都具有相同的數據限制?

如果是這樣,使用共享軸(我在這里使用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()

在此輸入圖像描述

Joe Kington的答案與matplotlib中的共享軸方形子圖的新pythonic風格相結合? 另一篇文章,我恐怕再也找不到了,我制作了一個代碼,用於精確設置盒子與給定值的比例。

令desired_box_ratioN指示框的y和x側之間的所需比率。 temp_inverse_axis_ratioN是當前圖的x和y邊之間的比率; 因為'aspect'是y和x scale(而不是axis)之間的比率,我們需要將aspect設置為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()

理論

matplotlib中存在不同的坐標系 不同坐標系之間的差異確實會讓很多人感到困惑。 OP想要的是顯示坐標中的寬高比,但是ax.set_aspect()是在數據坐標中設置寬高比。 他們的關系可以表述為:

aspect = 1.0/dataRatio*dispRatio

其中, aspect是在set_aspect方法中使用的參數, dataRatio是數據坐標中的縱橫比, dispRatio是顯示坐標中所需的縱橫比

實踐

有一個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()

我也寫了這些東西中的詳細說明這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM