MathPSfrag: Creating Publication-Quality Labels in Mathematica Plots

10/31/2005 ∙ by J. Grosse, et al. ∙ Max Planck Society 0

This article introduces a Mathematica package providing a graphics export function that automatically replaces Mathematica expressions in a graphic by the corresponding LaTeX constructs and positions them correctly. It thus facilitates the creation of publication-quality Enscapulated PostScript (EPS) graphics.

READ FULL TEXT VIEW PDF
POST COMMENT

Comments

There are no comments yet.

Authors

page 1

page 2

page 3

page 4

This week in AI

Get the week's most popular data science and artificial intelligence research sent straight to your inbox every Saturday.

Introduction

Many programs producing EPS graphics do not allow the inclusion of LaTeX commands. While there exist several solutions (see for example McKay and Moore (1999)) to work around these difficulties, they all have various drawbacks. In this article, we will focus on a particular existing solution, the PSfrag package Grant and Carlisle , which provides LaTeX macros allowing to replace pieces of text (“tags”) in an EPS file by an arbitrary LaTeX construct.

However, for PSfrag to work, the application must write tags unaltered into the EPS file. For Mathematica Wolfram (1999); Wolfram Research, Inc. (2005), this requirement amounts to using single words, strictly consisting of alphanumeric characters only. As a consequence, the user has to work most of the time with an unconveniently labelled graphic and is furthermore required to keep track of the tags used in the substitution macros.

On the other hand, it is not always possible to use Mathematica’s conventional export function as it produces EPS files requiring the inclusion of additional fonts into the document, a process often not being under the author’s control. A way out is to include the font into the EPS file, or set the font family to a standard PostScript one:

Plot[…, TextStyle\(\to\){FontFamily\(\to\)"Times"}] and
Export[…, ConversionOptions\(\to\)
 {"IncludeSpecialFonts"\(\to\)True}].

(a) Conventional Mathematica plot before using MathPSfrag

a0A[cr][cr][1][0] a0[tc][tc][1][0] a1A[cr][cr][1][0] a1[cr][cr][1][0] a2[cr][cr][1][0] a2Pi[tc][tc][1][0] a3Cos2[cr][cr][1][0] a3[cr][cr][1][0] a3Pi2[tc][tc][1][0] localm[tc][tc][1][0]local maximum Pi2[tc][tc][1][0] Pi[tc][tc][1][0] Sinx[cl][cl][1][0]

(b) The same plot after automatically substituting all Text primitives (including tick mark labels) by LaTeX.
Figure 1: Old vs. new graphics export mechanism.
\({}^{*}\) jgrosse@mppmu.mpg.de
  http://wwwth.mppmu.mpg.de/members/jgrosse

gA[br][br]—[br][br]— *gA[Br][bc][2]—[Br][bc][2]— *gA[cr][bl]—[cr][bl]— *gA[tr][Bl]—[tr][Bl]— *gA[bc][Bc]—[bc][Bc]— *gA[Bc][Br]—[Bc][Br]— *gA[cc][cr]—[cc][cr]— *gA[tc][cc][0.75][45]—[tc][cc][0.75][45]— *gA[bl][cl][1.5][30]—[bl][cl][1.5][30]— *gA[Bl][tl]—[Bl][tl]— *gA[bl][Bl]     (baseline) *gA[bl][cl]     (center line) *gA[bl][tc][1][-90]     (center line) *gA[cl][tc]—[cl][tc]— *gA[tl][tr][1][180]—[tl][tr][1][180]—

Figure 2: Illustration of the various optional arguments of the \psfrag command, taken from Grant and Carlisle with minor changes. The first option determines the alignment of the LaTeX description, while the second one is responsible for the point to which the LaTeX macro is attached.

While the slight mismatch between the PostScript font’s appearance, cf. fig. 1(a), and that of LaTeX’s standard font (Computer Modern) may be acceptable in case of ordinary text labels, mathematical expressions like square roots or fractions cannot compete with LaTeX’s typesetting quality in this approach. Consequently, some authors simply restrict labelling of Mathematica plots to a bare minimum.

