减少matplotlib图中的左右边距

发布于 2024-09-29 22:45:08 字数 242 浏览 2 评论 0原文

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

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

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

I'm struggling to deal with my plot margins in matplotlib. I've used the code below to produce my chart:

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

However, I get an output figure with lots of white space on either side of the plot. I've searched google and read the matplotlib documentation, but I can't seem to find how to reduce this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

忘羡 2024-10-06 22:45:08

自动执行此操作的一种方法是将 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。 strict_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')

One way to automatically do this is the bbox_inches='tight' kwarg to plt.savefig.

E.g.

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

Another way is to use 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')
赠佳期 2024-10-06 22:45:08

您可以使用 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)

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

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

You can adjust the spacing around matplotlib figures using the subplots_adjust() function:

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

This will work for both the figure on screen and saved to a file, and it is the right function to call even if you don't have multiple plots on the one figure.

The numbers are fractions of the figure dimensions, and will need to be adjusted to allow for the figure labels.

甜妞爱困 2024-10-06 22:45:08

您所需要的只是

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

All you need is

plt.tight_layout()

before your output.

In addition to cutting down the margins, this also tightly groups the space between any subplots:

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()
撩心不撩汉 2024-10-06 22:45:08

有时,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()

更改边框和space GUI here

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

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

Sometimes, the plt.tight_layout() doesn't give me the best view or the view I want. Then why don't plot with arbitrary margin first and do fixing the margin after plot?
Since we got nice WYSIWYG from there.

import matplotlib.pyplot as plt

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

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

Change border and spacing GUI here

Then paste settings into margin function to make it permanent:

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()
无妨# 2024-10-06 22:45:08

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

plt.tight_layout(pad=0.05)

将其减少到很小的幅度。输入 0 对我来说不起作用,因为它也会使子图的框被切掉一点。

In case anybody wonders how how to get rid of the rest of the white margin after applying plt.tight_layout() or fig.tight_layout(): With the parameter pad (which is 1.08 by default), you're able to make it even tighter:
"Padding between the figure edge and the edges of subplots, as a fraction of the font size."
So for example

plt.tight_layout(pad=0.05)

will reduce it to a very small margin. Putting 0 doesn't work for me, as it makes the box of the subplot be cut off a little, too.

没企图 2024-10-06 22:45:08

只需使用 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])

Just use ax = fig.add_axes([left, bottom, width, height])
if you want exact control of the figure layout. eg.

left = 0.05
bottom = 0.05
width = 0.9
height = 0.9
ax = fig.add_axes([left, bottom, width, height])
栖竹 2024-10-06 22:45:08
plt.savefig("circle.png", bbox_inches='tight',pad_inches=-1)
plt.savefig("circle.png", bbox_inches='tight',pad_inches=-1)
葬心 2024-10-06 22:45:08

对于最新的 matplotlib 版本,您可能需要尝试约束布局

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

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

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

太糟糕了 pandas 处理不好...

With recent matplotlib versions you might want to try Constrained Layout:

constrained_layout automatically adjusts subplots and decorations like
legends and colorbars so that they fit in the figure window while
still preserving, as best they can, the logical layout requested by
the user.

constrained_layout is similar to tight_layout, but uses a constraint
solver to determine the size of axes that allows them to fit.

constrained_layout needs to be activated before any axes are added to
a figure.

Too bad pandas does not handle it well...

心在旅行 2024-10-06 22:45:08

受到 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=...) 中使用的元组

inspired by Sammys answer above:

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)

Where figsize is the tuple that you used in fig = pyplot.figure(figsize=...)

孤千羽 2024-10-06 22:45:08

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) 的转换是因为我需要将毫米转换为英寸。

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

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

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

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

The problem with matplotlibs subplots_adjust is that the values you enter are relative to the x and y figsize of the figure. This example is for correct figuresizing for printing of a pdf:

For that, I recalculate the relative spacing to absolute values like this:

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)

for a figure of 'figure.xsize' inches in x-dimension and 'figure.ysize' inches in y-dimension. So the whole figure has a left margin of 5 mm, bottom margin of 4 mm, right of 1 mm and top of 3 mm within the labels are placed. The conversion of (x/25.4) is done because I needed to convert mm to inches.

Note that the pure chart size of x will be "figure.xsize - left margin - right margin" and the pure chart size of y will be "figure.ysize - bottom margin - top margin" in inches

Other sniplets (not sure about these ones, I just wanted to provide the other parameters)

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

and

pyplot.savefig("outputname.eps", dpi = 100)
离鸿 2024-10-06 22:45:08

对我来说,上面的答案不适用于 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

For me, the answers above did not work with matplotlib.__version__ = 1.4.3 on Win7. So, if we are only interested in the image itself (i.e., if we don't need annotations, axis, ticks, title, ylabel etc), then it's better to simply save the numpy array as image instead of 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)

Also, using opencv drawing functions (cv2.line, cv2.polylines), we can do some drawings directly on the numpy array. http://docs.opencv.org/2.4/modules/core/doc/drawing_functions.html

迷爱 2024-10-06 22:45:08
# import pyplot
import matplotlib.pyplot as plt

# your code to plot the figure

# set tight margins
plt.margins(0.015, tight=True)
# import pyplot
import matplotlib.pyplot as plt

# your code to plot the figure

# set tight margins
plt.margins(0.015, tight=True)
七婞 2024-10-06 22:45:08

用于子图的紧凑 matplotlib 模板

由于每次设置新图时我都会遇到同样的麻烦,因此我决定在 stackoverflow 上记录一个模板。

模板

import matplotlib.pylab as plt

def plot_figure_tempalte():
    nrows=2
    ncols=3

    fig, axs = plt.subplots(
        nrows=nrows, ncols=ncols, figsize=(14.9, 10.5),  # A6: 145mm x 105mm
        gridspec_kw=dict(
            left=.1, bottom=.05, right=.99, top=.8, wspace=.1, hspace=.3
        )
    )

    for rr in range(nrows):
        for cc in range(ncols):
            axs[rr, cc].set_title(f"row {rr}, col {cc}")

    fig.savefig("output.png", dpi=300)


if __name__ == "__main__":
    plot_figure_tempalte()

output.png

在此处输入图像描述

compact matplotlib template for subplots

As I have the same hussle each time I set up a new plot, I decided to document a template for this on stackoverflow.

template

import matplotlib.pylab as plt

def plot_figure_tempalte():
    nrows=2
    ncols=3

    fig, axs = plt.subplots(
        nrows=nrows, ncols=ncols, figsize=(14.9, 10.5),  # A6: 145mm x 105mm
        gridspec_kw=dict(
            left=.1, bottom=.05, right=.99, top=.8, wspace=.1, hspace=.3
        )
    )

    for rr in range(nrows):
        for cc in range(ncols):
            axs[rr, cc].set_title(f"row {rr}, col {cc}")

    fig.savefig("output.png", dpi=300)


if __name__ == "__main__":
    plot_figure_tempalte()

output.png

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文