如何在matplotlib中设置纵横比?

jtl*_*lz2 98 python 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')
Run Code Online (Sandbox Code Playgroud)

似乎这些调用被忽略了(我经常在matplotlib中遇到这个问题).

Yan*_*ann 68

第三次的魅力.我的猜测是这是一个bug,而Zhenya的回答表明它已在最新版本中修复.我有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')
Run Code Online (Sandbox Code Playgroud)

这是'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')
Run Code Online (Sandbox Code Playgroud)

生成具有"相等"宽高比的图像图: 在此输入图像描述 和一个'自动'宽高比: 在此输入图像描述

下面"原始答案"中提供的代码为明确控制的宽高比提供了一个起点,但是一旦调用了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')
Run Code Online (Sandbox Code Playgroud)

这会产生如下图: 在此输入图像描述

我可以想象如果您在图中有多个子图,您可能希望将y和x子图的数量作为关键字参数(默认为1)包含在提供的例程中.然后使用这些数字与hspacewspace关键字,就可以使所有的次要情节有正确的纵横比.


小智 35

使用 plt.gca() 获取当前轴并设置纵横比的简单选项

        plt.gca().set_aspect('equal')
Run Code Online (Sandbox Code Playgroud)

代替你的最后一行

  • 我认为最好的答案。简单明了 (3认同)
  • 绝对是最好的,但我会把 1.0 作为参数,因为这个问题很普遍。 (3认同)
  • 这是二维“绘图”的正确答案。 (2认同)

ev-*_*-br 19

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


jtl*_*lz2 6

在通过上述答案获得多年成功后,我发现这不再起作用 - 但我确实在以下位置找到了子图的有效解决方案

https://jdhao.github.io/2017/06/03/change-aspect-ratio-in-mpl

当然完全归功于上面的作者(他也许可以在这里发帖),相关行是:

ratio = 1.0
xleft, xright = ax.get_xlim()
ybottom, ytop = ax.get_ylim()
ax.set_aspect(abs((xright-xleft)/(ybottom-ytop))*ratio)
Run Code Online (Sandbox Code Playgroud)

该链接还对 matplotlib 使用的不同坐标系进行了清晰的解释。

感谢收到的所有精彩答案 - 特别是@Yann's,它将继续成为赢家。


小智 6

就我而言,以下设置效果最好:

plt.figure(figsize=(16,9))
Run Code Online (Sandbox Code Playgroud)

其中 (16,9) 是绘图纵横比。