MathPSfrag Große is a package that conveniently produces publication-quality labels in EPS files generated by Mathematica. MathPSfrag automates many (often all) tedious details related to the use of the standard LaTeX package PSfrag, while still allowing manual fine tuning. As a demonstration of the degree of automation, compare fig. 1(a), which has been generated by using the standard Mathematica command Export, and fig. 1(b), generated by MathPSfrag’s export instruction.

While the solution presented here, relies on the PSfrag package, it avoids many of its shortcomings by providing a semi-automatic layer. In particular,

  • in most cases, it is sufficient to simply use the new PSfragExport command,

  • including the graphic into the document requires only one additional command.

This article is organized as follows. A short review of PSfrag and a somewhat longer explanation of the semi-automatic features provided by MathPSfrag, are given in the first and second section, respectively. The third part contains several examples whose code as well as that of figures 1(a) and 1(b) is contained in the appendix. Finally, some of MathPSfrag’s internals are discussed.

I Review of PSfrag

This is intended to be a short introduction into PSfrag explaining only the essential features necessary to understand the corresponding Mathematica package’s internals and to take advantage of its manual options if automatic placement does not yield the desired result. The full documentation can be found in Grant and Carlisle .

PSfrag provides the macro

\psfrag\(\langle\)tag\(\rangle\)[\([\)posn\(]\)][\([\)psposn\(]\)][\([\)scale\(]\)][\([\)rot\(]\)]\(\langle\)LaTeX\(\rangle\),
which replaces any occurence of tag in the output of an EPS file by LaTeX. According to Grant and Carlisle , “all \psfrag calls that precede an \includegraphics (or equivalent) in the same or surrounding environments” will affect the output of the included graphics, i.e. \psfrag commands can be defined either locally, to act on stricly one graphic, or globally, thus acting on all graphics in a document.

posn and psposn are optional arguments which allow to set (first) the vertical (top, bottom, Baseline, or center) and (second) the horizontal (left, right, center) alignment of the replacement text by specifying the respective first character of the choices given in parentheses. The arguments refer to the position of the reference point in the respective bounding boxes. The LaTeX construct is placed such that its reference point is at the position of the corresponding PostScript (tag) box’ reference point, cf. fig. 2.

ExamplA[cc][cc][1][0]Example 90 ExamplB[cc][cc][1][0]Example 150 ExamplC[cc][cc][1][0]Example 210 Exampl[cc][cc][1][0]Example 30 ExamplD[cc][cc][1][0]Example 270 ExamplE[cc][cc][1][0]Example 330

Figure 3: Example for substituting rotated text. To demonstrate that the new export function can preserve the orientation, only half of the labels have been substituted by LaTeX.

scale and rot permit scaling and rotation of the inserted box, where the rotation is relative to the slope of the PostScript bounding box such that a value of “0” preserves the orientation, see fig. 3. Scaling is best achieved by using LaTeX scaling commands, like \Large, instead of the scale option, since the standard LaTeX fonts consists of bitmaps rendered specifically for the chosen size and do not rescale well. As will be demonstrated in the example section, MathPSfrag provides macro hooks that allow to scale labels retroactively from within the document.

Ii How to use MathPSfrag

There are only two commands needed to control MathPSfrag’s EPS generation: PSfragExport, which supersedes Mathematica’s Export command, and PSfrag, which allows overriding of the automatics for particular expressions.

The export function

PSfragExport[\(\langle\)basename\(\rangle\), \(\langle\)graphics\(\rangle\), \([\)options\(]\)]
converts graphics, the usual Graphics construct returned by Mathematica commands like Plot, to an EPS file and a LaTeX file containing \psfrag macros.

options can be any combination of the following options, listed with their parenthetic defaults.

  • TeXSuffix"string" ("-psfrag.tex")

  • EpsSuffix"string" ("-psfrag.eps")

  • RenumberTagsboolean (False)

  • AutoConvertTextboolean (True)

  • AutoPositionboolean (True)

The respective file names of the LaTeX and EPS file are determined by basename to which the value of the options TeXSuffix and EpsSuffix is appended.

