сюжеты matplotlib savefig (), отличные от show () - PullRequest
47 голосов
/ 26 октября 2011

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

Ответы [ 4 ]

53 голосов
/ 26 октября 2011

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

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

1012 * Е.Г. *

import matplotlib.pyplot as plt

fig = plt.figure()
plt.plot(range(10))
fig.savefig('temp.png', dpi=fig.dpi)
26 голосов
/ 27 октября 2011

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

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

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

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

Параметры конфигурации для сохранения цифр начинаются примерно с строки 314 в поставляемом matplotlibrc.template (первая строка перед этим разделом: ### SAVING FIGURES).

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

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 () , начинаются примерно с строки 277 matplotlibrc.template (этому разделу предшествует строка: ### FIGURE):

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

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

7 голосов
/ 24 мая 2017

Старый вопрос, но, видимо, 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)

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

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

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 () изображений.

4 голосов
/ 22 марта 2012

Я исправил это в моем источнике 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 ().

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...