为什么从 Mathematica 导出的条形图图形具有像素化文本?有解决方法吗?

发布于 2024-12-04 01:39:34 字数 2467 浏览 0 评论 0原文

我一直在炫耀我的奇特的新图形格式 给同事,但我们发现基于 BarChart 的图形在导出为 EMF、WMF、PDF 等时会出现锯齿状文本。基于 ListLinePlot 的折线图, DateListPlot 等没有这个问题。

缺少Rasterize-自动每个Export功能(它是针对最终用户的应用程序,因此不能指望他们自己摆弄它),是否有解决方法?这是一个惊喜,因为文档说:

由于 EMF 支持矢量图形,因此导出到 EMF 时不会对字体进行光栅化。

编辑如果相关,使用的字体是Arial。这应该会给你一些非常接近图表的东西,除了tickgrid业务之外,它涉及的自定义函数比人们真正想要费力的要多。

SetOptions[BarChart,Background->None, BaseStyle -> {20, FontFamily -> Rfont}, 
Frame -> True,  FrameTicksStyle -> {{Directive[20, 20], 20}, {20, 20}}, 
 FrameStyle -> 
 Directive[AbsoluteThickness[0.9], FontFamily -> Rfont, Black], 
 AspectRatio -> 14./19., PlotRangePadding -> None, Ticks -> None,
 ChartBaseStyle -> EdgeForm[None], GridLinesStyle->Directive[GrayLevel[0.7],  
 AbsoluteThickness[0.9]], GridLines -> {None, Automatic},
 ImageSize -> 672, ImageMargins -> {{0, 0}, {0, 3}}, 
ImagePadding -> {{66, 66}, {All, 1}}
]

SetOptions[ListPlot,Background->None,BaseStyle -> {20, FontFamily -> Rfont,  
 AbsolutePointSize[6]}, Frame -> True, 
 FrameStyle -> Directive[AbsoluteThickness[0.9], FontFamily -> "Arial", Black], 
 FrameTicksStyle -> {{Directive[20, 20], 20}, {20, 20}}, 
 AspectRatio -> 14./19., GridLinesStyle->Directive[GrayLevel[0.7],
 AbsoluteThickness[0.9]], GridLines -> {None, Automatic},PlotRangePadding->None,
  ImageSize -> 672, ImageMargins -> {{0, 0}, {0, 3}}, 
  ImagePadding -> {{66, 66}, {All, 1}}
 ];

areaharvested = {0.25, 1.25, 0.3, -0.1, -0.5, -0.5, -0.5, 0.25, 0.4};
yield = {3.25, 1.1, 2.6, 3., 2., -0.3, 2., 1.5, 1.2};
totalgrainprod = areaharvested + yield;


exgraph = Show[BarChart[Transpose@{areaharvested, yield}, ChartLayout -> "Stacked",
ChartStyle -> {Orange, Green}, PlotRange ->{{8.5, 9.5}, {-1, 4.}},   
 PlotRangePadding -> None,
 FrameTicks ->{{myTickGrid[-1, 4, 1, "%"], myTickGrid[-1, 4, 1, "%"]},
  {myBarChartTicks[{"67-71", "77-81", "87-91", "97-01", "07-11"}, 9], None}}],
ListPlot[totalgrainprod, PlotStyle -> AbsolutePointSize[13]]]    

Export["exgraph.emf", exgraph]

I've been showing off my fancy new graph formats to colleagues, but we have discovered that graphics based on BarChart have jagged text when exported as EMF, WMF, PDF etc. Line graphs based on ListLinePlot, DateListPlot etc do not have this problem.

Short of Rasterize-ing every Export function automatically (it's for an application for end-users so they can't be expected to fiddle with it themselves), is there a workaround? It's a surprise because the documentation says:

Since EMF supports vector graphics, fonts are not rasterized when exporting to EMF.

EDIT If it's relevant, font used is Arial. This should give you something very close to the graph, except for the tickgrid business, which involves more custom functions than one would really want to wade through.

