Zapisz wykres do pliku obrazu zamiast wyświetlania go za pomocą Matplotlib

Piszę szybki i brudny skrypt do generowania działek w locie. Jako punkt wyjścia używam poniższego kodu (z dokumentacji Matplotlib ):

from pylab import figure, axes, pie, title, show

# Make a square figure and axes
figure(1, figsize=(6, 6))
ax = axes([0.1, 0.1, 0.8, 0.8])

labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
fracs = [15, 30, 45, 10]

explode = (0, 0.05, 0, 0)
pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%', shadow=True)
title('Raining Hogs and Dogs', bbox={'facecolor': '0.8', 'pad': 5})

show()  # Actually, don't show, just save to foo.png

Nie chcę wyświetlać wykresu W GUI, zamiast tego chcę zapisać wykres do pliku (powiedzmy foo.png), dzięki czemu np. można go używać w skryptach wsadowych. Jak mam to zrobić?

Author: Aurgho Bhattacharjee, 2012-03-08

14 answers

Chociaż pytanie zostało już udzielone, chciałbym dodać kilka przydatnych wskazówek podczas korzystania zsavefig . Format pliku może być określony przez rozszerzenie:

savefig('foo.png')
savefig('foo.pdf')

Da odpowiednio rasteryzowane lub wektoryzowane wyjście, które może być użyteczne. Ponadto przekonasz się, że pylab pozostawia obfite, często niepożądane, białe spacje wokół obrazu. Usuń za pomocą:

savefig('foo.png', bbox_inches='tight')
 950
Author: Hooked,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-05 14:08:22

Rozwiązaniem jest:

pylab.savefig('foo.png')
 136
Author: Lukasz Czerwinski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-19 07:37:52

Jak mówili inni, plt.savefig() lub fig1.savefig() jest rzeczywiście sposobem na zapisanie obrazu.

Jednak odkryłem, że w niektórych przypadkach(np. gdy Spyder posiada plt.ion(): interactive mode = On), rysunek jest zawsze pokazywany. Obejść to, wymuszając zamknięcie okna figury w mojej gigantycznej pętli, więc nie mam miliona otwartych figur podczas pętli:

import matplotlib.pyplot as plt
fig, ax = plt.subplots( nrows=1, ncols=1 )  # create figure & 1 axis
ax.plot([0,1,2], [10,20,3])
fig.savefig('path/to/save/image/to.png')   # save the figure to file
plt.close(fig)    # close the figure
 121
Author: Demis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-20 06:12:51

Właśnie znalazłem ten link w dokumentacji MatPlotLib, który rozwiązuje dokładnie ten problem: http://matplotlib.org/faq/howto_faq.html#generate-images-without-having-a-window-appear

Mówią, że najprostszym sposobem, aby zapobiec pojawianiu się postaci, jest użycie nieinteraktywnego backendu (np. Agg), via matplotib.use(<backend>), np:

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.savefig('myfig')

Ja osobiście nadal wolę używać plt.close( fig ), od tego czasu masz możliwość ukrycia pewnych figur( podczas pętli), ale nadal wyświetlanie figur dla post-loop przetwarzanie danych. Jest to prawdopodobnie wolniejsze niż wybór nieinteraktywnego backendu - byłoby interesujące, gdyby ktoś to przetestował.

 64
Author: Demis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-04 00:35:56

Jeśli nie podoba Ci się pojęcie" aktualnej " figury, wykonaj:

import matplotlib.image as mpimg

img = mpimg.imread("src.png")
mpimg.imsave("out.png", img)
 35
Author: wonder.mice,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-19 07:38:20

Pozostałe odpowiedzi są poprawne. Jednak czasami okazuje się, że chcę otworzyć rysunek obiekt później. Na przykład mogę zmienić rozmiar etykiet, dodać siatkę lub wykonać inne przetwarzanie. W idealnym świecie, chciałbym po prostu ponownie kod generujący fabułę, i dostosować ustawienia. Niestety, świat nie jest doskonały. Dlatego oprócz zapisywania do PDF lub PNG dodaję:

with open('some_file.pkl', "wb") as fp:
    pickle.dump(fig, fp, protocol=4)

W ten sposób mogę później załadować obiekt figure i manipulować ustawieniami, jak proszę.

Zapisuję również stos z kodem źródłowym i słownikiem locals() dla każdej funkcji / metody w stosie, aby później móc dokładnie określić, co wygenerowało figurę.

NB: bądź ostrożny, ponieważ czasami ta metoda generuje ogromne pliki.

 25
Author: gerrit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-22 14:14:35
import datetime
import numpy as np
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt

