4
$\begingroup$

My boss wants several Mathematica graphics as vector graphics in EMF format. All my plots are exported neatly, except for a BarChart which gets rasterized for no apparent reason:

Export["test.emf", BarChart[{1, 2, 3}]];

The resulting test.emf is almost 1 MB and clearly rasterized.

I found an older threat on the subject, but was wondering whether there is a new solution to the problem.

Thank you!

$\endgroup$
5
$\begingroup$

UPDATE

It seems that I found a straightforward way to disable rasterization while preserving the original appearance: the key is to add the ChartBaseStyle -> EdgeForm[Directive[GrayLevel[0.356], Opacity[1]]] option. The offending dot bug (demonstrated below in the "Original answer" section) we steel have to fix separately via post-processing /. {Opacity[0], __} -> {}:

plot = BarChart[{1, 2, 3}, 
   ChartBaseStyle -> 
    EdgeForm[Directive[GrayLevel[0.356], Opacity[1]]]] /. {Opacity[0], __} -> {}

Export["test.emf", plot]

The above produces a 15 kb EMF file without rasterization. I have checked this workaround in Mathematica 7.0.1, 8.0.4 and 10.0.1 and it seems to work reliably. Note that the dot bug was introduced in version 8.

Original answer

Removing the transparency solves the problem:

Export["test.emf", 
 BarChart[{1, 2, 3}, 
   PerformanceGoal -> "Speed"] /. {{Opacity[0], __} :> (## &[]), Opacity[_] :> Opacity[1]}]

The above produces a 15 kb file without rasterization.

The first replacement {Opacity[0], __} :> (## &[]) is necessary for removing the redundant black dot at the axis origin:

BarChart[{1, 2, 3}, PerformanceGoal -> "Speed"] /. Opacity[_] -> Opacity[1]

screenshot

In this concrete case the original appearance can be reproduced by replacing non-zero Opacity with GrayLevel:

Export["test.emf", 
 BarChart[{1, 2, 3}, 
   PerformanceGoal -> "Speed"] /. {{Opacity[0], __} :> (## &[]), 
   Opacity[o_] :> GrayLevel[1 - o]}]

More general way for removing transparency provides Blend:

Opacity[a_, color_] :> Blend[{White, color}, a]

Unfortunately the form Opacity[a, color] is rarely used and inspection of the low-level structure of graphics is usually necessary for finding a way to reproduce the original appearance. For this task I recommend my shortInputForm function.

$\endgroup$
  • $\begingroup$ Thank you! May I ask, what exactly the statement {Opacity[0], __} :> (## &[]) is doing, since it seems to work without it? $\endgroup$ – Franz Xaver Nov 12 '14 at 15:35
  • $\begingroup$ It removes completely transparent objects from the plot. Without it you get a redundant black dot in the plot. $\endgroup$ – Alexey Popkov Nov 12 '14 at 15:38
  • $\begingroup$ I have added a screenshot showing the offending dot. $\endgroup$ – Alexey Popkov Nov 12 '14 at 15:53
  • 2
    $\begingroup$ Admittedly, it's not the kind of solution you would expect from a software as pricey as Mathematica... $\endgroup$ – Franz Xaver Nov 12 '14 at 16:10
  • 1
    $\begingroup$ I updated the answer with a new method. $\endgroup$ – Alexey Popkov Nov 12 '14 at 19:58
3
$\begingroup$

I am the person who originally hit this problem several years ago. Recently Wolfram got back to us with a fix that works for us. It's a slight variation on Alexey's original answer.

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] ]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.