SetOptions[BarChart,Background->None, BaseStyle -> {20, FontFamily -> Rfont}, 
Frame -> True,  FrameTicksStyle -> {{Directive[20, 20], 20}, {20, 20}}, 
 FrameStyle -> 
 Directive[AbsoluteThickness[0.9], FontFamily -> Rfont, Black], 
 AspectRatio -> 14./19., PlotRangePadding -> None, Ticks -> None,
 ChartBaseStyle -> EdgeForm[None], GridLinesStyle->Directive[GrayLevel[0.7],  
 AbsoluteThickness[0.9]], GridLines -> {None, Automatic},
 ImageSize -> 672, ImageMargins -> {{0, 0}, {0, 3}}, 
ImagePadding -> {{66, 66}, {All, 1}}
]

SetOptions[ListPlot,Background->None,BaseStyle -> {20, FontFamily -> Rfont,  
 AbsolutePointSize[6]}, Frame -> True, 
 FrameStyle -> Directive[AbsoluteThickness[0.9], FontFamily -> "Arial", Black], 
 FrameTicksStyle -> {{Directive[20, 20], 20}, {20, 20}}, 
 AspectRatio -> 14./19., GridLinesStyle->Directive[GrayLevel[0.7],
 AbsoluteThickness[0.9]], GridLines -> {None, Automatic},PlotRangePadding->None,
  ImageSize -> 672, ImageMargins -> {{0, 0}, {0, 3}}, 
  ImagePadding -> {{66, 66}, {All, 1}}
 ];

areaharvested = {0.25, 1.25, 0.3, -0.1, -0.5, -0.5, -0.5, 0.25, 0.4};
yield = {3.25, 1.1, 2.6, 3., 2., -0.3, 2., 1.5, 1.2};
totalgrainprod = areaharvested + yield;


exgraph = Show[BarChart[Transpose@{areaharvested, yield}, ChartLayout -> "Stacked",
ChartStyle -> {Orange, Green}, PlotRange ->{{8.5, 9.5}, {-1, 4.}},   
 PlotRangePadding -> None,
 FrameTicks ->{{myTickGrid[-1, 4, 1, "%"], myTickGrid[-1, 4, 1, "%"]},
  {myBarChartTicks[{"67-71", "77-81", "87-91", "97-01", "07-11"}, 9], None}}],
ListPlot[totalgrainprod, PlotStyle -> AbsolutePointSize[13]]]    

Export["exgraph.emf", exgraph]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

笑着哭最痛 2024-12-11 01:39:34

更新

许多年后,Wolfram 带着修复程序回来了。

Export[stringtouse, 
     DeleteCases[ obj /. {_Opacity, p_Point} :> 
     {PointSize[0], p}, _Opacity, Infinity], opts]

我将其绑定到一个像这样的小辅助函数中。

ExportEMFNicely[pathorfile_String, obj_, opts:OptionsPattern[{Export}]]:=
With[{stringtouse = If[ToLowerCase[StringTake[pathorfile,-4]]===".emf", 
 pathorfile, pathorfile<>".emf"]},
Export[stringtouse, 
 DeleteCases[ obj /. {_Opacity, p_Point} :> 
  {PointSize[0], p}, _Opacity, Infinity], opts] ]

这会产生矢量 EMF,无需任何Magnify 或使用 ImageResolution hack。

原始答案

Wolfram 支持人员回复了我。简短的回答是,这是 Mathematica 中的一个错误,他们建议使用其他格式或Rasterize

感谢您的电子邮件。出口产品质量问题
来自 Mathematica 的图像过去曾被报道过,我们的
开发人员正在研究这些。不过我已经单独提交了一份
代表您进行报告。我还附上了您的联系信息
这样问题解决后您就会收到通知。

与此同时,您可以尝试的另一个选项是光栅化
在导出到 EMF 之前以适当的分辨率绘制图形。

光栅化[图形,图像分辨率-> XXX]

您还可以尝试导出为其他 Windows 格式,例如 RTF。

编辑

我已经发现,您可以使用非常高的 ImageResolution 值来解决此问题(至少在 v 8.0.4 和 v 9.0.1 中) 导出命令。

bc = BarChart[RandomInteger[{1, 20}, {15}], Frame -> True, 
  FrameStyle -> AbsoluteThickness[1], PlotRangePadding -> 0, 
  PlotRange -> {0, 20}, 
  BaseStyle -> {FontFamily -> "Arial", FontSize -> 16}, 
  LabelingFunction -> None]

Export["testbarchart.emf", bc, ImageResolution -> 2000]

