python numpy matplotlib

python - ¿Cómo eliminar el espacio entre subtramas en matplotlib.pyplot?



numpy (2)

Intente agregar a su 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([])

Estoy trabajando en un proyecto en el que necesito armar una cuadrícula de 10 filas y 3 columnas. Aunque pude hacer las tramas y organizar las subtramas, no pude producir una buena trama sin espacios en blanco como este a continuación a partir de la documentación de gridspec . .

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

Aquí está mi imagen:

Abajo está 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 imágenes 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'')


Una nota al principio: si desea tener un control total sobre el espaciado, evite usar plt.tight_layout() ya que tratará de ordenar las parcelas en su figura para que estén distribuidas de manera equitativa y agradable. Esto está muy bien y produce resultados agradables, pero ajusta el espacio a su voluntad.

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 subtramas no está predefinido. Es decir, las subtramas simplemente se expandirán en la cuadrícula y dejarán el espacio establecido (en este caso wspace=0.0, hspace=0.0 ) independientemente del tamaño de la figura.

En contraste con eso, está trazando imágenes con imshow y el aspecto de la imagen se establece igual por defecto (equivalente a ax.set_aspect("equal") ). Dicho esto, por supuesto, podría poner set_aspect("auto") en cada gráfico (y agregar adicionalmente wspace=0.0, hspace=0.0 como argumentos para 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 una matriz cuadrada se muestre como una imagen cuadrada.
Lo que deberá hacer es jugar con el tamaño de la imagen y los márgenes de la figura para obtener el resultado esperado. El argumento de figsize para figurar es la figura (ancho, alto) en pulgadas y aquí se puede jugar con la relación de los dos números. Y los parámetros de subtrama 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()

Editar:
Por supuesto, es deseable no tener que ajustar los parámetros manualmente. Entonces uno podría calcular algunos óptimos de acuerdo con 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()