2011-11-01 337 views
74

我試圖做一個方形圖(使用imshow),即縱橫比爲1:1,但我不能。這些工作都不是:如何在matplotlib中設置縱橫比?

import matplotlib.pyplot as plt 

ax = fig.add_subplot(111,aspect='equal') 
ax = fig.add_subplot(111,aspect=1.0) 
ax.set_aspect('equal') 
plt.axes().set_aspect('equal') 

這似乎是調用只是被忽略(我經常看到與matplotlib有關的問題)。

+5

你試過'ax.axis('equal')',偶然嗎?正如大家所說,你做了什麼應該可以工作,但'ax.axis'可能是嘗試解決方法的另一種途徑。 –

+0

http://matplotlib.org/examples/pylab_examples/equal_aspect_ratio.html –

回答

53

第三次的魅力。我的猜測是,這是一個錯誤,並且Zhenya's answer表示它已在最新版本中修復。我有版本0.99.1.1,我已經創建了以下解決方案:

import matplotlib.pyplot as plt 
import numpy as np 

def forceAspect(ax,aspect=1): 
    im = ax.get_images() 
    extent = im[0].get_extent() 
    ax.set_aspect(abs((extent[1]-extent[0])/(extent[3]-extent[2]))/aspect) 

data = np.random.rand(10,20) 

fig = plt.figure() 
ax = fig.add_subplot(111) 
ax.imshow(data) 
ax.set_xlabel('xlabel') 
ax.set_aspect(2) 
fig.savefig('equal.png') 
ax.set_aspect('auto') 
fig.savefig('auto.png') 
forceAspect(ax,aspect=1) 
fig.savefig('force.png') 

這是「force.png」: enter image description here

下面是我的失敗,但希望翔實的嘗試。

第二個答案:下面

我 '原來的答案' 是矯枉過正,因爲它類似於axes.set_aspect()東西。我想你想用axes.set_aspect('auto')。我不明白爲什麼是這樣的話,但它會產生一個正方形圖像的情節對我來說,比如這個腳本:

import matplotlib.pyplot as plt 
import numpy as np 

data = np.random.rand(10,20) 

fig = plt.figure() 
ax = fig.add_subplot(111) 
ax.imshow(data) 
ax.set_aspect('equal') 
fig.savefig('equal.png') 
ax.set_aspect('auto') 
fig.savefig('auto.png') 

產生一個與「平等」的寬高比的圖像情節: enter image description here 和一個用「自動」縱橫比: enter image description here

在「原始答案」下面提供的代碼提供一種用於顯式控制縱橫比的出發點,但它似乎被忽略一旦imshow被調用。

原來的答案:

這裏有一個程序,將調整插曲參數的例子,讓你得到所需的寬高比:

import matplotlib.pyplot as plt 

def adjustFigAspect(fig,aspect=1): 
    ''' 
    Adjust the subplot parameters so that the figure has the correct 
    aspect ratio. 
    ''' 
    xsize,ysize = fig.get_size_inches() 
    minsize = min(xsize,ysize) 
    xlim = .4*minsize/xsize 
    ylim = .4*minsize/ysize 
    if aspect < 1: 
     xlim *= aspect 
    else: 
     ylim /= aspect 
    fig.subplots_adjust(left=.5-xlim, 
         right=.5+xlim, 
         bottom=.5-ylim, 
         top=.5+ylim) 

fig = plt.figure() 
adjustFigAspect(fig,aspect=.5) 
ax = fig.add_subplot(111) 
ax.plot(range(10),range(10)) 

fig.savefig('axAspect.png') 

這將產生像這樣一個數字: enter image description here

我可以想象如果你在圖中有多個子圖,你w應該將y和x子圖的數量作爲關鍵字參數(默認爲1)提供給例程。然後使用這些數字和hspacewspace關鍵字,可以使所有子圖具有正確的寬高比。

+0

非常感謝 - 終於使用你的功能的作品!謝謝,謝謝你:-) – jtlz2

+0

對於'get_images'是一個空列表的情況(就像'ax.plot([0,1],[0,2])'一樣'',你可以使用'get_xlim'和' get_ylim' – Joel

+0

在我看來,如果使用logscale完成這項工作將無法正常工作,我已經添加了一個測試並處理它的答案,隨時將其合併到您的答案中,然後刪除我的答案。 – Joel

2

你應該嘗試與figaspect。這個對我有用。從文檔:

創建一個具有指定寬高比的圖形。如果arg是數字,請使用該寬高比。 >如果arg是一個數組,則figaspect將確定一個數字的寬度和高度,該數字將適合保存縱橫比的數組 。數字寬度,英寸高度爲 返回。一定要平等與和高度創建一個軸,如

用法示例:

# make a figure twice as tall as it is wide 
    w, h = figaspect(2.) 
    fig = Figure(figsize=(w,h)) 
    ax = fig.add_axes([0.1, 0.1, 0.8, 0.8]) 
    ax.imshow(A, **kwargs) 

    # make a figure with the proper aspect for an array 
    A = rand(5,3) 
    w, h = figaspect(A) 
    fig = Figure(figsize=(w,h)) 
    ax = fig.add_axes([0.1, 0.1, 0.8, 0.8]) 
    ax.imshow(A, **kwargs) 

編輯:我不知道你在找什麼。上面的代碼更改畫布(繪圖大小)。如果你想改變圖形的matplotlib窗口的大小,然後使用:

In [68]: f = figure(figsize=(5,1)) 

這併產生5×(寬x高)的窗口。

+0

感謝你 - 在改變畫布縱橫比時確實有一些效果:更具體地說,我需要改變畫面的縱橫比數字本身,它做以下不(格式化..):圖= plt.figure(figsize =(plt.figaspect(2.0))) – jtlz2

17

什麼是您運行的matplotlib版本?我最近不得不升級到1.1.0,與此同時,add_subplot(111,aspect='equal')適合我。

+0

It's 1.0.1。也許這是一個答案.. – jtlz2

+0

在'matplotlib'版本'2.0.2'中適用於我。''jupyter notebook' version'5.0.0'。謝謝。 – Sathish

1

此答案是根據Yann的回答。它將設置線性或對數圖的縱橫比。我使用https://stackoverflow.com/a/16290035/2966723的附加信息來測試軸是否爲對數刻度。

def forceAspect(ax,aspect=1): 
    #aspect is width/height 
    scale_str = ax.get_yaxis().get_scale() 
    xmin,xmax = ax.get_xlim() 
    ymin,ymax = ax.get_ylim() 
    if scale_str=='linear': 
     asp = abs((xmax-xmin)/(ymax-ymin))/aspect 
    elif scale_str=='log': 
     asp = abs((scipy.log(xmax)-scipy.log(xmin))/(scipy.log(ymax)-scipy.log(ymin)))/aspect 
    ax.set_aspect(asp) 

很明顯,你可以使用你想要的,我用scipy,但numpymath應罰款的log任何版本。