B[Br][Br][1][0] C[Br][Br][1][0] D[Br][Br][1][0] E[Br][Br][1][0] F[Br][Br][1][0] G[Br][Br][1][0] H[Br][Br][1][0] I[Br][Br][1][0] J[Br][Br][1][0] K[Br][Br][1][0] L[Br][Br][1][0] M[Br][Br][1][0] N[Br][Br][1][0] O[Br][Br][1][0] P[Br][Br][1][0] Q[Br][Br][1][0] R[Br][Br][1][0] S[Br][Br][1][0]

Figure 4: Three dimensional example: As there exists no FullGraphics3D command, manual labelling was required and the RenumberTags option of PSfragExport was used to produce smaller tags, increasing positioning precision.

The option RenumberTagsTrue will renumber all tags and represent the number as one of 52 (small and capital) latin characters or a combination of letters when the number is larger than 52. This feature, which generates very short tags, has been used in fig. 4 to achieve a preciser positioning.

Setting AutoConvertTextFalse will restrict conversion of Text directives in graphics into LaTeX commands to those directives having been marked manually. The default behaviour is to wrap the PSfrag command discussed below around all expressions found in graphics.

AutoPositionFalse switches off the mechanism for determining the \psfrag alignment from Mathematica’s internal representation of the graphics. Note that this also implies AutoConvertTextFalse.

Any other options will be passed on to Export or applied to the graphics using a Show commmand, respectively.

For the purpose of manually controlling the output, that means circumventing the automatics, the

PSfrag[\(\langle\)expr\(\rangle\), \([\)options\(]\)]
command is available. It can be wrapped around each Mathematica expression expr appearing as text in a graphic, such as the argument of a PlotLabel or AxesLabel option.

PSfrag processes the following options, whose defaults have been put in parentheses.

  • TeXCommand"string" (Automatic)

  • PSfragTag"string" (Automatic)

  • Position"yx" (Automatic)

  • PSPosition"yx" (CopyPosition)

  • Rotation"number" (0)

  • Scaling"number" (Automatic)

Actually, PSfragExport’s automatic mechanism simply wraps PSfrag around all Text primitives using the default values above. However, manual wrapping has the advantage of allowing to apply different options to expressions where the automatic behaviour did not give satisfactory results.

TeXCommand"string" sets to string the LaTeX command to appear in the final EPS graphic as a replacement of the corresponding expression expr. If set to Automatic, the internal function GuessTeX is called, which is basically a wrapper around TeXForm that adds $ signs around math expressions. Moreover, GuessTeX inserts some LaTeX commands that can be used to change the text style from within your document later on.

GuessTeX has several options of the form PreApplytype{list} and PostReplacetype{list}, where type is one of “Text”, “Math” or “Numeric”. For each type respectively, they provide a list for hooking in commands applied before or string replacements applied after TeXForm. Especially, the latter is rather useful for working around minor shortcomings of earlier Mathematica versions’ TeXForm.

a0A[cr][cr][1][0] a0[tc][tc][1][0] a1A[cr][cr][1][0] a1[cr][cr][1][0] a2[cr][cr][1][0] a2Pi[tc][tc][1][0] a3Cos2[cr][cr][1][0] a3[cr][cr][1][0] a3Pi2[tc][tc][1][0] localm[tc][tc][1][0]local maximum Pi2[tc][tc][1][0] Pi[tc][tc][1][0] Sinx[cl][cl][1][0]

Figure 5: Using the LaTeX hooks included by GuessTeX to fine-tune the appearance. As one can see, the default values are chosen carefully.

The remaining options are in one-to-one correspondence with those of \psfrag explained in section I. Their respective default value Automatic has the following different meanings for each of them: For PSfragTag, it means that a \psfrag compatible tag is created from a string representation of expr, for Position and PSPosition, it means to take over the alignment of the surrounding Text command. (If there is none, it waits till the Text command is produced during export.) For Rotation, Automatic means “0”, whereas for Scaling it means insertion of one of three LaTeX hooks, \psfragscaletext, \psfragscalemath and \psfragscalenumeric depending on the type of expr. The default value CopyPosition of PSPosition does exactly what it says, i.e. taking over the value of the Position option.

