image - pyplot - Los diagramas de Matplotlib pierden transparencia al guardar como.ps/.eps
plt.savefig size (7)
Tengo problemas para intentar guardar algunos trazados con elipsoides transparentes si intento guardarlos con extensiones .ps / .eps.
Aquí está la trama guardada como .png:
Si elijo guardarlo como .ps / .eps aquí es lo que parece:
Cómo supero esto, fue utilizar ImageMagick para convertir el png original en un ps. El único problema es que la imagen en formato png es de aproximadamente 90k, y se convierte en poco menos de 4M después de la conversión. Esto no es bueno ya que tengo muchas de estas imágenes, y tomará mucho tiempo para compilar mi documento de látex. ¿Alguien tiene una solución para esto?
Como se mencionó anteriormente, la mejor y más fácil elección (si no quieres perder la resolución) es rasterizar la figura
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)
De esta forma, también puede administrar la opción de tamaño por dpi. De hecho, también puede jugar con el zorder a continuación y desea aplicar la rasterización:
ax.set_rasterization_zorder(0)
Nota: Es importante mantener f.set_rasterized (True) cuando usa las funciones plt.subplot y plt.subplot2grid. De lo contrario, la etiqueta y el área marcada no aparecerán en el archivo .eps
Mi solución es exportar la gráfica como .eps, cargarla en Inkscape por ejemplo, luego desagrupar la gráfica, seleccionar el objeto que quiero establecer como transparencia y simplemente editar la opacidad del relleno en la pestaña "Rellenar y trazar" .
Puede guardar el archivo como .svg si quiere modificarlo más tarde o exportar la imagen para una publicación.
Otra alternativa sería guardarlos en pdf
savefig(''myfigure.pdf'')
Eso funciona con pdflatex, si esa era la razón por la que necesitabas usar eps y no svg.
Puede rasterizar la figura antes de guardarla para conservar la transparencia en el archivo eps:
ax.set_rasterized(True)
plt.savefig(''rasterized_fig.eps'')
Resolví esto al: 1) agregar un set_rasterization_zorder (1) al definir el área de la figura:
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) un zorder = 0 en cada alfa = cualquier número en la gráfica:
ax110.scatter(xs1,ys1 , marker=''o'', color=''gray'' , s=1.5,zorder=0,alpha=0.3)#, label=label_bg)
y 3) finalmente un rasterizado = Verdadero al guardar:
P.savefig(str(PLOTFILENAME)+''.eps'', rasterized=True)
Yo tuve el mismo problema. Para evitar el rastrillado, puede guardar la imagen como un pdf y luego ejecutarla (en sistemas unixish al menos) en una terminal:
pdftops -eps my.pdf my.eps
Lo que le da un archivo .eps como salida.
El problema es que eps
no admite transparencias de forma nativa.
Hay pocas opciones:
rasterize la imagen e incruste en un archivo eps (como @Molly sugiere) o exportar a pdf y convertir con alguna herramienta externa (como gs) (que generalmente también se basa en la rasterización)
"imitar" la transparencia, dando un color que se parece al transparente en un fondo dado.
Discutí esto con seguridad una vez en la lista de correo de matplotlib , y recibí la sugerencia de rasterizar, lo que no es factible ya que se obtienen figuras pixeladas o enormes. Y no se escalan muy bien cuando se ponen en, por ejemplo, una publicación.
Yo personalmente uso el segundo enfoque, y aunque no es ideal, lo encontré lo suficientemente bueno. Escribí una pequeña secuencia de comandos python que implementa el algoritmo de esta publicación SO para obtener una representación RGB sólida de un color con una transparencia
EDITAR
En el caso específico de su trama intente utilizar la palabra clave zorder
para ordenar las partes trazadas. Intente usar zorder=10
para la elipse azul, zorder=11
para el verde y zorder=12
para los hexbins.
De esta forma, el azul debe estar debajo de todo, luego la elipse verde y finalmente los hexbins. Y la trama debería ser legible también con colores sólidos. Y si te gustan los tonos azules y verdes que tienes en png, puedes intentar jugar con mimic_alpha.py
.
EDIT 2
Si está 100% seguro de que tiene que usar eps, hay un par de soluciones que se me vienen a la mente (y que definitivamente son más feas que su trama):
- Simplemente dibuja los bordes de la elipse en la parte superior de los hexbins.
- Obtenga el centro y la amplitud de cada hexágono (posiblemente descarte todos los contenedores cero) y haga un diagrama de dispersión usando el mismo mapa de color que en
hexbin
y ajustando el tamaño y la forma del marcador como desee. Es posible que desee volver a dibujar los bordes de las elipsis encima de eso