Wywołanie pylab.savefig bez wyświetlania w ipythonie

111

Muszę utworzyć figurę w pliku bez wyświetlania jej w notatniku IPython. Nie mam jasności co do interakcji między IPythoniw matplotlib.pylabtym zakresie. Ale kiedy dzwonię pylab.savefig("test.png")do bieżącej liczby, oprócz zapisania w test.png. Często jest to niepożądane podczas automatyzacji tworzenia dużego zestawu plików wydruku. Lub w sytuacji, gdy potrzebny jest plik pośredni do zewnętrznego przetwarzania przez inną aplikację.

Nie jestem pewien, czy jest to matplotliblub IPythonnotebook pytanie.

tnt
źródło
Odpowiedź @staticfloat działała dla mnie nawet poza notebookiem i podczas korzystania z matplotlib przez JuliaLang; używającioff
Vass

Odpowiedzi:

173

To jest pytanie matplotlib i możesz obejść ten problem, używając zaplecza, które nie wyświetla się użytkownikowi, np. „Agg”:

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

plt.plot([1,2,3])
plt.savefig('/tmp/test.png')

EDYCJA: Jeśli nie chcesz stracić możliwości wyświetlania wykresów, wyłącz tryb interaktywny i dzwoń tylko plt.show()wtedy, gdy jesteś gotowy do wyświetlenia wykresów:

import matplotlib.pyplot as plt

# Turn interactive plotting off
plt.ioff()

# Create a new figure, plot into it, then close it so it never gets displayed
fig = plt.figure()
plt.plot([1,2,3])
plt.savefig('/tmp/test0.png')
plt.close(fig)

# Create a new figure, plot into it, then don't close it so it does get displayed
plt.figure()
plt.plot([1,3,2])
plt.savefig('/tmp/test1.png')

# Display all "open" (non-closed) figures
plt.show()
staticfloat
źródło
2
Ok - ale generalnie chcę zachować wbudowane kreślenie w iPythonie. To, co sugerujesz, działa dobrze, jeśli całkowicie przełączysz backend. Pytanie brzmi, jak uwzględnić ogólną sytuację kreślenia w wierszu z wyjątkowym przypadkiem zapisywania liczb (bez ich wyświetlania). Zgodnie z twoją sugestią próbowałem ponownie załadować moduły i tymczasowo zmienić backend, ale bez powodzenia. Jakieś pomysły, jak tymczasowo zmienić backend w sesji notebooka iPython?
tnt
1
Zaktualizowałem pytanie, aby omówić interaktywne kreślenie close()oraz show()polecenia i , które powinny rozwiązać twój problem. Jak odkryłeś, zmiana backendów w locie nie jest obsługiwana.
staticfloat
3
Dziękuję za doskonałą opinię. Wygląda na to, że plt.close (rys.) Jest kluczowym poleceniem dla moich potrzeb. Nadal nie jestem pewien co do ioff, ponieważ nie wydaje się, aby miało to wpływ na operację; ale chyba czegoś mi brakuje. Dzięki jeszcze raz.
tnt
1
Przepis, który podałem, jest ogólny; jeśli nie pracujesz w notatniku ipython, funkcja plt.ioff () jest ważna, aby zapobiec migotaniu liczb na ekranie i poza nim, ponieważ w wierszu poleceń liczby ipython są drukowane natychmiast po wywołaniu, plt.plot()jeśli tryb interaktywny jest włączony. Wyłączenie trybu interaktywnego opóźnia wyświetlanie wykresów do plt.show(). Ponieważ używasz notatnika ipython, tryb interaktywny jest traktowany inaczej.
staticfloat
Dla mnie matplotlib.use('Agg')sam załatwił sprawę. Nie potrzebowałem żadnego plt.show()lub plt.ioff()w moim kodzie.
Zhanwen Chen
67

Nie musimy plt.ioff()lub plt.show()(jeśli używamy %matplotlib inline). Możesz przetestować powyższy kod bez plt.ioff(). plt.close()ma zasadniczą rolę. Spróbuj tego:

%matplotlib inline
import pylab as plt

# It doesn't matter you add line below. You can even replace it by 'plt.ion()', but you will see no changes.
## plt.ioff()

# Create a new figure, plot into it, then close it so it never gets displayed
fig = plt.figure()
plt.plot([1,2,3])
plt.savefig('test0.png')
plt.close(fig)

# Create a new figure, plot into it, then don't close it so it does get displayed
fig2 = plt.figure()
plt.plot([1,3,2])
plt.savefig('test1.png')

Jeśli uruchomisz ten kod w iPythonie, wyświetli się drugi wykres, a jeśli dodasz plt.close(fig2)go na końcu, nic nie zobaczysz.

Podsumowując, jeśli zamkniesz figurę plt.close(fig), nie zostanie ona wyświetlona.

Mojtaba Khodadadi
źródło
5
Rzeczywiście lepsze rozwiązanie! Generuję i zapisuję wiele wykresów w pętli. Z plt.ioffdostanę RuntimeWarning: More than 20 figures have been opened.... plt.closerozwiązałem to.
Nagasaki