从很早的版本开始MATLAB就支持对patch、surface等对象设定透明属性,有些示意图也必须使用透明的对象才能充分展示所要表达的含义。对透明对象支持最好的通用图片格式就是.png了,但是png图像并非矢量图形,对于一些需要以矢量图显示的场合并不适用,比如某些展示超多细节的文档需要不断被放大放大放大,再比如许多期刊就不允许提交png格式的附件,只支持.eps、.tiff、.jpeg等。
eps(EncapsulatedPostScript)格式是被学术期刊最广泛认可的图片格式,其本身就是为矢量图而设计。遗憾的是PostScript作为一个啥都能干的图形学语音,居然直到现在都不支持透明度(transparency)的属性,因此想要让MATLAB中的带透明对象图形以.eps格式输出,只能依靠一些偏门的手段来曲线救国,比如下面提到的方案就是把透明对象的表观颜色赋给了矢量图,让它看起来像是透明而已。
首先明确一下目标:利用MATLAB生成带有透明度属性(FaceAlpha、EdgeAlpha等)的图形,将其以.eps格式输出,且保留MATLAB中所展示的透明度特征。先用 peaks 函数生成一个曲面,令其表面透明度为50%:
s=surf(peaks(30))
set(s,’facealpha’,0.5);
set(gcf,’color’,’none’);
首先试试用自带的 print 函数导出会得到怎样的结果:
printE:graphic.eps-r300-opengl
-r300表示以300dpi导出,-opengl表示使用opengl渲染器,-painters渲染器不支持透明属性所以不用试了。将这张eps图片插入Word中,然后用AdobePDF打印机默认的「高质量打印」输出pdf。
打开pdf,果然不行,虽然矢量图保留了,但是连颜色居然都没了:(
下图中右边为局部放大展示,下同。
再来试一下广受欢迎的 export_fig 函数:
export_figE:Graphic2.eps-r300-a2-opengl
注意一下 export_fig 要直接输出eps格式的话需要已经安装 GhostScript 以及 GhostXPS,否则会报错。export_fig 能保留透明效果(前提是使用-opengl),但是已经变成了位图,效果如下:
既然 export_fig 还可以直接输出为PDF,不妨试一试PDF能不能行得通,然后再用 GSView 转成eps:
仍然不对,问题跟直接输出的eps一样。想要靠MATLAB自带的导出函数和 export_fig 基本是没指望了。我搜了一下,发现不少人提倡以.svg(ScalableVectorGraphics)格式导出矢量图,但是.svg只是网页常见的矢量图格式,人家期刊并不支持,还得再绕一步将.svg转成.eps。MATLAB本身不支持svg的导出,所幸FileExchange中有人已经写好了 plot2svg,使用非常方便。但是需要注意一下的是,plot2svg 已经三四年没有更新过了,对于2014以后版本的MATLAB会报错,只需要进入plot2svg.m文件中将所有的 str2num 改为 str2double 即可。仍然是刚才那个图形,将其导出为svg格式:
plot2svg(‘E:Graphic3.svg’);
svg文件当然是极好的,又能透明又是矢量,比如下面这张,不管你怎么缩放现在这个页面都能保证一直是清晰的
但是我们的目标是eps。我先试了一下免费的 Inkscape,还是用300dpi导出,不选择栅格化:
可惜导出之后还是变成了位图(不过貌似使用Inkscape导出时会自动抗锯齿?对比下图和上面 export_fig 的结果就会发现):
没办法只能用AI了。我为了把这个问题解决特意去下载了一个AI,感觉有些大材小用啊…还好,问题解决了!AI导出时全部使用默认设置,除了把dpi调到300:
导出,真•矢量图达成!
继续放大:
最后总结一下工作流:
1、使用 plot2svg 函数先将MATLAB中生成的图形以.svg格式导出;
2、在AdobeIllustrator中打开svg文件,再将其以.eps格式导出。
附带说一下,本文转载自:https://capbone.com/use-matlab-to-export-vector-graphics-with-transparent-features/。这个方法只有必要对MATLAB中的带透明属性的patch、edge对象进行操作,如果仅仅是令当前窗口或当前坐标轴的背景透明,用自带的 print 和 export_fig 都能实现,没必要搞得那么复杂。