PostScript/EPS文件可以使用透明度吗?

15

我正在尝试将一个R绘图保存为EPS文件,但是我遇到了以下组件的问题 - 灰色透明多边形(透明黑色=灰色效果):

polygon(x.polygon, y.polygon.6, col="#00000022", border=NA)

当将图形保存为PDF时,此代码行可正常工作,但保存为EPS时则不行。看起来EPS不支持透明度?我还有什么其他选择吗?

这是完整图形的代码:

postscript(file="Figure.eps", width=5.5, height=5.5, onefile=F, horizontal=F)

ts(t(data.frame(initial_timepoint, second_timepoint, third_timepoint, final_timepoint)))->obj
obj[,-c(3,7)]->obj1
plot(obj1, plot.type="single", lwd=0.6, xaxs="i",yaxs="i",xlab="",ylab="LV ejection fraction (%)",xaxt='n',yaxt='n',ylim=c(0,70),col="black")
axis(1, at=c(1,2,3,4), labels=c("1","2","3","4"),cex.axis=1)
axis(2, at=seq(0,70,10), labels=c("0%","10%","20%","30%","40%","50%","60%","70%"),cex.axis=1, las=1)
abline(v=c(2,3),lwd=0.6,lty=2)

stderr <- function(x) sqrt(var(x,na.rm=TRUE)/length(na.omit(x)))
avg<-c(mean(initial_timepoint,na.rm=T), mean(second_timepoint,na.rm=T), mean(third_timepoint,na.rm=T), mean(final_timepoint,na.rm=T))
err<-c(stderr(initial_timepoint), stderr(second_timepoint), stderr(third_timepoint), stderr(final_timepoint))

my.count <- c(1,2,3,4)
my.count.rev <- c(4,3,2,1)
y.polygon.6 <- c((avg+err*1.96)[my.count],(avg-err*1.96)[my.count.rev])
x.polygon <- c(my.count, my.count.rev)
polygon(x.polygon, y.polygon.6, col="#00000022", border=NA)
lines(avg,col="black",lwd=0.8,lty=3)
lines((avg+err*1.96),lwd=0.8,lty=3)
lines((avg-err*1.96),lwd=0.8,lty=3)

dev.off()

EPS确实不支持透明度。我们需要更多的上下文来建议合理的替代方案。如果您只想模仿与白色背景上的透明黑色相关联的颜色,那么这并不难,但如果它后面有不同的对象,那就会很困难。 - Ben Bolker
3
PostScript语言不支持透明度,除了像图像蒙版(和蒙版图像)和套印等小细节。如果你需要使用PostScript(或EPS)格式,并且需要透明度效果,那么你需要将其转换为图像格式。 - KenS
这仍然无法复现。您可以通过以灰色绘制置信区间(不透明,但看起来像是)来获得所需内容,然后重新绘制任何被其遮挡的内容... - Ben Bolker
1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - luser droog
我在想,能否修改绘图代码,使得多边形先被绘制,然后时间序列线条再叠加在多边形之上? - Oposum
显示剩余3条评论
4个回答

19

虽然EPS格式本身不支持半透明,但仍然可以使用cairo_ps(),它会自动光栅化半透明区域,可以通过参数fallback_resolution来控制这个过程的分辨率:

Translated text:

虽然EPS格式本身不支持半透明,但仍然可以使用cairo_ps(),它会自动将半透明区域转化为点阵图形,并且可以通过参数fallback_resolution来控制这个过程的分辨率:

cairo_ps(file = "test.eps", onefile = FALSE, fallback_resolution = 600)
qplot(Sepal.Length, Petal.Length, data = iris, color = Species, size = Petal.Width, alpha = I(0.7))
dev.off()

所有非半透明区域都可以保留为矢量图形。

甚至更简洁的方法是使用:

ggsave("filename.eps", device=cairo_ps, fallback_resolution = 600)

或使用新的export包将函数导出为eps格式,该包刚刚在CRAN上发布:

install.packages("export")
library(export)
graph2eps("filename.eps", fallback_resolution = 600)

该软件包还支持其他几种导出格式,包括Powerpoint(graph2ppt),请参见?graph2vector,它也保留了半透明性...


10

PostScript图形模型本身不支持页面元素的通用透明度。因此,EPS也不支持。PostScript颜色全部是完全不透明的。

覆盖在另一个对象上面的对象会用自己的颜色覆盖并覆盖所有较低的对象,没有留下任何透明效果的余地。(如果您在PostScript查看器或打印输出中看到类似透明度叠加的东西,则那只是通过将两个(或更多)相应对象平铺成一个单一的光栅区域来模拟透明度,从而创造了透明度的幻象。)

PDF图形模型基于PostScript的,但它在各个方面进行了扩展,增加了几个新功能之一是完整对象的真正透明度。

Adobe在PDF中添加透明度后,还创建了一个扩展[1],向现有的PostScript语言中添加了代码,该代码能够向通过Distiller从此PostScript创建的PDF添加透明度。然而,在屏幕上呈现或在纸张上打印时,包括这些代码的相同原始PostScript,该附加的透明度不会出现直接在PostScript中使用时,上部(在PDF中透明)的对象仍将覆盖底部对象。

我还有其他选择吗?

各种:

  1. 只使用PDF。不要使用EPS。

  2. 如果必须使用EPS,请使用两步处理:

    • 首先创建PDF。
    • 然后从(启用透明度的)PDF转换为EPS,“平铺”透明元素为光栅化区域,以模拟所需的透明效果。

[1]这个扩展的名字叫做pdfmark。通过使用pdfmark运算符,可以在将PostScript转换为PDF时添加其他功能:注释、交互式表单字段和按钮、元数据、超链接等等。所有这些元素都不会在屏幕或纸张打印上的直接PostScript呈现中产生任何效果。


2
科学期刊要求使用EPS格式的图形,而不是PDF。因此需要透明的EPS。现在,如果EPS是通过pdfmark从PDF转换而来,那么当最终版本的文章PDF创建时,透明度是否会被保留? - Oposum
1
@Oposum:既然您说您的原始图保存为PDF确实包含所需的透明度,那么请按照我在答案的最后部分所说的做法进行操作--使用这两个步骤:***(1)创建具有透明度的PDF;(2)**将该PDF转换为EPS(透明度部分几乎会看起来*像PDF,通过静态光栅区域模拟透过效果)。 - Kurt Pfeifle
1
@Oposum: *"如果EPS是使用pdfmark从PDF转换而来的"*。-- 你没理解。必须在EPS代码中使用pdfmark运算符,以便让Distiller在将使用该EPS代码作为输入的PDF创建透明部分。当您将启用透明度的PDF转换回EPS时,不能保证会得到pdfmark运算符... - Kurt Pfeifle
2
我并不是说科学期刊要求透明的EPS格式,他们只是要求EPS格式而我需要透明度。 - Oposum
2
@Oposum:你可能需要它,但在EPS中不可能。你必须将启用透明度的PDF压平为EPS来进行伪造 - Kurt Pfeifle
显示剩余2条评论

0

不要使用透明的黑色来产生灰色,我建议在R中使用gray.colors()函数来生成你需要的灰色阴影。这样你就可以在.eps文件中获得你想要的效果,而没有任何问题。


-1

这对我来说很好用,可以保存 eps 文件。

import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.use('PS')

legend = plt.legend(loc="upper left", edgecolor="black")
legend.get_frame().set_alpha(None)
legend.get_frame().set_facecolor((0, 0, 0, 0))
plt.show()
plt.savefig('fig1.eps', format='eps')

你的回答可以通过提供更多支持信息来改进。请[编辑]以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接