减少matplotlib图中的左右边距

Posted

技术标签:

【中文标题】减少matplotlib图中的左右边距【英文标题】:Reduce left and right margins in matplotlib plot 【发布时间】:2011-05-01 19:53:07 【问题描述】:

我正在努力处理我在 matplotlib 中的绘图边距。我使用下面的代码来制作我的图表:

plt.imshow(g)
c = plt.colorbar()
c.set_label("Number of Slabs")
plt.savefig("OutputToUse.png")

但是,我得到一个输出图,图的两边都有很多空白。我搜索了谷歌并阅读了 matplotlib 文档,但我似乎找不到如何减少这种情况。

【问题讨论】:

问题是imshow图形的extent中的空白数量,还是图形周围生成的png中边框空白的数量,由savefig生成?跨度> 我认为两者都 - 在查看窗口和 PNG 中似乎都有很多空间。但是,重要的输出是savefig 生成的 png 文件 - 所以这就是我想要排序的内容。 后来我刚刚在 GIMP 中裁剪了它们。 :// ax.margins(x=0.01) 就是你要找的东西! 【参考方案1】:

请删除程序中的键“sharex=True 和 sharey=True”。我想你没有在这里上传完整的程序。希望我的回答对您的查询有所帮助。

【讨论】:

【参考方案2】:
# import pyplot
import matplotlib.pyplot as plt

# your code to plot the figure

# set tight margins
plt.margins(0.015, tight=True)

【讨论】:

【参考方案3】:

对于最近的 matplotlib 版本,您可能想尝试Constrained Layout:

constrained_layout 自动调整子图和装饰,例如 图例和颜色条,以便它们适合图形窗口,同时 仍然尽最大努力保留所要求的逻辑布局 用户。

constrained_layout 类似于tight_layout,但使用了一个约束 求解器来确定允许它们适合的轴的大小。

constrained_layout 需要在添加任何轴之前激活 一个数字。

太糟糕了pandas does not handle it well...

【讨论】:

虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review【参考方案4】:

有时,plt.tight_layout() 无法提供最佳视图或我想要的视图。那么为什么不先绘制任意边距,然后在绘制后固定边距呢? 因为我们从那里得到了很好的所见即所得。

import matplotlib.pyplot as plt

fig,ax = plt.subplots(figsize=(8,8))

plt.plot([2,5,7,8,5,3,5,7,])
plt.show()

然后将设置粘贴到边距功能中以使其永久化:

fig,ax = plt.subplots(figsize=(8,8))

plt.plot([2,5,7,8,5,3,5,7,])
fig.subplots_adjust(
    top=0.981,
    bottom=0.049,
    left=0.042,
    right=0.981,
    hspace=0.2,
    wspace=0.2
)
plt.show()

【讨论】:

这真是一个很好的提示 - 我从来没有发现那里的“导出”按钮.. 谢谢。 这真的帮助我处理了子图的边界【参考方案5】:

如果有人想知道在应用plt.tight_layout()fig.tight_layout() 后如何去除剩余的白边:使用参数pad(默认为1.08),您可以让它更紧: “图形边缘和子图边缘之间的填充,作为字体大小的一部分。” 比如

plt.tight_layout(pad=0.05)

会将其减少到非常小的余量。输入0 对我不起作用,因为它也会使子图的框被切掉一点。

【讨论】:

我使用pad=0.5 代替,因为我立即遇到了这种剪辑内容的情况:如果最高 y 轴刻度线靠近绘图区域的顶部,那么它的标签将被切断。不错的提示,我是来找这个的。【参考方案6】:

自动执行此操作的一种方法是将bbox_inches='tight' kwarg 转换为plt.savefig

例如

import matplotlib.pyplot as plt
import numpy as np
data = np.arange(3000).reshape((100,30))
plt.imshow(data)
plt.savefig('test.png', bbox_inches='tight')

另一种方法是使用fig.tight_layout()

import matplotlib.pyplot as plt
import numpy as np

xs = np.linspace(0, 1, 20); ys = np.sin(xs)

fig = plt.figure()
axes = fig.add_subplot(1,1,1)
axes.plot(xs, ys)

# This should be called after all axes have been added
fig.tight_layout()
fig.savefig('test.png')

【讨论】:

有什么办法让它成为默认值吗? 如果您有多个子图并且想要保存每个子图,您也可以将其与fig.savefig() 一起使用。 (plt.savefig() 在这种情况下不起作用。) 所有这一切都是在图像被渲染后裁剪;如果您尝试强制执行特定分辨率,则图像会变小 @detly - 是的。这正是它所做的(尽管它也可以“裁剪”出来并使图像更大)。对于您想要的内容,请查看fig.tight_layout()。最初编写此答案时该功能不存在,否则我会更突出地提及它。 如果有人有问题,请使用fig = plt.gcf()【参考方案7】:

只需使用ax = fig.add_axes([left, bottom, width, height]) 如果您想精确控制图形布局。例如。

left = 0.05
bottom = 0.05
width = 0.9
height = 0.9
ax = fig.add_axes([left, bottom, width, height])

【讨论】:

【参考方案8】:

受上述 Sammys 回答的启发:

