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]
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With