Funkcja savefig Matplotlib (pyplot) wyświetla pusty obraz

174

Próbuję zapisać wykresy, które wykonuję za pomocą matplotlib; jednak obrazy są zapisywane puste.

Oto mój kod:

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)

Plik tessstttyyy.png jest pusty (próbowano też z .jpg)

tylerthemiler
źródło

Odpowiedzi:

286

Po pierwsze, co się dzieje, kiedy T0 is not None? Sprawdziłbym to, a potem dostosowałbym wartości, do których przekazuję plt.subplot(); może spróbuj wartości 131, 132 i 133 lub wartości, które zależą od tego, czy T0istnieją, czy nie .

Po drugie, po plt.show()wywołaniu tworzona jest nowa figura. Aby sobie z tym poradzić, możesz

  1. Zadzwoń, plt.savefig('tessstttyyy.png', dpi=100)zanim zadzwoniszplt.show()

  2. Zapisz figurę przed sobą show(), wywołując polecenie plt.gcf()„pobierz aktualną figurę”, a następnie możesz wywołać savefig()ten Figureobiekt w dowolnym momencie.

Na przykład:

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

W twoim kodzie „tesssttyyy.png” jest puste, ponieważ zapisuje nową figurę, do której nic nie zostało naniesione.

Yann
źródło
Zapomniałem usunąć część T0 ... zostało to skomentowane wcześniej.
tylerthemiler
7
Szczególny przypadek ma miejsce w jupyternotatnikach z %matplotlib inlinewłączoną opcją: savefigwywołanie musi znajdować się w tej samej komórce, co metoda tworzenia wykresu.
ijoseph
3
Ciekawe do zobaczenia plt.show()generuje nowy obraz. Rzeczywiście, to rozwiązało problem.
user989762
Co ciekawe, jeśli wpiszesz plt.plot, plt.savefig, plt.show jeden po drugim w terminalu takim jak spyder, to nie pokaże rys. Umieść wszystkie polecenia w skrypcie i uruchom je za jednym razem. Pokazuje fabułę.
CKM
Moje rozwiązanie plt.show () plt.draw () fig.set_dpi (200) fig.savefig ('/
image.png
110

plt.show() powinien przyjść później plt.savefig()

Objaśnienie: plt.show()usuwa całość, więc wszystko, co potem wydarzy się na nowej pustej figurze

JAG2024
źródło
4
To jedyny sposób, który mi pomógł.
Yauhen
14
plt.show()czyści całość, więc wszystko później wydarzy się na nowej pustej figurze.
luckydonald
2
To właśnie uratowało mój tyłek! : Naprawdę nie rozumiem, dlaczego trzeba to zaimplementować w taki sposób, że fabuła wymazuje wszystko po wyświetleniu obrazu. Szkoda ...
Romeo Sierra
12

zmiana kolejności funkcji rozwiązała problem :

  • najpierw Zapisz działkę
  • następnie Pokaż fabułę

w następujący sposób:

plt.savefig('heatmap.png')

plt.show()
Behzad Sezari
źródło
2

Wywołanie savefig przed show () działało dla mnie.

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
źródło
1

pozwól mi podać bardziej szczegółowy przykład:

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

wprowadź opis obrazu tutaj

Jayhello
źródło