margins =   #     vvv margin in inches
    "left"   :     1.5 / figsize[0],
    "bottom" :     0.8 / figsize[1],
    "right"  : 1 - 0.3 / figsize[0],
    "top"    : 1 - 1   / figsize[1]

fig.subplots_adjust(**margins)

其中 figsize 是您在 fig = pyplot.figure(figsize=...) 中使用的元组

【讨论】:

【参考方案9】:

对我来说,上面的答案不适用于 Win7 上的 matplotlib.__version__ = 1.4.3。因此,如果我们只对图像本身感兴趣(即,如果我们不需要注释、轴、刻度、标题、ylabel 等),那么最好将 numpy 数组简单地保存为图像而不是savefig

from pylab import *

ax = subplot(111)
ax.imshow(some_image_numpyarray)
imsave('test.tif', some_image_numpyarray)

# or, if the image came from tiff or png etc
RGBbuffer = ax.get_images()[0].get_array()
imsave('test.tif', RGBbuffer)

另外,使用opencv绘图函数(cv2.line,cv2.polylines),我们可以直接在numpy数组上做一些绘图。 http://docs.opencv.org/2.4/modules/core/doc/drawing_functions.html

【讨论】:

【参考方案10】:

你只需要

plt.tight_layout()

在你的输出之前。

除了减少边距之外,这还紧密地组合了任何子图之间的空间:

x = [1,2,3]
y = [1,4,9]
import matplotlib.pyplot as plt
fig = plt.figure()
subplot1 = fig.add_subplot(121)
subplot1.plot(x,y)
subplot2 = fig.add_subplot(122)
subplot2.plot(y,x)
fig.tight_layout()
plt.show()

【讨论】:

我认为这确实是最好的方法。它不需要像 `bbox='tight' 那样保存图形,并修复了狭窄图形中的各种其他布局问题。 这应该是正确的答案,因为它的行为符合您的预期,因为它适用于图形而不是图像。 奇怪的是,与 bbox_inches='tight' 相比,这也改变了 实际绘图 的宽度(即峰更靠近),它只是剪裁了边缘周围的空白区域但不理会情节。我用plt.figure(figsize=(10,3)) 创建了这个图。【参考方案11】:

matplotlibs subplots_adjust 的问题是你输入的值是相对于图形的 x 和 y figsize 的。此示例用于正确打印 pdf 的数字:

为此,我将相对间距重新计算为绝对值,如下所示:

pyplot.subplots_adjust(left = (5/25.4)/figure.xsize, bottom = (4/25.4)/figure.ysize, right = 1 - (1/25.4)/figure.xsize, top = 1 - (3/25.4)/figure.ysize)

对于 x 维度的“figure.xsize”英寸和 y 维度的“figure.ysize”英寸的图形。因此,整个图形的左边距为 5 毫米,下边距为 4 毫米,右边为 1 毫米,顶部为 3 毫米,放置在标签内。 (x/25.4) 的转换已经完成,因为我需要将 mm 转换为英寸。

请注意,x 的纯图表大小将为“figure.xsize - 左边距 - 右边距”,y 的纯图表大小将为“figure.ysize - 下边距 - 上边距”,以英寸为单位

其他片段(不确定这些片段,我只是想提供其他参数)

pyplot.figure(figsize = figureSize, dpi = None)

pyplot.savefig("outputname.eps", dpi = 100)

【讨论】:

你从哪里得到xsizeysize。我使用这些属性,我得到AttributeError: 'Figure' object has no attribute 'xsize'【参考方案12】:

您可以使用 subplots_adjust() 函数调整 matplotlib 图形周围的间距:

import matplotlib.pyplot as plt
plt.plot(whatever)
plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1)

这适用于屏幕上的图形和保存到文件中,即使您在一个图形上没有多个绘图,它也是正确调用的函数。

数字是图形尺寸的分数,需要调整以允许图形标签。

【讨论】:

分配给参数的值而不是改变多少,它们是设置边距的地方。换句话说,如果你想把右边距提高 10%,你应该设置 right=0.9,而不是 right=0.1 matplotlib.sourceforge.net/api/… 有必要指出,显然您可以在 plt.subplots_adjust() 中指定负值。这样做甚至可以让您在图形区域之外进行绘制,还可以处理烦人的边距。 这也适用于GridSpec 对象,方法是调用update 方法(参见***.com/a/20058199/1030876)。【参考方案13】:
plt.savefig("circle.png", bbox_inches='tight',pad_inches=-1)

【讨论】:

"pad_inches=-1" 导致我的 savefig 只生成部分图形。 savefig 函数中使用参数是优雅的,但是pad_inches 的负值不一定在每种情况下都需要。 设置为0,有帮助

以上是关于减少matplotlib图中的左右边距的主要内容,如果未能解决你的问题,请参考以下文章

在Matplotlib中为子图添加边距[重复]

如何减少/删除分组 UITableView 中的左/右手边距?

Python matplotlib图例如何减少框架左边缘和标记之间的距离

Matplotlib 使用

Python可视化-当Matplotlib遇上matplotx

如何在 Matplotlib 中扩展图形底部的边距?