如何删除matplotlib.pyplot中子图之间的空间? [英] How to remove the space between subplots in matplotlib.pyplot?

查看:132
本文介绍了如何删除matplotlib.pyplot中子图之间的空间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在一个项目中,我需要将10行3列的绘图网格放在一起.尽管我已经能够进行绘制并安排子图,但是如果没有空白,就无法生成一个不错的图,例如下面的.

I am working on a project in which I need to put together a plot grid of 10 rows and 3 columns. Although I have been able to make the plots and arrange the subplots, I was not able to produce a nice plot without white space such as this one below from .

我尝试了以下文章,但仍然无法完全消除空白,如示例图像中所示.有人可以给我一些指导吗?谢谢!

I tried the following posts, but still not able to completely remove the white space as in the example image. Can someone please give me some guidance? Thanks!

这是我的图片:

下面是我的代码. 完整的脚本在GitHub上. 注意:images_2和images_fool都是形状为(1032,10)的平坦图像的numpy数组,而delta是形状(28,28)的图像数组.

Below is my code. The full script is here on GitHub. Note: images_2 and images_fool are both numpy arrays of flattened images with shape (1032, 10), while delta is an image array of shape (28, 28).

def plot_im(array=None, ind=0):
    """A function to plot the image given a images matrix, type of the matrix: \
    either original or fool, and the order of images in the matrix"""
    img_reshaped = array[ind, :].reshape((28, 28))
    imgplot = plt.imshow(img_reshaped)

# Output as a grid of 10 rows and 3 cols with first column being original, second being
# delta and third column being adversaril
nrow = 10
ncol = 3
n = 0

from matplotlib import gridspec
fig = plt.figure(figsize=(30, 30)) 
gs = gridspec.GridSpec(nrow, ncol, width_ratios=[1, 1, 1]) 

for row in range(nrow):
    for col in range(ncol):
        plt.subplot(gs[n])
        if col == 0:
            #plt.subplot(nrow, ncol, n)
            plot_im(array=images_2, ind=row)
        elif col == 1:
            #plt.subplot(nrow, ncol, n)
            plt.imshow(w_delta)
        else:
            #plt.subplot(nrow, ncol, n)
            plot_im(array=images_fool, ind=row)
        n += 1

plt.tight_layout()
#plt.show()
plt.savefig('grid_figure.pdf')

推荐答案

开始时的注释:如果要完全控制间距,请避免使用plt.tight_layout(),因为它将尝试将图中的图形排列为均匀且均匀地分布.这通常很好,并且会产生令人愉悦的效果,但是会随意调整间距.

A note at the beginning: If you want to have full control over spacing, avoid using plt.tight_layout() as it will try to arange the plots in your figure to be equally and nicely distributed. This is mostly fine and produces pleasant results, but adjusts the spacing at its will.

您从Matplotlib示例库中引用的GridSpec示例之所以运行良好,是因为子图的方面未预定义.也就是说,子图将仅在网格上扩展,而与图形大小无关地保留设置的间距(在本例中为wspace=0.0, hspace=0.0).

The reason the GridSpec example you're quoting from the Matplotlib example gallery works so well is because the subplots' aspect is not predefined. That is, the subplots will simply expand on the grid and leave the set spacing (in this case wspace=0.0, hspace=0.0) independent of the figure size.

与使用imshow绘制图像相反,默认情况下图像的纵横比设置为相等(等效于ax.set_aspect("equal")).就是说,您当然可以在每个图上放置set_aspect("auto")(并像在图库示例中一样,将wspace=0.0, hspace=0.0作为参数添加到GridSpec),这将生成一个没有间距的图.

In contrast to that you are plotting images with imshow and the image's aspect is set equal by default (equivalent to ax.set_aspect("equal")). That said, you could of course put set_aspect("auto") to every plot (and additionally add wspace=0.0, hspace=0.0 as arguments to GridSpec as in the gallery example), which would produce a plot without spacings.

但是,在使用图像时,保持相等的宽高比非常有意义,以使每个像素都一样高,并且将正方形阵列显示为正方形图像.
然后,您需要做的就是使用图像大小和图形边距来获得预期的结果. Figure的figsize自变量是以英寸为单位的数字(宽度,高度),在这里可以使用两个数字的比率.子图参数 wspace, hspace, top, bottom, left 可以手动调整以提供所需的结果. 下面是一个示例:

However when using images it makes a lot of sense to keep an equal aspect ratio such that every pixel is as wide as high and a square array is shown as a square image.
What you will need to do then is to play with the image size and the figure margins to obtain the expected result. The figsize argument to figure is the figure (width, height) in inch and here the ratio of the two numbers can be played with. And the subplot parameters wspace, hspace, top, bottom, left can be manually adjusted to give the desired result. Below is an example:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import gridspec

nrow = 10
ncol = 3

fig = plt.figure(figsize=(4, 10)) 

gs = gridspec.GridSpec(nrow, ncol, width_ratios=[1, 1, 1],
         wspace=0.0, hspace=0.0, top=0.95, bottom=0.05, left=0.17, right=0.845) 

for i in range(10):
    for j in range(3):
        im = np.random.rand(28,28)
        ax= plt.subplot(gs[i,j])
        ax.imshow(im)
        ax.set_xticklabels([])
        ax.set_yticklabels([])

#plt.tight_layout() # do not use this!!
plt.show()

修改:
当然希望不必手动调整参数.因此,可以根据行和列的数量来计算一些最优值.


It is of course desireable not having to tweak the parameters manually. So one could calculate some optimal ones according to the number of rows and columns.

nrow = 7
ncol = 7

fig = plt.figure(figsize=(ncol+1, nrow+1)) 

gs = gridspec.GridSpec(nrow, ncol,
         wspace=0.0, hspace=0.0, 
         top=1.-0.5/(nrow+1), bottom=0.5/(nrow+1), 
         left=0.5/(ncol+1), right=1-0.5/(ncol+1)) 

for i in range(nrow):
    for j in range(ncol):
        im = np.random.rand(28,28)
        ax= plt.subplot(gs[i,j])
        ax.imshow(im)
        ax.set_xticklabels([])
        ax.set_yticklabels([])

plt.show()

这篇关于如何删除matplotlib.pyplot中子图之间的空间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