8
$\begingroup$

I'm trying to generate a template for exporting figures and plots in a consistent way that will allow easy editing in any vector based drawing software (such as illustrator). My problem is that exported figures in vector format have an (apparently) unnecessarily cumbersome structure. For instance

p = Plot[x, {x, 0, 1}
  , Frame -> True
  , FrameLabel -> {"Abscissa [unit]", "Ordinate [a.u]"}
  , BaseStyle -> {FontSize -> 11, FontFamily -> "Helvetica", 
    FontTracking -> "Plain", TextJustification -> 0, 
    PrivateFontOptions -> {"OperatorSubstitution" -> False}}
  ]
Export["test.svg",p,"SVG"]

will generate an SVG file which code look like this:

<g transform='matrix(1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000)' clip-path='url(#cp98)'>
<clipPath id='cp98'><polygon points='74,13 74,252 434,252 434,13 ' /></clipPath>
<polyline fill='none' stroke-opacity='1' stroke-width='0.2px' stroke='rgb(0%,0%,0%)' points='431.898,20 428.122,20 ' />
</g>
<g transform='matrix(1.000000, 0.000000, 0.000000, 1.000000, 235.948980, 236.753659)' clip-path='url(#cp99)'>
<clipPath id='cp99'><polygon points='-1.94898,-1.75366 -1.94898,15.2463 73.051,15.2463 73.051,-1.75366 ' /></clipPath>
<text x='0' y='11' font-family='Arial' font-size='11px' fill='rgb(0%,0%,0%)'>Abscissa</text>
<text x='49' y='11' font-family='Arial' font-size='11px' fill='rgb(0%,0%,0%)'>[</text>
<text x='52' y='11' font-family='Arial' font-size='11px' fill='rgb(0%,0%,0%)'>unit</text>
<text x='69' y='11' font-family='Arial' font-size='11px' fill='rgb(0%,0%,0%)'>]</text>
</g>

See how each piece of text, and tick stroke has a group, a clipping mask and the text is split in several text instances. That code also is cumbersome to manipulate when opened in Illustrator

Screenshot layers and groups seen in Illustrator

The described problem also exists in PDF and EPS formats, but is easier to see in the SVG code.

Is it possible to control this behaviour?

At least I would like to remove any clipping masks AND groups, and force all the text in a label to be a single object. Ideally I would like to have a group for traces, another for axis and another for labels

I tried making TextJustification -> 0,FontTracking -> "Plain" hoping at least the text split could be solved, but with no consequence.

Edit

Based on this question one strategy would be to parse back the SVG file (that is XML mark-up) , join all text that is in the same group. and then remove groups and clipping paths. That was not the kind of solution I was expecting, but it may work.

Any help on how to do this string or XML translation?

<g (random options 1)>
<clipPath (random options 2) /></clipPath>
<text (random options 3)> A</text>
<text (random options 3)> B</text>
<text (random options 3)> C</text>
</g>

into

<text (same options 3)> ABC</text>

Edit 2

A very preliminary and partially failed solution is to create the SVG and parse it back as XML, and take what is inside the groups (g) and clips (clipPath), and export it back as text.

p = Plot[x, {x, 0, 1}
  , Frame -> True
  , FrameLabel -> {"Abscissa [unit]", "Ordinate [a.u]"}
  , BaseStyle -> {FontSize -> 11, FontFamily -> "Helvetica", 
    FontTracking -> "Plain", TextJustification -> 0, 
    PrivateFontOptions -> {"OperatorSubstitution" -> False}}
  ]

Export["test2.svg", 
 ExportString[
  ImportString[ExportString[p, "SVG"], "XML"] /. 
   XMLElement["g", __, {XMLElement["clipPath", __], x_}] -> x, 
  "XML"], "Text"]

But the problem is that some groups have transform definitions that redefine the coordinate system and that information is currently lost. Also not all the groups are removed, i don't understand why. I would appreciate some help on this XML substitution rules and data parsing.

$\endgroup$
4
  • $\begingroup$ @Szabolcs, thanks for your comment, but Illustrator says that no clean-up was necessary. $\endgroup$
    – rhermans
    Commented Feb 10, 2014 at 14:59
  • 1
    $\begingroup$ That doesn't solve the core issue by itself, sorry for the misunderstanding. What I meant was that when I edit Mathematica-generated files, I often start with ungrouping, then using Clean Up, mostly to get rid of unnecessary clipping paths. I don't think there's a way to improve these files. You could write to support and explain your difficulties, which might help convince them that this is an important thing to improve ... $\endgroup$
    – Szabolcs
    Commented Feb 10, 2014 at 15:05
  • $\begingroup$ I have contacted Wolfram Technical Support [CASE:631799]. Will report once I get a reply. Thanks. $\endgroup$
    – rhermans
    Commented Feb 11, 2014 at 14:01
  • 2
    $\begingroup$ Hmm, why the close votes? $\endgroup$
    – Ajasja
    Commented Feb 14, 2014 at 9:32

1 Answer 1

8
$\begingroup$

This is the reply from Wolfram Research Technical Support [CASE:631799]:

After consultation with a developer, there is nothing really that can be done with the Export function directly in terms of simplifying the group structure of SVG files. You may be able to develop some system by programmatically parsing the file down, but this would likely not be simple or easy.

I can say that our developers are aware that exporting to vector based formats could be improved in Mathematica. Therefore, future versions of Mathematica might see improvement in this respect. I certainly can't make any guarantees about what might make it into any specific future version of Mathematica, but I can say that our developers do know that users would like improvement in this area.

So I guess the answer to my question is that so far (M v9) there is no native way to avoid the cumbersome structure of objects generated when exporting vector graphics. Therefore the only way around is to open the poorly generated file, to then parse and re-structure it.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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