In the LaTeX document

There are only two additional things the user has to do:

  1. add \usepackage{psfrag, graphicx, amsmath} into the document’s preamble,

  2. use \input{basename-psfrag.tex}} to read the additional \psfrag labels created with PSfragExport["basename", myplot].

Iii Examples

We start to consider in more detail figures 1(a) and 1(b). The first one has been generated using standard Mathematica commands only, for the latter, the export was carried out with PSfragExport["example", exampleplot] and it was included into this document with

\begin{psfrags}
\input{example-psfrag.tex}
\includegraphics[width=0.9\linewidth]
  {example-psfrag.eps}
\end{psfrags}.

The \begin{psfrags} starts an empty group provided by PSfrag, whose sole purpose is making \psfrag definitions local to the following graphic.

There are three LaTeX commands, one of which is inserted by the automatic LaTeX guesser depending on the type of expression: \psfragtextstyle, \psfragmathstyle and \psfragnumericstyle. The latter is used for expressions identified by NumericQ. For demonstration of their respective effects, the following lines

\newcommand{\psfragtextstyle}{\Large}
\newcommand{\psfragmathstyle}{\pmb}
\newcommand{\psfragnumericstyle}{\scriptstyle}

have been inserted just before the \input command of fig. 5.

a0A[cr][cr][1][0] a0[tc][tc][1][0] a1A[cr][cr][1][0] a1[cr][cr][1][0] a2[cr][cr][1][0] a2Pi[tc][tc][1][0] a3Cos2[cr][cr][1][0] a3[cr][cr][1][0] a3Pi2[tc][tc][1][0] localm[tc][tc][1][0]local maximum Pi2[tc][tc][1][0] Pi[tc][tc][1][0] Sinx[cl][cl][1][0]

Figure 6: Example plot without resorting to automatics: AutoConvertTextFalse, AutoPositionFalse. Additionally, the “” label’s typesetting has been manually improved.

Fig. 6 demonstrates, that it is possible to easily reconstruct fig. 1(b) without using the automatic positioning feature. Additionally, one of the labels’ LaTeX code was improved to be instead of .

HoldFo[bc][bc][1][0] PaddedA[tc][tc][1][0] PaddedB[tc][tc][1][0] PaddedC[tc][tc][1][0] PaddedD[tc][tc][1][0] PaddedE[tc][tc][1][0] PaddedF[cr][cr][1][0]-15 PaddedG[cr][cr][1][0]-10 PaddedH[cr][cr][1][0] -5 PaddedI[cr][cr][1][0] 5 PaddedJ[cr][cr][1][0] PaddedK[cr][cr][1][0]Padded[tc][tc][1][0] x[cl][cl][1][0]

Figure 7: HoldForm example: Without HoldForm, Mathematica would normal order the label on the axis to . The CustomTicks package has been used to have a “1.0” instead of a “1.” on the axis.

Fig. 7 demonstrates compatibility with the CustomTicks package Caprio (2005) and the HoldForm command, which can be used to circumvent Mathematica’s automatic reordering of expressions into a normal form.

While Mathematica does not reliably rotate text in an interactive session, PSfragExport has no problems in doing so, as has been shown in fig. 3. Note that for each piece of text, the Rotation option is set to “0”, thus preserving the original orientation of the PostScript text.

Finally, it has been demonstrated in fig. 4, that three dimensional graphics can be processed also, even though it has to be done manually with PSfrag commands, since the FullGraphics command only works on two dimensional graphics.

Iv Discussion

MathPSfrag relies on two Mathematica commands: TeXForm and FullGraphics. Both are potential sources of failure.

For the first one, this is due to substantial changes concerning its output in its version history, which do not seem to have been publicly documented. With the latest steps in the transition towards amsmath compatible LaTeX though, TeXForm

will probably stabilize. However,

