我如何设置matplotlib的纵横比?

我试图做一个方形的阴谋(使用imshow),即纵横比为1:1,但我不能。 这些工作都不是:

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来解决这个问题)。

第三次的魅力。 我的猜测是,这是一个错误, Zhenya的答案表明它是在最新版本中修复的。 我有版本0.99.1.1,我创build了以下解决scheme:

 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': 在这里输入图像说明

下面是我不成功,但希望丰富的尝试。

第二个答案:

我的'原始答案'下面是矫枉过正,因为它做类似于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') 

产生具有“相等”宽高比的图像: 在这里输入图像说明 和“自动”宽高比: 在这里输入图像说明

下面在“原始答案”中提供的代码提供了明确控制纵横比的起点,但是一旦调用了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') 

这产生了这样一个数字: 在这里输入图像说明

我可以想象,如果在图中有多个子图,则需要将y和x个子图的数量作为关键字参数(默认为1)包含在所提供的例程中。 然后使用这些数字和hspacewspace关键字,可以使所有子图具有正确的宽高比。

什么是您正在运行的matplotlib版本? 我最近不得不升级到1.1.0 ,并使用它, add_subplot(111,aspect='equal')为我工作。

你应该用无形的尝试。 这个对我有用。 从文档:

创build一个具有指定宽高比的graphics。 如果arg是数字,则使用该宽高比。 >如果arg是一个数组,figaspect将确定一个数字的宽度和高度,以适合保存数组的高宽比。 数字宽度,以英寸为单位的高度被返回。 一定要创build一个与高度相等的轴,例如

用法示例:

  # 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) 

编辑:我不知道你在找什么。 上面的代码更改了canvas(绘图大小)。 如果你想改变图的matplotlib窗口的大小,那么使用:

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

这确实产生了5×1(wxh)的窗口。

这个答案是基于Yann的回答。 它将设置线性或对数图的纵横比。 我使用了https://stackoverflow.com/a/16290035/2966723中的附加信息来testing这些轴是否为日志规模。;

 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) 

显然你可以使用任何你想要的log版本,我已经使用scipy ,但是numpymath应该没问题。