Сюжеты matplotlib savefig(), отличные от show()

Когда я использую show() построить графики в XГрафики выглядят очень хорошо. Однако, когда я начинаю использовать savefig() для генерации большого количества графиков, savefig() шрифт сгенерированных графиков, линии, многоугольники выглядят меньше, чем show() сгенерированный граф. Моя среда Ubuntu и бэкэнд для show() является Qt4Agg, Как я могу сделать show() сюжет и savefig() сюжет выглядит последовательным?

4 ответа

savefig задает DPI для сохраненного рисунка (по умолчанию установлено значение 100, если оно не указано в вашем.matplotlibrc, посмотрите на dpi Kwarg дляsavefig). Это не связано с DPI оригинальной фигуры.

DPI влияет на относительный размер текста и ширину обводки на линиях и т. Д. Если вы хотите, чтобы объекты выглядели одинаково, передайте fig.dpi в fig.savefig,

Например

import matplotlib.pyplot as plt

fig = plt.figure()
plt.plot(range(10))
fig.savefig('temp.png', dpi=fig.dpi)

Старый вопрос, но, видимо, Google это нравится, поэтому я решил написать ответ после некоторого исследования этой проблемы.

Если вы создаете фигуру с нуля, вы можете указать ей размер при создании:

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(3, 6))

plt.plot(range(10)) #plot example
plt.show() #for control

fig.savefig('temp.png', dpi=fig.dpi)

figsize (ширина, высота) регулирует абсолютный размер вашего графика и помогает убедиться, что оба графика выглядят одинаково.

Как указано в другом ответе, параметр dpi влияет на относительный размер текста и ширину обводки линий и т. Д. Использование параметра dpi = fig.dpi гарантирует, что их относительный размер одинаков как для show(), так и для savefig. ().

В качестве альтернативы размер фигуры может быть изменен после создания с помощью:

fig.set_size_inches(3, 6, forward=True)

вперед позволяет изменять размер на лету.

Если у вас возникли проблемы с слишком большими границами в созданном изображении, вы можете настроить их с помощью:

plt.tight_layout()
#or:
plt.tight_layout(pad=2)

или же:

fig.savefig('temp.png', dpi=fig.dpi, bbox_inches='tight')
#or:
fig.savefig('temp.png', dpi=fig.dpi, bbox_inches='tight', pad_inches=0.5)

Первый вариант просто минимизирует расположение и границы, а второй параметр позволяет вручную немного отрегулировать границы. Эти советы помогли мне, по крайней мере, решить мою проблему с различными изображениями savefig() и show().

Вы отображаете графики matplotlib на разных устройствах (например, на экране с помощью Quartz или в формате PDF с использованием различных функций (plot и savefig), параметры которых почти одинаковы, но значения по умолчанию для этих параметров не одинаковы для обе функции.

Другими словами, параметры по умолчанию для savefig отличаются от параметров отображения по умолчанию.

Выравнивание их просто, если вы делаете это в конфигурационном файле matplotlib. Файл шаблона включен в пакет с исходным кодом и называется matplotlibrc.template. Если вы не создали его при установке matplotlib, вы можете получить этот шаблон из источника matplotlib или с веб-сайта matplotlib.

Как только вы настроите этот файл так, как вам нужно, переименуйте его в matplotlibrc (без расширения) и сохраните его в каталоге .matplotlib (обратите внимание на начальный "."), Который должен находиться в вашем домашнем каталоге.

Параметры конфигурации для сохранения фигур начинаются примерно со строки 314 в прилагаемом файле matplotlibrc.template (первая строка перед этим разделом: ### СОХРАНЯЮЩИЕ ФИГУРЫ).

В частности, вы захотите взглянуть на это:

savefig.dpi       : 100         # figure dots per inch
savefig.facecolor : white       # figure facecolor when saving
savefig.edgecolor : white       # figure edgecolor when saving
savefig.extension : auto        # what extension to use for savefig('foo'), or 'auto'

Ниже этих строк находятся настройки для типа шрифта и различные параметры формата изображения.

Эти же параметры для отображения, т. Е. PLT.show (), начинаются примерно со строки 277a в matplotlibrc.template (этому разделу предшествует строка: ### FIGURE):

figure.figsize   : 8, 6          
figure.dpi       : 80            
figure.facecolor : 0.75       
figure.edgecolor : white     

Как вы можете видеть, сравнивая значения этих двух блоков параметров, настройки по умолчанию для одного и того же атрибута рисунка отличаются для savefig против display (show).

Я исправил это в моем источнике matplotlib, но это не очень хорошо. Однако, если вы, как и я, очень внимательно относитесь к тому, как выглядит график, оно того стоит.

Проблема, кажется, в бэкэндах рендеринга; каждый из них получает правильные значения ширины линии, размера шрифта и т. д., но это получается немного больше при рендеринге в формате PDF или PNG, чем при рендеринге с помощью show().

Я добавил несколько строк в источник для генерации PNG в файле matplotlib/backends/backend_agg.py. Вы можете внести аналогичные изменения для каждого используемого вами бэкэнда или найти способ сделать более умное изменение в одном месте;)

Добавлен в мой файл matplotlib / backends / backend_agg.py:

    # The top of the file, added lines 42 - 44
42  # @warning: CHANGED FROM SOURCE to draw thinner lines
43  PATH_SCALAR = .8
44  FONT_SCALAR = .95

    # In the draw_markers method, added lines 90 - 91
89  def draw_markers(self, *kl, **kw):
90      # @warning: CHANGED FROM SOURCE to draw thinner lines
91      kl[0].set_linewidth(kl[0].get_linewidth()*PATH_SCALAR)
92      return self._renderer.draw_markers(*kl, **kw)

    # At the bottom of the draw_path method, added lines 131 - 132:
130 else:
131     # @warning: CHANGED FROM SOURCE to draw thinner lines
132     gc.set_linewidth(gc.get_linewidth()*PATH_SCALAR)
133     self._renderer.draw_path(gc, path, transform, rgbFace)

    # At the bottom of the _get_agg_font method, added line 242 and the *FONT_SCALAR
241     font.clear()
242     # @warning: CHANGED FROM SOURCE to draw thinner lines
243     size = prop.get_size_in_points()*FONT_SCALAR
244     font.set_size(size, self.dpi)

Это соответствует моим потребностям, но, в зависимости от того, что вы делаете, вы можете захотеть внести аналогичные изменения в другие методы. Или найдите лучший способ сделать то же самое без такого количества изменений строки!

Обновление: После публикации проблемы в проекте matplotlib на Github я смог отследить источник моей проблемы: я изменил настройку figure.dpi в файле matplotlibrc. Если это значение отличается от значения по умолчанию, мои изображения savefig() получаются другими, даже если я установил df savefig равным значению dpi. Таким образом, вместо изменения источника, как описано выше, я просто сохранил значение figure.dpi по умолчанию 80 и смог генерировать изображения с помощью savefig(), которые выглядели как изображения из show().

Леон, ты тоже изменил эту настройку?

Другие вопросы по тегам