Mathematica versions 4.x and earlier will likely either require to include additional style files shipped with these versions to process the generated LaTeX commands or to manually produce ordinary LaTeX code. There are two possibilities to achieve the latter. First, one can substitute all non-standard LaTeX commands by setting up GuessTeX’s PostReplace…{…} options accordingly. This works particularly well if there is only a small number of non-standard macros generated for a large number of text entries. Second, it is still possible to set all TeXCommands with PSfrag.

The automatic positioning relies on FullGraphics to substitute all Text generating graphics options by Text commands, which in turn are used to read off the correct alignment for \psfrag. However, as one can see comparing figures 1(a) and 1(b), the bounding box differs slightly between Export[graphics] and Export[FullGraphics[graphics]]. There might be further differences, which can not be corrected by simply rescaling the graphics. Therefore, PSfragExport allows to set AutoPositionFalse, disabling the use of FullGraphics. In this case it has to use static standard values when encountering an Automatic value, which cannot be interpreted anymore. (These fall back values are: Bottomline, centered horizontally.) Since the mechanism for converting options like PlotLabel into LaTeX labels also depends on FullGraphics, setting AutoPositionFalse implies AutoConvertTextFalse.

V Conclusion

MathPSfrag provides a convenient interface to PSfrag permitting the generation of high-quality labels in Mathematica graphics. While it automatizes all tedious aspects of PSfrag, it still allows to seamlessly override all of its internal assumptions. Finally, MathPSfrag does not provide methods to construct correct tick mark contents as it is strictly focussed on shape. As shown in fig. 7, it does however integrate well with the CustomTicks package Caprio (2005), which provides that functionality.

Acknowledgements

I am grateful to Riccardo Apreda and Robert Eisenreich for helpful comments and discussion.

Figure Source Code

We assume that MathPSfrag and CustomTicks are placed where they can be found by Mathematica. CustomTicks is only needed for one of the examples.

Needs["MathPSfrag‘"];
Needs["CustomTicks‘"];
<< Graphics‘Arrow‘;
SetDirectory["/tmp/"]; (* set according to your needs *)

.1 Automatic Example

This example produces the conventional Mathematica plot in fig. 1(a). Merely in the last line, a MathPSfrag command is invoked to produce fig. 1(b).

f1[x_] := Sin[x];
f2[x_] := 3*((Cos[2 Sqrt[x]])^2)^(1/3);

rawplot = Plot[{f1[x], f2[x]}, {x, 0, 2 Pi},
      PlotStyle\(\to\){Hue[1.0], Hue[0.6]}, Frame\(\to\)True,
      FrameTicks\(\to\){Pi/2*{0, 1, 2, 3, 4}, Automatic, None, None},
      TextStyle\(\to\){FontFamily\(\to\)"Times"}];

SimpleLabel[tip : {_, _}, txt_, txtpos : {_, _}, align : {_, _}] :=  Sequence[
    Arrow[txtpos, tip, HeadScaling\(\to\)Absolute, HeadLength\(\to\)8, HeadCenter\(\to\)0.6],
    Text[txt, txtpos, align]];

textlabels = Graphics[{
        SimpleLabel[{Pi/2, f1[Pi/2]}, "local maximum", {1, -0.5}, {0, 1}],
        SimpleLabel[{7/6Pi, f1[7/6Pi]}, f1[x], {4.2, -0.3}, {-1, 0}],
        SimpleLabel[{4.2, f2[4.2]}, f2[x], {3.5, 1.5}, {1, 0}]
        }];

mygrid = Map[{#, {AbsoluteDashing[{0.1, 1}], GrayLevel[0.5]}} &, {Pi*{1/2, 1,
            3/2}, {1, 2}}, {2}];
exampleplot = Show[rawplot, textlabels, GridLines\(\to\)mygrid];

Export["ex_nopsfrag.eps", exampleplot, "EPS"]
PSfragExport["ex_auto", exampleplot]

.2 Rotated Text

While Mathematica does not rotate the letters of a rotated Text on screen, both the conventional Export and PSfragExport do the right thing, cf. fig. 3. Furthermore, it is demonstrated, that PSfragExport can apply the option PlotRangeAll to the graphics before carrying out the export.

