繁体   English   中英

如何在 matplotlib 中设置纵横比?

[英]How can I set the aspect ratio in 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 版本,我创建了以下解决方案:

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关键字,您可以使所有子图具有正确的纵横比。

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

        plt.gca().set_aspect('equal')

代替你的最后一行

您正在运行的matplotlib版本是什么? 我最近不得不升级到1.1.0 ,有了它, add_subplot(111,aspect='equal')对我add_subplot(111,aspect='equal')

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

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)

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

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

这个答案基于 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)

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

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

plt.figure(figsize=(16,9))

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

您应该尝试使用 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))

这确实会产生一个 5x1 (wxh) 的窗口。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM