Python 轴类 - 以给定单位明确设置轴的大小(宽度/高度)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44970010/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 00:42:11  来源:igfitidea点击:

Axes class - set explicitly size (width/height) of axes in given units

pythonmatplotlibplotaxisaxes

提问by Gabriel

I want to to create a figure using matplotlib where I can explicitly specify the size of the axes, i.e. I want to set the width and height of the axes bbox.

我想使用 matplotlib 创建一个图形,我可以在其中明确指定轴的大小,即我想设置轴 bbox 的宽度和高度。

I have looked around all over and I cannot find a solution for this. What I typically find is how to adjust the size of the complete Figure (including ticks and labels), for example using fig, ax = plt.subplots(figsize=(w, h))

我环顾四周,找不到解决方案。我通常发现的是如何调整完整图形的大小(包括刻度和标签),例如使用fig, ax = plt.subplots(figsize=(w, h))

This is very important for me as I want to have a 1:1 scale of the axes, i.e. 1 unit in paper is equal to 1 unit in reality. For example, if xrange is 0 to 10 with major tick = 1 and x axis is 10cm, then 1 major tick = 1cm. I will save this figure as pdf to import it to a latex document.

这对我来说非常重要,因为我希望轴的比例为 1:1,即纸上的 1 个单位实际上等于 1 个单位。例如,如果 xrange 为 0 到 10,主刻度 = 1,x 轴为 10cm,则 1 个主刻度 = 1cm。我将此图保存为 pdf 以将其导入乳胶文档。

This questionbrought up a similar topic but the answer does not solve my problem (using plt.gca().set_aspect('equal', adjustable='box')code)

这个问题提出了一个类似的话题,但答案并没有解决我的问题(使用plt.gca().set_aspect('equal', adjustable='box')代码)

From this other questionI see that it is possible to get the axes size, but not how to modify them explicitly.

从this other question我看到可以获取轴大小,但不能明确修改它们。

Any ideas how I can set the axes box size and not just the figure size. The figure size should adapt to the axes size.

任何想法如何设置轴框大小而不仅仅是图形大小。图形大小应适应轴大小。

Thanks!

谢谢!

For those familiar with pgfplotsin latex, it will like to have something similar to the scale only axisoption (see herefor example).

对于那些熟悉latex 中的pgfplots的人,它会希望有类似于该scale only axis选项的东西(例如,请参见此处)。

回答by ImportanceOfBeingErnest

The axes size is determined by the figure size and the figure spacings, which can be set using figure.subplots_adjust(). In reverse this means that you can set the axes size by setting the figure size taking into acount the figure spacings:

轴大小由图形大小和图形间距决定,可以使用 进行设置figure.subplots_adjust()。相反,这意味着您可以通过设置图形大小来设置轴大小,同时考虑图形间距:

import matplotlib.pyplot as plt

def set_size(w,h, ax=None):
    """ w, h: width, height in inches """
    if not ax: ax=plt.gca()
    l = ax.figure.subplotpars.left
    r = ax.figure.subplotpars.right
    t = ax.figure.subplotpars.top
    b = ax.figure.subplotpars.bottom
    figw = float(w)/(r-l)
    figh = float(h)/(t-b)
    ax.figure.set_size_inches(figw, figh)

fig, ax=plt.subplots()

ax.plot([1,3,2])

set_size(5,5)

plt.show()

回答by Max

It appears that Matplotlib has helper classes that allow you to define axes with a fixed size Demo fixed size axes

似乎 Matplotlib 具有帮助类,允许您定义具有固定大小的轴 Demo 固定大小的轴

回答by BongaCodeBuddy

I have found that ImportanceofBeingErnests answer which modifies that figure size to adjust the axes size provides inconsistent results with the paticular matplotlib settings I use to produce publication ready plots. Slight errors were present in the final figure size, and I was unable to find a way to solve the issue with his approach. For most use cases I think this is not a problem, however the errors were noticeable when combining multiple pdf's for publication.

我发现 ImportanceofBeingErnests 答案修改图形大小以调整轴大小提供了与我用来生成发布就绪图的特定 matplotlib 设置不一致的结果。最终图形大小存在轻微错误,我无法通过他的方法找到解决问题的方法。对于大多数用例,我认为这不是问题,但是在组合多个 pdf 进行发布时错误很明显。

In lieu of developing a minimum working example to find the real issue I am having with the figure resizing approach I instead found a work around which uses the fixed axes size utilising the divider class.

代替开发一个最小的工作示例来找到我在调整图形大小方法中遇到的真正问题,我找到了一个解决方法,该方法使用分隔符类使用固定轴大小。

from mpl_toolkits.axes_grid1 import Divider, Size
def fix_axes_size_incm(axew, axeh):
    axew = axew/2.54
    axeh = axeh/2.54

    #lets use the tight layout function to get a good padding size for our axes labels.
    fig = plt.gcf()
    ax = plt.gca()
    fig.tight_layout()
    #obtain the current ratio values for padding and fix size
    oldw, oldh = fig.get_size_inches()
    l = ax.figure.subplotpars.left
    r = ax.figure.subplotpars.right
    t = ax.figure.subplotpars.top
    b = ax.figure.subplotpars.bottom

    #work out what the new  ratio values for padding are, and the new fig size.
    neww = axew+oldw*(1-r+l)
    newh = axeh+oldh*(1-t+b)
    newr = r*oldw/neww
    newl = l*oldw/neww
    newt = t*oldh/newh
    newb = b*oldh/newh

    #right(top) padding, fixed axes size, left(bottom) pading
    hori = [Size.Scaled(newr), Size.Fixed(axew), Size.Scaled(newl)]
    vert = [Size.Scaled(newt), Size.Fixed(axeh), Size.Scaled(newb)]

    divider = Divider(fig, (0.0, 0.0, 1., 1.), hori, vert, aspect=False)
    # the width and height of the rectangle is ignored.

    ax.set_axes_locator(divider.new_locator(nx=1, ny=1))

    #we need to resize the figure now, as we have may have made our axes bigger than in.
    fig.set_size_inches(neww,newh)

Things worth noting:

值得注意的事情:

  • Once you call set_axes_locator()on an axis instance you break the tight_layout()function.
  • The original figure size you choose will be irrelevent, and the final figure size is determined by the axes size you choose and the size of the labels/tick labels/outward ticks.
  • This approach doesn't work with colour scale bars.
  • This is my first ever stack overflow post.
  • 一旦您调用set_axes_locator()轴实例,您就会破坏该tight_layout()功能。
  • 您选择的原始图形大小将无关紧要,最终图形大小由您选择的轴大小和标签/刻度标签/向外刻度的大小决定。
  • 这种方法不适用于颜色比例尺。
  • 这是我有史以来第一篇堆栈溢出帖子。