Show[Graphics[{
        Table[Text["Example " <> ToString[Round[phi*180/Pi]],
                   {Cos[phi], Sin[phi]}, {0, 0}, {Cos[phi], Sin[phi]}],
              {phi, 0, 2Pi - 0.01, 2Pi/6}],
        Table[Text[PSfrag["Example " <> ToString[Round[phi*180/Pi]]],
                   {Cos[phi], Sin[phi]}, {0, 0}, {Cos[phi], Sin[phi]}],
              {phi, 2Pi/12, 2Pi - 0.01, 2Pi/6}],
        Circle[{0, 0}, 1]
     }]];
PSfragExport["ex_rot", %, AutoConvertText \(\to\) False, PlotRange \(\to\) All]

.3 Three-dimensional Knot

Here, the three-dimensional knot in fig. 4 is generated. Note that PSfragExport acting on Graphics3D always implies AutoConvertTextFalse and AutoPositionFalse.

myticks3d = {#, PSfrag[#, Position\(\to\)"Br"]} & /@ {-1, -0.5, 0, 1, 0.5, 1};
ParametricPlot3D[
    Evaluate[Flatten[{(0.5 + 0.2*Cos[phi/5] + r*Sin[1.7phi]){Cos[phi],
              Sin[phi]}, phi/(5Pi) + r*Cos[1.7 phi]}]],
    {phi, -3Pi, 4Pi}, {r, 0.05, 0.2}, PlotPoints\(\to\){200, 3}, Ticks\(\to\){myticks3d, myticks3d, myticks3d}];
PSfragExport["ex_3d", %, RenumberTags\(\to\)True]

.4 Manual Clone of the Introductory Example

Under the assumption that the automatic export did not work at all, the manual alignment options are used to reproduce fig. 1(b). Moreover, the opportunity to improve the label by hand is seized; the corresponding commands below are in italics. The functions f1, f2 and SimpleLabel from the first example have been taken over.

mytickmarks = {
      {N[#], PSfrag[#, Position\(\to\)"tc"]} & /@ (Pi/2*{0, 1, 2, 3, 4}),
      {N[#], PSfrag[#, Position\(\to\)"cr"]} & /@ {-1, 0, 1, 2, 3},
      None,
      None};

texstr = "$3\left|\cos \sqrt{4x}\right|^\frac{2}{3}$";

Show[ Plot[
        {f1[x], f2[x]}, {x, 0, 2 Pi}, PlotStyle\(\to\){Hue[1.0], Hue[0.6]},
        Frame\(\to\)True, FrameTicks\(\to\)mytickmarks, GridLines\(\to\)mygrid,
        DisplayFunction\(\to\)Identity
        ],
      Graphics[{
        SimpleLabel[{Pi/2, f1[Pi/2]},
          PSfrag["local maximum", Position\(\to\)"tc"], {1, -0.5}, {0, 1}],
        SimpleLabel[{7/6Pi, f1[7/6Pi]},
          PSfrag[f1[x], Position\(\to\)"cl"], {4.2, -0.3}, {-1, 0}],
        SimpleLabel[{4.2, f2[4.2]},
          PSfrag[f2[x], Position\(\to\)"cr", TeXCommand\(\to\)texstr], {3.5, 1.5}, {1, 0}]
        }],
      DisplayFunction\(\to\)$DisplayFunction
      ];
PSfragExport["ex_manual", %, AutoConvertText\(\to\)False, AutoPosition\(\to\)False]

.5 HoldForm plus CustomTicks

Fig. 7 is a plain example demonstrating that HoldForm can be used to fix the shape of an expression while LinTicks from CustomTicks Caprio (2005) can be used to circumvent the usual stripped decimal “1.” and print a much nicer “1.0” instead.

Plot[(3x - 1)^3, {x, -0.5, 2.5}, PlotStyle\(\to\)Hue[0.6],
    AxesLabel\(\to\){x, HoldForm[(3x - 1)^3]},
    Ticks\(\to\){LinTicks[-0.5, 2.5], LinTicks[-15, 18]}];
PSfragExport["ex_hold", %]

References