Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do BarChart graphics exported from Mathematica have pixelated text? Is there a workaround?

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]
like image 270
Verbeia Avatar asked Feb 23 '23 00:02

Verbeia


1 Answers

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.

like image 146
Verbeia Avatar answered Apr 06 '23 08:04

Verbeia