¿Cómo eliminar el espacio entre las subplots en matplotlib.pyplot?

Estoy trabajando en un proyecto en el que necesito armar una cuadrícula de trazado de 10 filas y 3 columnas. Aunque he podido hacer las plots y organizar las subplots, no pude producir una ttwig agradable sin espacios en blanco como este a continuación a partir de la documentación de gridspec . imagen sin espacio en blanco .

Probé las siguientes publicaciones, pero aún no puedo eliminar completamente el espacio en blanco como en la imagen de ejemplo. ¿Alguien por favor me puede dar alguna orientación? ¡Gracias!

  • Parcelas de diferentes tamaños de Matplotlib
  • ¿Cómo eliminar el espacio “vacío” entre las subplots?

Aquí está mi imagen: Mi imagen

A continuación se muestra mi código. El script completo está aquí en GitHub . Nota: images_2 e images_fool son matrices numpy de imágenes planas con forma (1032, 10), mientras que delta es una matriz de imagen de forma (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') 

Related of "¿Cómo eliminar el espacio entre las subplots en matplotlib.pyplot?"

Una nota al principio: si desea tener un control total sobre el espaciado, evite usar plt.tight_layout() ya que intentará organizar las plots en su figura para que se distribuyan de manera equitativa y agradable. Esto es principalmente bueno y produce resultados agradables, pero ajusta el espacio a su gusto.

La razón por la que el ejemplo de GridSpec que está citando de la galería de ejemplos de Matplotlib funciona tan bien es porque el aspecto de las subplots no está predefinido. Es decir, las subplots simplemente se expandirán en la cuadrícula y dejarán el espacio establecido (en este caso, wspace=0.0, hspace=0.0 ) independiente del tamaño de la figura.

En contraste con eso, usted está trazando imágenes con imshow y el aspecto de la imagen se establece igual de manera predeterminada (equivalente a ax.set_aspect("equal") ). Dicho esto, podría, por supuesto, poner set_aspect("auto") en cada gráfico (y además agregar wspace=0.0, hspace=0.0 como argumentos a GridSpec como en el ejemplo de la galería), lo que produciría un gráfico sin espacios.

Sin embargo, cuando se usan imágenes, tiene mucho sentido mantener una relación de aspecto igual de modo que cada píxel sea tan ancho como alto y se muestre una matriz cuadrada como una imagen cuadrada.
Lo que tendrá que hacer entonces es jugar con el tamaño de la imagen y los márgenes de la figura para obtener el resultado esperado. El argumento de figura a figura es la figura (ancho, alto) en pulgadas y aquí se puede jugar con la proporción de los dos números. Y los parámetros de wspace, hspace, top, bottom, left se pueden ajustar manualmente para obtener el resultado deseado. A continuación se muestra un ejemplo:

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

introduzca la descripción de la imagen aquí

Editar:
Por supuesto, es deseable no tener que modificar los parámetros manualmente. Así que uno podría calcular algunos óptimos según el número de filas y columnas.

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

Intenta agregar a tu código esta línea:

 fig.subplots_adjust(wspace=0, hspace=0) 

Y para cada conjunto de objetos de un eje:

 ax.set_xticklabels([]) ax.set_yticklabels([])