4

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]
Community
  • 1
  • 1
Verbeia
  • 4,400
  • 2
  • 23
  • 44
  • 1
    I can't be of much help since EMF export is not available in Linux - but maybe something in [this question](http://stackoverflow.com/q/6368642/421225) might be useful... Or maybe replacing the fonts by outlines, e.g., [`outlinedGraphics = First@ImportString[ExportString[gr,"PDF"],"PDF","TextMode" -> "Outlines"]`](http://pages.uoregon.edu/noeckel/MathematicaGraphics.html#Mathematica2Illustrator) – Simon Sep 13 '11 at 07:27
  • 1
    That trick above is actually in the Mma documentation: [FilledCurve: Text Effects](http://reference.wolfram.com/mathematica/ref/FilledCurve.html#101018554) – Simon Sep 13 '11 at 07:30
  • Dear all, just to give an update - we did some testing and discovered that, yes, there is a definite problem with text in BarCharts when exported as EMF. `ListPlot/DateListPlot/Plot` etc are ok. The font used doesn't matter. Combining with a `ListPlot` using `Show` doesn't help. I have alerted Wolfram Support and will report here when I find out something from them. – Verbeia Sep 22 '11 at 08:37

3 Answers3

6

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.

Verbeia
  • 4,400
  • 2
  • 23
  • 44
3

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).

Community
  • 1
  • 1
Alexey Popkov
  • 9,355
  • 4
  • 42
  • 93
0

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

Dr. belisarius
  • 60,527
  • 15
  • 115
  • 190
  • The problem is EMF, not PDF. PDF doesn't pixelate, but file sizes are huge and PDFs can't be imported nicely into Word documents, which is a requirement. – Verbeia Sep 13 '11 at 06:10
  • But I am using 8.0.1, and it being EMF, this is the Windows version at work not the Mac version at home. – Verbeia Sep 13 '11 at 06:22
  • 3
    @Verbeia: Easy fix - stop using MS Word! – Simon Sep 13 '11 at 06:22
  • @Simon I'll make a poster with that one! – Dr. belisarius Sep 13 '11 at 06:24
  • 1
    A less elegant fix is to [convert](http://www.google.com.au/search?q=pdf+to+emf) nice vector PDF to (hopefully) nice vector EMF. – Simon Sep 13 '11 at 06:25
  • @belisarius: Should be on every tech support check list! 1) Reboot computer. 2) Use LaTeX. – Simon Sep 13 '11 at 06:26
  • @Simon - I wish, but that is never going to happen. Very conservative organisation that has to share documents with the rest of government and international bodies. – Verbeia Sep 13 '11 at 06:41
  • @Simon - I don't think exporting PDF then converting to EMF will be suitable workflow, especially given this isn't a problem for `ListPlot` and derivatives. The target audience are very much end users. – Verbeia Sep 13 '11 at 06:45
  • @Verbeia Dump Mma! Excel is the tool you are looking for! :) – Dr. belisarius Sep 13 '11 at 06:51
  • @belisarius :) when Excel can do pretty multipanel graphs and center date labels over the year (see the examples in that other question) - then maybe the powers that be would consider that. Until then, we need a "something else". – Verbeia Sep 13 '11 at 07:02
  • 1
    @Verbeia: Working for the "powers that be" eh? Gotta be tough! – Simon Sep 13 '11 at 07:31
  • @Simon - yes. Check your email :) – Verbeia Sep 13 '11 at 07:58