# Create the PdfPages object to which we will save the pages:
# The with statement makes sure that the PdfPages object is closed properly at
# the end of the block, even if an Exception occurs.
with PdfPages('multipage_pdf.pdf') as pdf:
    plt.figure(figsize=(3, 3))
    plt.plot(range(7), [3, 1, 4, 1, 5, 9, 2], 'r-o')
    plt.title('Page One')
    pdf.savefig()  # saves the current figure into a pdf page
    plt.close()

    plt.rc('text', usetex=True)
    plt.figure(figsize=(8, 6))
    x = np.arange(0, 5, 0.1)
    plt.plot(x, np.sin(x), 'b-')
    plt.title('Page Two')
    pdf.savefig()
    plt.close()

    plt.rc('text', usetex=False)
    fig = plt.figure(figsize=(4, 5))
    plt.plot(x, x*x, 'ko')
    plt.title('Page Three')
    pdf.savefig(fig)  # or you can pass a Figure object to pdf.savefig
    plt.close()

    # We can also set the file's metadata via the PdfPages object:
    d = pdf.infodict()
    d['Title'] = 'Multipage PDF Example'
    d['Author'] = u'Jouni K. Sepp\xe4nen'
    d['Subject'] = 'How to create a multipage pdf file and set its metadata'
    d['Keywords'] = 'PdfPages multipage keywords author title subject'
    d['CreationDate'] = datetime.datetime(2009, 11, 13)
    d['ModDate'] = datetime.datetime.today()
 22
Author: Victor Juliet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-30 08:38:37

Po użyciu metody plot () i innych funkcji do tworzenia pożądanej zawartości, możesz użyć klauzuli takiej jak ta, aby wybrać pomiędzy kreską na ekranie lub do pliku:

import matplotlib.pyplot as plt

fig = plt.figure(figuresize=4, 5)
# use plot(), etc. to create your plot.

# Pick one of the following lines to uncomment
# save_file = None
# save_file = os.path.join(your_directory, your_file_name)  

if save_file:
    plt.savefig(save_file)
    plt.close(fig)
else:
    plt.show()
 18
Author: Mark P.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-11 22:12:15

Użyłem:

import matplotlib.pyplot as plt

p1 = plt.plot(dates, temp, 'r-', label="Temperature (celsius)")  
p2 = plt.plot(dates, psal, 'b-', label="Salinity (psu)")  
plt.legend(loc='upper center', numpoints=1, bbox_to_anchor=(0.5, -0.05),        ncol=2, fancybox=True, shadow=True)

plt.savefig('data.png')  
plt.show()  
f.close()
plt.close()

Uważam, że bardzo ważne jest użycie plt.pokaż po zapisaniu rysunku, w przeciwnym razie nie będzie działać.Rysunek wyeksportowany w png

 16
Author: Cristian Muñoz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-05 13:58:11

Jeśli, tak jak ja, używasz Spyder IDE, musisz wyłączyć tryb interaktywny za pomocą:

plt.ioff()

(Polecenie to jest uruchamiane automatycznie przy starcie naukowym)

Jeśli chcesz włączyć go ponownie, użyj :

plt.ion()

 11
Author: Covich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-29 14:50:47

Rozwiązanie:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
matplotlib.style.use('ggplot')
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts = ts.cumsum()
plt.figure()
ts.plot()
plt.savefig("foo.png", bbox_inches='tight')

Jeśli chcesz wyświetlić obraz, jak również zapisać obraz użyj:

%matplotlib inline

Po import matplotlib

 10
Author: Durgesh satam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-27 08:59:31

Możesz albo zrobić:

plt.show(hold=False)
plt.savefig('name.pdf')

I pamiętaj, aby pozwolić savefig zakończyć przed zamknięciem wykresu GUI. W ten sposób możesz zobaczyć obraz wcześniej.

Alternatywnie, możesz spojrzeć na to za pomocą plt.show() Następnie zamknij GUI i uruchom skrypt ponownie, ale tym razem zamień plt.show() na plt.savefig().

Alternatywnie możesz użyć

fig, ax = plt.figure(nrows=1, ncols=1)
plt.plot(...)
plt.show()
fig.savefig('out.pdf')
 10
Author: Nutcracker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-23 23:20:03
#write the code for the plot     
plt.savefig("filename.png")

Plik zostanie zapisany w tym samym katalogu co uruchomiony plik python/Jupyter

 3
Author: Swaraj Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-19 06:14:39

Zgodnie z pytaniem Matplotlib (pyplot) savefig wyświetla pusty obraz.

Należy pamiętać o jednej rzeczy: jeśli użyjesz plt.show i powinno być po plt.savefig, lub podasz pusty obraz.

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

Tutaj wpisz opis obrazka

 3
Author: Jayhello,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-20 09:38:00