Matplotlib (pyplot) savefig genera una imagen en blanco

176

Estoy tratando de guardar tramas que hago usando matplotlib; sin embargo, las imágenes se guardan en blanco.

Aquí está mi código:

plt.subplot(121)
plt.imshow(dataStack, cmap=mpl.cm.bone)

plt.subplot(122)
y = copy.deepcopy(tumorStack)
y = np.ma.masked_where(y == 0, y)

plt.imshow(dataStack, cmap=mpl.cm.bone)
plt.imshow(y, cmap=mpl.cm.jet_r, interpolation='nearest')

if T0 is not None:
    plt.subplot(123)
    plt.imshow(T0, cmap=mpl.cm.bone)

    #plt.subplot(124)
    #Autozoom

#else:
    #plt.subplot(124)
    #Autozoom

plt.show()
plt.draw()
plt.savefig('tessstttyyy.png', dpi=100)

Y tessstttyyy.png está en blanco (también probado con .jpg)

tylerthemiler
fuente

Respuestas:

286

Primero, ¿qué pasa cuando T0 is not None? Lo probaría, luego ajustaría los valores a los que paso plt.subplot(); quizás pruebe los valores 131, 132 y 133, o valores que dependen de si T0existen o no .

En segundo lugar, después de que plt.show()se llama, se crea una nueva figura. Para lidiar con esto, puedes

  1. Llama plt.savefig('tessstttyyy.png', dpi=100)antes de llamarplt.show()

  2. Guarde la cifra que tiene delante show()llamando plt.gcf()a "obtener la cifra actual", luego puede llamar savefig()a este Figureobjeto en cualquier momento.

Por ejemplo:

fig1 = plt.gcf()
plt.show()
plt.draw()
fig1.savefig('tessstttyyy.png', dpi=100)

En su código, 'tesssttyyy.png' está en blanco porque está guardando la nueva figura, a la que no se ha trazado nada.

Yann
fuente
Olvidé eliminar la parte T0 ... se comentó anteriormente.
tylerthemiler
77
Un caso especial de esto ocurre en los jupytercuadernos con %matplotlib inlinehabilitado: la savefigllamada debe estar en la misma celda que el método de creación del diagrama.
ijoseph
3
Interesante ver plt.show()genera una nueva imagen. De hecho, esto resolvió el problema.
user989762
Curiosamente, si escribe plt.plot, plt.savefig, plt.show uno por uno en un terminal como spyder, no mostrará fig. Ponga todos los comandos en un script y ejecútelos de una vez. Muestra la trama.
CKM
Mi solución plt.show () plt.draw () fig.set_dpi (200) fig.savefig ('/ image.png')
EduardoUstarez
110

plt.show() debería venir después plt.savefig()

Explicación: plt.show()borra todo el asunto, por lo que cualquier cosa posterior sucederá en una nueva figura vacía

JAG2024
fuente
44
Esa es la única forma que me ayudó.
Yauhen
14
plt.show()borra todo, por lo que cualquier cosa posterior sucederá en una nueva figura vacía.
luckydonald
2
¡Esto es lo que me salvó el trasero! : DI realmente no entiendo por qué uno tuvo que implementarlo de manera que la trama borre todo al mostrar la imagen. Lástima ...
Romeo Sierra
13

cambiar el orden de las funciones me solucionó el problema :

  • primero guardar la trama
  • luego muestra la trama

de la siguiente manera:

plt.savefig('heatmap.png')

plt.show()
Behzad Sezari
fuente
2

Llamar a savefig antes de show () funcionó para mí.

fig ,ax = plt.subplots(figsize = (4,4))
sns.barplot(x='sex', y='tip', color='g', ax=ax,data=tips)
sns.barplot(x='sex', y='tip', color='b', ax=ax,data=tips)
ax.legend(['Male','Female'], facecolor='w')

plt.savefig('figure.png')
plt.show()
Krish
fuente
1

déjenme dar un ejemplo más detallado:

import numpy as np
import matplotlib.pyplot as plt


def draw_result(lst_iter, lst_loss, lst_acc, title):
    plt.plot(lst_iter, lst_loss, '-b', label='loss')
    plt.plot(lst_iter, lst_acc, '-r', label='accuracy')

    plt.xlabel("n iteration")
    plt.legend(loc='upper left')
    plt.title(title)
    plt.savefig(title+".png")  # should before plt.show method

    plt.show()


def test_draw():
    lst_iter = range(100)
    lst_loss = [0.01 * i + 0.01 * i ** 2 for i in xrange(100)]
    # lst_loss = np.random.randn(1, 100).reshape((100, ))
    lst_acc = [0.01 * i - 0.01 * i ** 2 for i in xrange(100)]
    # lst_acc = np.random.randn(1, 100).reshape((100, ))
    draw_result(lst_iter, lst_loss, lst_acc, "sgd_method")


if __name__ == '__main__':
    test_draw()

ingrese la descripción de la imagen aquí

Jayhello
fuente