Сохраните график в файл изображения вместо отображения его с помощью Matplotlib - PullRequest
958 голосов
/ 08 марта 2012

Я пишу быстрый и грязный скрипт для генерации графиков на лету.Я использую приведенный ниже код (из документации 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

Я не хочу отображать график в графическом интерфейсе, вместо этого я хочу сохранитьучасток к файлу (скажем, foo.png), так что, например, его можно использовать в пакетных сценариях.Как мне это сделать?

Ответы [ 18 ]

1189 голосов
/ 27 марта 2012

Пока на вопрос дан ответ, я хотел бы добавить несколько полезных советов при использовании matplotlib.pyplot.savefig . Формат файла можно указать по расширению:

from matplotlib import pyplot as plt

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

Даст растеризованный или векторизованный вывод соответственно, оба могут быть полезны. Кроме того, вы обнаружите, что pylab оставляет большой, часто нежелательный, пробел вокруг изображения. Удалить его с помощью:

savefig('foo.png', bbox_inches='tight')
163 голосов
/ 29 апреля 2015

Как уже говорили другие, plt.savefig() или fig1.savefig() - это действительно способ сохранить изображение.

Однако я обнаружил, что в некоторых случаях (например, если Spyder имеет plt.ion(): интерактивныйmode = On) рисунок всегда отображается.Я работаю над этим, заставляя закрывать окно фигуры в моем гигантском цикле, чтобы у меня не было миллиона открытых фигур во время цикла:

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
155 голосов
/ 27 марта 2012

Решение:

pylab.savefig('foo.png')
79 голосов
/ 04 января 2016

Только что нашел эту ссылку в документации MatPlotLib, касающейся именно этой проблемы: http://matplotlib.org/faq/howto_faq.html#generate-images-without-having-a-window-appear

Они говорят, что самый простой способ предотвратить появление фигуры - это использовать неинтерактивный бэкэнд (например, Agg.), через matplotib.use(<backend>), например:

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

Я по-прежнему лично предпочитаю использовать plt.close( fig ), так как тогда у вас есть возможность скрыть определенные цифры (во время цикла), но по-прежнему отображать цифры для пост-циклическая обработка данных.Это, вероятно, медленнее, чем выбор неинтерактивного бэкэнда, хотя было бы интересно, если бы кто-то это проверил.

UPDATE : для Spyder вы обычно не можете установить бэкэнд таким образомПоскольку Spyder обычно загружает matplotlib раньше, что не позволяет вам использовать matplotlib.use()).

Вместо этого используйте plt.switch_backend('Agg') или отключите « enable support » в настройках Spyder и запустите matplotlib.use('Agg') командуй собой.

Из этих двух подсказок: один , два

43 голосов
/ 30 января 2014

Если вам не нравится понятие «текущий» рисунок, выполните:

import matplotlib.image as mpimg

img = mpimg.imread("src.png")
mpimg.imsave("out.png", img)
26 голосов
/ 26 мая 2016

Остальные ответы верны.Однако иногда я обнаруживаю, что хочу открыть фигуру объект позже.Например, я мог бы хотеть изменить размеры этикетки, добавить сетку или сделать другую обработку.В идеальном мире я бы просто перезапустил код, генерирующий сюжет, и изменил настройки.Увы, мир не идеален.Поэтому, в дополнение к сохранению в PDF или PNG, я добавляю:

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

Таким образом, я могу позже загрузить объект рисунка и манипулировать настройками, как мне нравится.из стека с исходным кодом и словарем locals() для каждой функции / метода в стеке, чтобы позже я мог точно сказать, что сгенерировало фигуру.огромные файлы.

25 голосов
/ 12 октября 2016

После использования plot () и других функций для создания необходимого контента, вы можете использовать такое предложение, чтобы выбирать между выводом на экран или в файл:

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(4, 5))       # size in inches
# 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()
24 голосов
/ 30 июня 2015
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()
21 голосов
/ 05 апреля 2016

Я использовал следующее:

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

Мне показалось очень важным использовать plt.show после сохранения рисунка, иначе он не будет работать. рисунок экспортирован в png

12 голосов
/ 24 сентября 2017

Вы можете сделать:

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

и не забудьте сохранить savefig до закрытия графика GUI.Таким образом, вы можете увидеть изображение заранее.

Кроме того, вы можете посмотреть на него с помощью plt.show() Затем закройте графический интерфейс и снова запустите скрипт, но на этот раз замените plt.show() на plt.savefig().

В качестве альтернативы вы можете использовать

fig, ax = plt.figure(nrows=1, ncols=1)
plt.plot(...)
plt.show()
fig.savefig('out.pdf')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...