Графики Matplotlib теряют прозрачность при сохранении в формате .ps / .eps

У меня возникла проблема с попыткой сохранить некоторые графики с прозрачными эллипсоидами на них, если я попытаюсь сохранить их с расширениями .ps / .eps.

Вот сюжет, сохраненный в формате .png: png

Если я решу сохранить его как .ps / .eps, вот как он будет выглядеть: ps

Как я обошел это, я использовал ImageMagick для преобразования исходного png в ps. Единственная проблема заключается в том, что изображение в формате png имеет размер около 90 КБ, а после преобразования его размер становится чуть меньше 4 МБ. Это нехорошо, так как у меня много этих изображений, и компиляция моего латексного документа займет слишком много времени. Есть ли у кого-нибудь решение этого?


person astromax    schedule 28.10.2013    source источник
comment
Вы наконец решили проблему, не используя мимик?   -  person Srivatsan    schedule 07.12.2015


Ответы (8)


Проблема в том, что eps изначально не поддерживает прозрачность.

Есть несколько вариантов:

  1. растеризовать изображение и встроить в файл eps (например, @Molly) или экспортировать в pdf и преобразовать с помощью какого-либо внешнего инструмента (например, gs) (который обычно также полагается на растеризацию)

  2. «имитировать» прозрачность, придавая цвет, который выглядит как прозрачный на заданном фоне.

Я наверняка однажды обсуждал этот в списке рассылки matplotlib, и я получил предложение растеризовать, что невозможно, так как вы получаете либо пиксельные, либо огромные фигуры. И они не очень хорошо масштабируются, когда помещаются, например, в публикацию.

Я лично использую второй подход, и хотя он не идеален, я нашел его достаточно хорошим. Я написал небольшой скрипт Python, который реализует алгоритм из this SO post, чтобы получить твердое представление цвета RGB с заданной прозрачностью.

ИЗМЕНИТЬ

В конкретном случае вашего графика попробуйте использовать ключевое слово zorder, чтобы упорядочить построенные части. Попробуйте использовать zorder=10 для синего эллипса, zorder=11 для зеленого и zorder=12 для шестиугольников.

Таким образом, синий должен быть ниже всего, затем зеленый эллипс и, наконец, шестиугольники. И сюжет должен быть читабельным, также сплошным цветом. А если вам нравятся оттенки синего и зеленого, которые есть в png, вы можете попробовать поиграть с mimic_alpha.py.

ИЗМЕНИТЬ 2

Если вы на 100% уверены, что должны использовать eps, мне на ум приходит пара обходных путей (и они определенно уродливее, чем ваш сюжет):

  1. Просто нарисуйте границы эллипса поверх шестиугольников.
  2. Получите центр и амплитуду каждого шестиугольника (возможно, отбросьте все нулевые интервалы) и сделайте разброс постройте, используя ту же цветовую карту, что и в hexbin, и отрегулируйте размер и форму маркера по своему усмотрению. Вы можете перерисовать границы эллипсов поверх этого
person Francesco Montesano    schedule 28.10.2013
comment
Спасибо, я попробовал ваш код mimic_alpha.py, но вы не можете увидеть его на диаграмме рассеяния, которую я также сгенерировал. Цвета хорошо сочетаются, но все равно непрозрачно. - person astromax; 28.10.2013
comment
да, он имитирует цвета, но возвращает стандартные цвета RGB. В любом случае, если вам нужно использовать eps, мало что можно сделать. Я использую mimic_alpha несколько раз (думаю, в основном с fill_between), увеличивая границы стандартными линиями поверх затененных областей. - person Francesco Montesano; 29.10.2013
comment
@astromax: я отредактировал ответ, добавив возможное решение вашей проблемы - person Francesco Montesano; 29.10.2013
comment
Я тоже пробовал это - проблема в том, что хотя hexbin имеет много нулевых интервалов, график hexbin охватывает весь диапазон. В этом случае hexbin с порядковым номером больше, чем эллипсы, полностью их блокирует. - person astromax; 29.10.2013
comment
@astromax Понятно. Это очень раздражает. Я редактирую ответ с указанием возможного обходного пути - person Francesco Montesano; 29.10.2013

Другой альтернативой было бы сохранить их в формате pdf.

savefig('myfigure.pdf')

Это работает с pdflatex, если по этой причине вам нужно было использовать eps, а не svg.