ImageResolution 设置为 1300 或更高会生成矢量格式文本和 50k EMF 文件。然而,将其设置为 1000 会导致高分辨率光栅占用 48 Mb!据我所知,这种行为没有记录。它似乎也会产生刻度线问题,因为只有当您使用 TicksFrameTicks 等更复杂的语法显式设置它们的长度时,它们才会显示(请参阅文档。)

对此修复的一个警告是 Mathematica 仍然认为它需要尽可能多的内存到创建这个较小的、基于矢量的 EMF 文件,就像创建高分辨率位图一样。因此它有时会抱怨没有足够的内存,并且您需要退出一些其他应用程序。它实际上并不需要所有内存来创建矢量 EMF。在我的实验中,任何 1300 或以上的值都将触发矢量导出,而 1200 或以下的值将生成高分辨率的巨大位图。

UPDATE

Many years later, Wolfram came back with a fix.

Export[stringtouse, 
     DeleteCases[ obj /. {_Opacity, p_Point} :> 
     {PointSize[0], p}, _Opacity, Infinity], opts]

I bound this up into a little helper function like this.

ExportEMFNicely[pathorfile_String, obj_, opts:OptionsPattern[{Export}]]:=
With[{stringtouse = If[ToLowerCase[StringTake[pathorfile,-4]]===".emf", 
 pathorfile, pathorfile<>".emf"]},
Export[stringtouse, 
 DeleteCases[ obj /. {_Opacity, p_Point} :> 
  {PointSize[0], p}, _Opacity, Infinity], opts] ]

This produces vector EMFs without any need to Magnify or use ImageResolution hacks.

ORIGINAL ANSWER

Wolfram support got back to me. Short answer is that it is a bug in Mathematica and they recommend either using another format or Rasterize

Thank you for your email. Issues relating to the quality of exported
images from Mathematica have been reported in the past and our
developers are looking into these. I have however filed a separate
report on your behalf. I have also included your contact information
so you can be notified when this is resolved.

In the meantime, the other option that you can try is to rasterize the
graphic with an appropriate resolution before exporting to EMF.

Rasterize[graphic, ImageResolution-> XXX]

You could also try exporting to other Windows formats like RTF.

EDIT

I have since worked out that you can work around this issue (at least in v 8.0.4 and v 9.0.1) using a very high value for ImageResolution in the Export command.

bc = BarChart[RandomInteger[{1, 20}, {15}], Frame -> True, 
  FrameStyle -> AbsoluteThickness[1], PlotRangePadding -> 0, 
  PlotRange -> {0, 20}, 
  BaseStyle -> {FontFamily -> "Arial", FontSize -> 16}, 
  LabelingFunction -> None]

Export["testbarchart.emf", bc, ImageResolution -> 2000]

Setting ImageResolution to 1300 or higher results in vector-format text and a 50k EMF file. However setting it to 1000 results in a high-resolution raster taking up 48 Mb! This behaviour is, as far as I know, undocumented. It also seems to create problems with tick marks, in that they only show up if you explicitly set their lengths using the more complex syntax for Ticks, FrameTicks etc (see documentation.)

One caveat to this fix is that Mathematica still thinks that it needs as much memory to create this smaller, vector-based EMF file as it would to create the high-resolution bitmap. So it will sometimes complain about not having enough memory and you will need to quit out of some other applications. It doesn't actually need all that memory to create the vector EMF. In my experiments, anything 1300 or above will work to trigger the vector export, while 1200 and below will generate a high-resolution, enormous bitmap.

江心雾 2024-12-11 01:39:34

我认为您可以找到有用的我的工具包答案:“一般PDF/ EMF导出问题及解决方案。”和这个 答案也非常相关(尝试 cyrFix 函数)。

I think you can find useful my Toolbag answer: "General PDF/EMF export problems and solutons." And this answer is also strongly relevant (try cyrFix function).

面犯桃花 2024-12-11 01:39:34

您使用什么版本的MMA?

在 v8 中:

a =  BarChart[{1, 2, 3}]
Export["c:\\test.pdf", a]

在此处输入图像描述

并放大 pdf:

在此处输入图像描述

What version of Mma are you using?

In v8:

a =  BarChart[{1, 2, 3}]
Export["c:\\test.pdf", a]

enter image description here

And zooming into the pdf:

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文