person P.R.    schedule 11.03.2014
comment
Действительно, это правильный ответ. Мне неизвестны публикации в 2020 году, в которых не принимались бы цифры в формате PDF. - person Luke Davis; 15.05.2020

Вы можете растрировать фигуру перед ее сохранением, чтобы сохранить прозрачность в файле eps:

ax.set_rasterized(True)
plt.savefig('rasterized_fig.eps')
person Molly    schedule 28.10.2013
comment
Очень полезно, единственная проблема не в том, что это 33M, что слишком велико. У меня их много, и они не могут быть такими большими. - person astromax; 28.10.2013
comment
Кроме того, кажется, что задняя часть графика окрашивается в черный цвет, поэтому он закрывает метки осей x и y. Есть идеи, почему он это делает? - person astromax; 28.10.2013

У меня такая же проблема. Чтобы избежать растеризации, вы можете сохранить изображение в формате pdf, а затем запустить (по крайней мере, в unixish системах) в терминале:

pdftops -eps my.pdf my.eps

Что дает файл .eps в качестве вывода.

person Poshpaws    schedule 08.05.2014

Я решил это: 1) добавив set_rasterization_zorder (1) при определении области фигуры:

fxsize=16
fysize=8
f = figure(num=None, figsize=(fxsize, fysize), dpi=180, facecolor='w',
edgecolor='k')
plt.subplots_adjust(
left    = (18/25.4)/fxsize, 
bottom  = (13/25.4)/fysize, 
right   = 1 - (8/25.4)/fxsize, 
top     = 1 - (8/25.4)/fysize)
subplots_adjust(hspace=0,wspace=0.1)
#f.suptitle('An overall title', size=20)
gs0 = gridspec.GridSpec(1, 2)

gs11 = gridspec.GridSpecFromSubplotSpec(1, 1, subplot_spec=gs0[0])

ax110 = plt.Subplot(f, gs11[0,0])
f.add_subplot(ax110)

ax110.set_rasterization_zorder(1)

2) zorder = 0 в каждом alpha = anynumber на графике:

ax110.scatter(xs1,ys1  , marker='o', color='gray'  , s=1.5,zorder=0,alpha=0.3)#, label=label_bg)

и 3) наконец, при сохранении rasterized = True:

P.savefig(str(PLOTFILENAME)+'.eps', rasterized=True)

Обратите внимание, что это может не работать должным образом с ключевым словом transparent для savefig, потому что цвет RGBA с альфа ‹1 на прозрачном фоне будет отображаться так же, как цвет RGB с альфа = 1.

person Hugo    schedule 19.02.2016

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

f = plt.figure()
f.set_rasterized(True)

ax = f.add_subplot(111)

ax.set_rasterized(True)
f.savefig('figure_name.eps',rasterized=True,dpi=300)

Таким образом, вы также можете управлять размером с помощью параметра dpi. Фактически, вы также можете поиграть с зордером ниже, для которого хотите применить растеризацию:

ax.set_rasterization_zorder(0)

Примечание: важно сохранить f.set_rasterized (True), когда вы используете функции plt.subplot и plt.subplot2grid. В противном случае метка и область галочки не будут отображаться в файле .eps.

person Luis DG    schedule 23.11.2016

Мое решение - экспортировать график как .eps, загрузить его, например, в Inkscape, затем разгруппировать график, выбрать объект, для которого я хочу установить прозрачность, и просто отредактировать непрозрачность заливки на вкладке «Заливка и обводка». .

Вы можете сохранить файл как .svg, если хотите изменить его позже, или экспортировать изображение для публикации.

person B.Kocis    schedule 10.09.2015

Если вы пишете академическую статью в латексе, я бы рекомендовал вам экспортировать файл .pdf, а не .eps. Формат .pdf отлично поддерживает прозрачность и имеет хорошую эффективность сжатия, а главное, его можно легко редактировать в Adobe Illustrator.

Если вы хотите еще больше отредактировать график (НЕ РЕДАКТИРОВАТЬ ДАННЫЕ! Я СЧИТАЮ, ДЛЯ ХОРОШЕГО ВИДА), вы можете открыть экспортированный график в Adobe Acrobat - Редактировать - Копировать элементы в Adobe Illustrator. Эти два программного обеспечения могут справиться со всем отлично.

Я с удовольствием работаю с этим методом. Все понятно, доступно для редактирования и небольшого размера. Надежда может помочь.

person Caesar.T    schedule 16.03.2021