141
$\begingroup$

I quite often would like to draw graphics in my $\LaTeX$ documents using Mathematica. I have encountered three problems. I would like to know if there are any workarounds to these problems

I would like to make my graphics homogeneous with my document. That means that I would like to use the same font in the graphics (labels for axis etc) as the main text. Mathematica does not support Computer Modern. I found a workaround using PSFrag, saving graphics as EPS. It is possible using PSfrag to rename the text in the graphic into $\LaTeX$ code. A big downside is that this method does not allow me to use pdflatex. Many other packages (hyperlink) therefore do not work.

Graphics3D objects are extremely big. If I save it using a bitmap, the picture usually becomes horrible.

I often would like to use transparency. If I use Opacity to make some part of the graphic transparent, the exported file in Mathematica is horrible.

$\endgroup$
6
  • 5
    $\begingroup$ Theoretically you can get Mathematica to use Computer Modern, but it's a lot of trouble for little gain an imperfect results. You could start by downloading Latin Modern in OpenType format. Mathematica exports to PDF 1.4, a PDF specification too old to be able to embed OpenType fonts, so you'd need to convert them to TrueType. Then install the appropriate font (e.g. "LM Roman 10" is upright, optimized for 10 pt viewing), and make the plot with BaseStyle -> {FontFamily -> "LM Roman 10", FontSize -> 10}. $\endgroup$
    – Szabolcs
    Commented Jan 26, 2012 at 9:22
  • 1
    $\begingroup$ This is not a satisfactory answer I know, but I thought it would be good to write it down. Even if you do this, mathematical text (formulae) won't appear in the same style as when typeset by LaTeX, you unless all you need is numbers for the axes, it's probably not worth the trouble. $\endgroup$
    – Szabolcs
    Commented Jan 26, 2012 at 9:24
  • 2
    $\begingroup$ For Graphics3D objects, there is the Fortran code Polygone that reduces the size of postscript graphics by merging unnecessary polygons. $\endgroup$
    – Simon
    Commented Jan 26, 2012 at 12:39
  • $\begingroup$ @Simon that could have been a good answer for my question here: mathematica.stackexchange.com/questions/644/… I encourage you to post it. $\endgroup$
    – Szabolcs
    Commented Jan 26, 2012 at 14:25
  • 3
    $\begingroup$ Personally I use Mathematica to generate data for the plots, and then create the plots themselves using a LaTeX package like PGFPlots. A couple extra steps, sure, but I like the extra control that you get. $\endgroup$ Commented Mar 10, 2015 at 15:04

9 Answers 9

48
$\begingroup$

There are a few different parts to your question. I'll just answer the part about using psfragand pdflatex.

There's a package called pstool that automates the whole process of using psfrag with pdflatex.

For example, here's a graphics created in Mathematica 8

plot = Plot[Sin[Exp[x]], {x, -Pi, Pi}, AxesLabel -> {"e", "s"}]
Export[NotebookDirectory[] <> "plot.eps", plot]

da plot

Note the use of the single character names for the axes. This was discussed in the stackexchange question Mathematica 8.0 and psfrag.

You can use psfrag on this image and compile straight to pdf using the following latex file

\documentclass{article}  
\usepackage{pstool}
\begin{document}
\psfragfig{plot}{%
	\psfrag{e}{$\epsilon$}
	\psfrag{s}{$\Sigma$}}  
\end{document} 

Compile it using pdflatex --shell-escape filename.tex. You can optionally include a file plot.tex in the same directory which can contain all the psfrag code for plot.eps so that your main .tex file is tidier and the plot is more portable.
Here's a screenshot of the graphics in the pdf file:
screenshot

$\endgroup$
7
  • $\begingroup$ I don't use LaTeX so this is solely out of curiosity but I notice that the conversion also converted the axes labels. Presumably that is to do with default fonts or something? $\endgroup$ Commented Jan 26, 2012 at 22:25
  • $\begingroup$ @MikeHoneychurch : The conversion happens with \psfrag{e}{$\epsilon$} in the LaTeX file. $\endgroup$ Commented Jun 21, 2014 at 10:38
  • 4
    $\begingroup$ It is probably worth pointing out that pstools and psfrag do not work in MMA10. $\endgroup$ Commented Oct 13, 2014 at 14:30
  • 2
    $\begingroup$ @AlexeyBobrick If you look at the generated eps you can see that the fonts are by default outlined and not represented as text. This is probably a bug and will hopefully be fixed. See this comment by Szabolcs $\endgroup$
    – Simon
    Commented Oct 15, 2014 at 3:30
  • 1
    $\begingroup$ @Thankyouforyourcooperation - It looks like Mathematica is still converting text to outlines (as mentioned in a comment above). Until they fix this psfrag won't work. I just submitted feedback on this issue, asking that the option TextOutlines works for EPS like it does for PDF export. $\endgroup$
    – Simon
    Commented Oct 24, 2015 at 11:10
100
$\begingroup$

Join the chat at https://gitter.im/MaTeX-help/Lobby GitHub (pre-)release Github All Releases Contributions welcome DOI

I would like to make my graphics homogeneous with my (LaTeX) document. That means that I would like to use the same font in the graphics (labels for axis etc) as the main text.

I recently wrote a package, called MaTeX, to solve this exact problem. MaTeX makes it easy to compile short LaTeX snippets and embed them in Mathematica notebooks or graphics.

Tip: MaTeX comes with integrated documentation that contains many examples and a full tutorial. After installing the package, go to Help → Wolfram Documentation, and search for "MaTeX".

Here's a quick demo:

<< MaTeX`

MaTeX["\\sin^2 \\varphi + \\cos^2 \\varphi = 1", Magnification -> 2]

MaTeX[Sin[x] + O[x]^8, Magnification -> 2]

enter image description here

funs = {Sin[x], Normal[Sin[x] + O[x]^8]};

Plot[Evaluate[funs], {x, 0, 2 Pi}, PlotLegends -> MaTeX /@ funs, 
 BaseStyle -> {FontFamily -> "Latin Modern Roman"}, 
 Frame -> True, FrameStyle -> BlackFrame]

enter image description here

I use it in conjunction with the Latin Modern fonts to achieve a consistent visual style. (Note: These fonts are accessible under different names on different operating systems. Check your font manager for the correct name.)

I found a workaround using PSFrag, saving graphics as EPS. It is possible using PSfrag to rename the text in the graphic into LATEX code. A big downside is that this method does not allow me to use pdflatex.

You can still use pdflatex, but it comes with inconveniences. MaTeX solves this problem completely.

Another Mathematica package I learned about just after releasing MaTeX is MathPSfrag, which relies on PSfrag and should be able to create PDF output. However, I have never used it.

$\endgroup$
15
  • $\begingroup$ Maybe it is worth mentioning that you can load any latex fonts or predefined symbols using the "Preamble" option within MaTeX. I recommend it, it is really easy to use. $\endgroup$
    – tortortor
    Commented Oct 22, 2016 at 21:17
  • $\begingroup$ @tortortor Thanks for the feedback. I'll consider adding it to the documentation (blog page). $\endgroup$
    – Szabolcs
    Commented Oct 22, 2016 at 21:18
  • 1
    $\begingroup$ Oh, I just realized I was too optimistic. It does respect all the symbols I defined but it also seems to ignore the font. I am using \usepackage[sc]{mathpazo}. $\endgroup$
    – tortortor
    Commented Oct 23, 2016 at 1:51
  • $\begingroup$ @tortortor mathpazo works fine for me. $\endgroup$
    – Szabolcs
    Commented Sep 1, 2017 at 10:00
  • $\begingroup$ This is very nice, but I reeeeaaalllly need to use eps-images in a LaTeX-document. And psfrag-substitutions don't work with my Mathematica eps-files. $\endgroup$ Commented Sep 17, 2018 at 13:31
67
$\begingroup$

A more detailed guide on this topic is included in the MaTeX documentation, in the "Preparing Figures to Size" tutorial.

Exporting graphics with consistent font sizes


I'll show you my preferred way of exporting figures for use with $\LaTeX$.

I prefer to use consistent font sizes in figures. This means that I need to export PDF figures at the final print size and avoid scaling them within LaTeX. (Note that PDF files contain information about the physical print size of the document.)


Let's say we want a 10 cm wide figure that uses 10 point type. Taking an example figure from the documentation,

g = ContourPlot3D[
  x^4 + y^4 + z^4 - (x^2 + y^2 + z^2)^2 + 3 (x^2 + y^2 + z^2) == 
   3, {x, -2, 2}, {y, -2, 2}, {z, -2, 2}, Mesh -> None, 
  ContourStyle -> 
   Directive[Orange, Opacity[0.8], Specularity[White, 30]], 
  PlotPoints -> 30, MaxRecursion -> 5,
  
  BaseStyle -> {FontSize -> 10}] (* <-- specify text size in points here *)

Mathematica graphics

I increased the PlotPoints and MaxRecursion options, otherwise the raggedness of the surface will be noticeable at the high resolutions we will be using here.

I prefer to work in centimetres (and not printer's point, the default unit of Mathematica):

cm = 72/2.54;

Let's turn on the ruler (Window -> Show Ruler) and verify that the following is really 10 cm wide (you may also need to go to Edit -> Preferences and set the ruler units to centimetres):

Show[g, ImageSize -> 10 cm]

Mathematica graphics

As you noticed, exporting 3D objects as vector graphics is not ideal, so let's rasterize this figure at the correct size:

image = Rasterize[Show[g, ImageSize -> 10 cm], "Image", ImageResolution -> 600];

(Unfortunately Mathematica has trouble with scaling tick marks when rasterizing, so you may want to use an explicit tick specification if this is important.)

A resolution of 600 dpi ensures that it will look excellent in print, but rasterization may take a while.

Finally, export the figure to a PDF of the correct size:

Export["figure.pdf", Show[image, ImageSize -> 10 cm]]

(When using PDF, it is necessary to specify ImageSize within Show and not Export to avoid some problems.)

You can open the produced PDF, maybe even print it out, and you'll see that all the text is precisely at 10 point size.


The same principles can be applied to 2D graphics that export well as vector data:

g = Plot[Sin[x], {x, 0, 10}, BaseStyle -> {FontSize -> 10}]
Export["figure.pdf", Show[g, ImageSize -> 10 cm]]

Related reading:

$\endgroup$
1
  • 2
    $\begingroup$ While I have been using this workflow for a while, and I am sure there have been problems with exporting to size in some previous versions (6 or 7?), I recently realized that this convoluted workflow is not usually necessary in version 8. I don't have time right now to figure out if a more direct method of exporting to a given image size and resolution would work fine in all cases, so I am leaving this here as is. I'll update when I get the time to test. $\endgroup$
    – Szabolcs
    Commented Mar 19, 2012 at 14:18
21
$\begingroup$

You can use Mathematica-generated PDF graphics in LaTeX, using the pdflatex engine. I have been doing this for years. You have several options

  1. Use a font such as Times that will embed properly in the PDF, and a LaTeX package that uses matching fonts, such as mathptmx, txfonts or tex-gyre Termes. (There are actually many different font options in LaTeX beyond Computer Modern. If the packages that come with your TeX distribution don't appeal, I have published some more, including for fonts like New Baskerville.)
  2. If you have a Mac, right-click on the graph and choose "Print Graphic" from the pop-up menu, and then "Save as PDF" from the resulting dialog. The PDF that results is a higher version that will embed the Latin Modern fonts. You might need to crop the resulting PDF in Preview before inserting it in your LaTeX file.

PDF format handles opacity properly, so this will also solve some of the other issues you mention.

$\endgroup$
1
  • $\begingroup$ I second this. Have done this many times as well. I usually had to play with resizing though - used convert under Linux to change image resolution etc (this was a few years ago, M5 - M6. Perhaps now this is unnecessary). +1. $\endgroup$ Commented Jan 27, 2012 at 10:51
19
$\begingroup$

Endorsing Szabolcs' excellent $MaTeX$ package as a way to manage $\LaTeX$ in $Mathematica$ but with an addition that for me at least has removed the significant irritant of having to escape backslashes in strings.

For example, given some previous $\LaTeX$

 "\tilde{x}=\begin{cases}
 (\frac{n+1}{2}) \text{th term} & \text{n odd} \\
 ((\frac{n}{2}) \text{th} + (\frac{n}{2}+1) \text{th term})/2  & \text{n even}
 \end{cases}"

Applying $MaTeX$ out of the box means having to escape each occuring backslash:

Needs["MaTeX`"]

MaTeX@"\\tilde{x}=\\begin{cases}
  (\\frac{n+1}{2}) \\text{th term} & \\text{n odd} \\\\
  ((\\frac{n}{2}) \\text{th} + (\\frac{n}{2}+1) \\text{th term})/2  & \\text{n even}
 \\end{cases}"

enter image description here

It's not just the inconvenience of these mechanical modifications but that this also represents an impediment to programmatically modifying underlying $\LaTeX$. But following Simon Rochester's approach (while using a more efficient StringTake and specific MakeExpression - both as pointed out by Alexey Popkov in the comments), we can directly access the original string. Using MaTeX as a wrapper for this interpretative intercept

MakeExpression[
   RowBox@{"MaTeX", "[", str_String, "]"} | 
    RowBox@{"MaTeX", "@", str_String} | 
    RowBox@{str_String, "//", "MaTeX"} , StandardForm] := 
  MakeExpression[
   RowBox@{"MaTeX", "[", "StringTake", "[", ToString@InputForm[str], 
     ",", "{", "2", ",", "-2", "}", "]", "]"}, StandardForm];

we get a more natural MaTeX invocation

MaTeX@"\tilde{x}=\begin{cases}
  (\frac{n+1}{2}) \text{th term} & \text{n odd} \\
  ((\frac{n}{2}) \text{th} + (\frac{n}{2}+1) \text{th term})/2  & \text{n even}
 \end{cases}"

enter image description here

Some strings don't expect some of the harmless (in this context) escapes - e.g. MaTeX["X \sim \mathcal{N}(1,0)"] so we'll turn this error message off: Off[Syntax::stresc]

For string pre-processing we can do a similar intercept with a RawString wrapper to gain the ability to programmatically generate $\LaTeX$ for subsequent feeding into $MaTEX$

MakeExpression[
   RowBox@{"RawString", "[", str_String, "]"} | 
    RowBox@{"RawString", "@", str_String} | 
    RowBox@{str_String, "//", "RawString"} , StandardForm] := 
  MakeExpression[
   RowBox@{"StringTake", "[", ToString@InputForm[str], ",", "{", "2", 
     ",", "-2", "}", "]"
     }, StandardForm];

as illustrated by

med[var_String] := 
  StringTemplate[RawString["\tilde{`1`}=\begin{cases}
      (\frac{n+1}{2}) \text{th term} & \text{n odd} \\
      ((\frac{n}{2}) \text{th} + (\frac{n}{2}+1) \text{th term})/2  & \text{n even}
     \end{cases}"]][var];

vars = {"x", "y", "z"};

MaTeX[med /@ vars] // Column

enter image description here

Note that MaTeX operates on (non-string) expressions in the normal way. Hence programmability is preserved for $Mathematica$ expressions and the frontend's 2D formatting/shortcuts can still be used to readily generate $\LaTeX$ code as desired.

mean[var_] := HoldForm[
\!\(\*OverscriptBox[\(var\), \(_\)]\) = \!\(TraditionalForm\`
\*FractionBox[\(
\*UnderoverscriptBox[\(\[Sum]\), \(i = 1\), \(n\)]
\*SubscriptBox[\(var\), \(i\)]\), \(n\)]\)];
MaTeX[mean /@ vars] // Column

enter image description here

enter image description here

$MaTeX$'s use-cases would seem to be consistency and customising of $\LaTeX$ graphics/formulae, or for presenting complex formulae within a Mathematica notebook. Sometimes however, the need may arise for the original Mathematica code snippet/function to be included either in a paper or in as part of a collation within a notebook. The obvious method, HoldForm, does its holding after the underlying boxes have been parsed so to cut the parser off at the pass by way of showing how the code was originally entered, we can define a RawHoldForm using this same idiom (I've adapted from Simon Rochester's other answer).

MakeExpression[
  RowBox@{"RawHoldForm", "[", expr_, "]"} | 
   RowBox@{"RawHoldForm", "@", expr_} | 
   RowBox@{expr_, "//", "RawHoldForm"}, StandardForm] := 
 HoldComplete[
  ExpressionCell[RawBoxes@expr, "Input", 
   ShowStringCharacters -> True]]

and observe the difference

HoldForm[((x+"df") // f]

RawHoldForm[((x + "df") // f)]

(* 
   f[x + df]
   ((x+"df") // f)
 *)

Putting it all together in a single code block that provides a more natural MaTeX invocation, a string pre-processing, RawString wrapper and a RawHoldForm, the following can be loaded after $MaTeX$ (at least in its current version):

Needs["MaTeX`"];

MakeExpression[
   RowBox@{"MaTeX", "[", str_String, "]"} | 
    RowBox@{"MaTeX", "@", str_String} | 
    RowBox@{str_String, "//", "MaTeX"} , StandardForm] := 
  MakeExpression[
   RowBox@{"MaTeX", "[", "StringTake", "[", ToString@InputForm[str], 
     ",", "{", "2", ",", "-2", "}", "]", "]"}, StandardForm];

Off[Syntax::stresc]

MakeExpression[
   RowBox@{"RawString", "[", str_String, "]"} | 
    RowBox@{"RawString", "@", str_String} | 
    RowBox@{str_String, "//", "RawString"} , StandardForm] := 
  MakeExpression[
   RowBox@{"StringTake", "[", ToString@InputForm[str], ",", "{", "2", 
     ",", "-2", "}", "]"
     }, StandardForm];

MakeExpression[
  RowBox@{"RawHoldForm", "[", expr_, "]"} | 
   RowBox@{"RawHoldForm", "@", expr_} | 
   RowBox@{expr_, "//", "RawHoldForm"}, StandardForm] := 
 HoldComplete[
  ExpressionCell[RawBoxes@expr, "Input", 
   ShowStringCharacters -> True]]

Addends

  • While it is the ToString@InputForm@str that permits the sought-after programmability, as shown from MrWizard's and Jen's answers, the original strings can also be worked with in the frontend for one-off insertions

  • The use of StringTake avoids the infinite recursion in MakeExpression's definition

  • Thus far no downsides have been observed (escapes like \n, \t are not really relevant in latex formatting) although heavier users of $MaTeX$ might notice/uncover issues

  • From the originator's comments the original syntax was not designed and hence this would seem to offer an improved syntax for latex formatting in $MaTeX$

$\endgroup$
8
  • $\begingroup$ May be instead of modifying $PreRead we could make specific definition for MakeExpression? $\endgroup$ Commented Jun 3, 2017 at 4:06
  • $\begingroup$ For example: MakeExpression[RowBox@{"RawString","[",str_String,"]"},StandardForm]:=MakeExpression[RowBox@{"StringTrim","[",ToString@InputForm@str,",","\"\\\"\"","]"}]. Now evaluating RawString["\abc" ] returns "\\abc". $\endgroup$ Commented Jun 3, 2017 at 4:09
  • $\begingroup$ er ... yes that might be a little more logical :) will edit shortly - thanks $\endgroup$ Commented Jun 3, 2017 at 4:15
  • $\begingroup$ Also I would replace StringTrim[s, "\""] with more efficient StringTake[s, {2, -2}] which doesn't involve a call to the PCRE library. $\endgroup$ Commented Jun 3, 2017 at 6:33
  • 3
    $\begingroup$ That's very interesting! I did not think that there was a solution to this problem. It is a very real usability problem. Personally, I forget to escape all the time. I know very well I have to, and I respond to support email where people don't do it, but my fingers just refuse to type the double-backslash sometimes. $\endgroup$
    – Szabolcs
    Commented Jun 3, 2017 at 9:31
14
$\begingroup$

I usually draw only the non-textual part in Mathematica export it as PDF (if the graphic is simple) and do all text typesetting in LaTeX to get a consistent use of fonts across the document. This is mainly manual labor. On the LaTeX side I use TikZ. This entry on TeX.SE might be a starting point.

There is a solution for SVGs comming from Inkscape. I have not tried it with Mathematica however.

Regarding the size of the Graphics Objects there is no automatic solution I know of, if you don't want to rasterize the pictures already in Mathematica. In computer graphics you would use back-face culling to remove all the triangles not visible. If you export for example one of the mathematica spikeys into a PDF and open it. The sheer number of triangles exported slows the viewer down so much that you can see the graphic building up slowly. And you can see how many triangles are overpainted. I once tried to reduce the number of triangles however my knowledge about the graphic objects within Mathematica is not good enough for this task. So I usually rasterize them in Mathematica and export them as PNG.

EDIT: Over at TeX.SE there is a similar question, where tools for an EPS toolchain are mentioned. Never tried them myself however. Gnuplot and LaTeX play well together when EPS is used, perhaps this work for Mathematica EPS too?

EDIT2: This entry in Tex.SE explains the wrapping of a picture with axis and labels typeset with the TeX fonts in TikZ by an example EPS scatterplot.

$\endgroup$
13
$\begingroup$

About the size of 3d graphics, have you tried the ImageSize option in functions like Plot3D? For instance,

Export["~/Desktop/p2.pdf",
 Rasterize[
  Plot3D[
   Sin[x^2 + y^2]/Sqrt[x^2 + y^2],
   {x, -Pi, Pi},
   {y, -Pi, Pi}
   ],
  ImageSize -> 1000
  ]
 ]

exports a 527KB pdf file here, which looks OK on screen (without rasterizing, you get a 14.4MB file). You can increase the ImageSize if this is not enough.

EDIT: Actually, as Szabolcs points out in a comment, for this purpose ImageResolution is the right tool:

Export["~/Desktop/p2.pdf",
 Rasterize[
  Plot3D[
   Sin[x^2 + y^2]/Sqrt[x^2 + y^2],
   {x, -Pi, Pi},
   {y, -Pi, Pi}
   ],
  ImageResolution -> 300
  ]
 ]

as it takes care of font sizes etc.

$\endgroup$
4
  • 3
    $\begingroup$ I'd recommend ImageResolution instead which makes sure that every element of the image scales proportionally, including text and line widths. $\endgroup$
    – Szabolcs
    Commented Jan 26, 2012 at 9:59
  • $\begingroup$ @Szabolcs you're right, I added it to the answer (if you don't mind). I am making some composite images for a paper and have been using ImageSize all the time, so I kept thinking of that. Thanks for the correction. $\endgroup$
    – acl
    Commented Jan 26, 2012 at 10:09
  • 2
    $\begingroup$ When I was doing this a lot (2004-2009), I found that both ImageSize and ImageResolution are useful in combination, since one is not reduced to the other. May be it is different now, I have not checked. +1. $\endgroup$ Commented Jan 27, 2012 at 10:54
  • 2
    $\begingroup$ Here we may observe two of the top experts in this community -- people who have each given crucial help to countless users, answering thousands of questions -- both musing on the possible influence of ImageSize and ImageResolution on the scale and granularity of printed output. Is it not ludicrous that Mathematica should still, after all these years, require undocumented tricks and incantations simply to print something at a definite size? Then to top it off: "May be it is different now." As usual, whoever knows such details is keeping mum. $\endgroup$ Commented Dec 12, 2014 at 23:55
3
$\begingroup$

That means that I would like to use the same font in the graphics (labels for axis etc) as the main text.

I use MaTeX as follows:

    Needs["MaTeX`"];
SetOptions[MaTeX, "Preamble" -> {"\\usepackage{amsfonts,latexsym,amsthm,amssymb}",    
           "\\usepackage{pslatex,euler,beramono}"}]; 


funs = {Sin[x], Normal[Sin[x] + O[x]^8]};
Plot[Evaluate[funs], {x, 0, 2 Pi}, PlotLegends -> MaTeX /@ funs,
 Frame -> True, FrameStyle -> BlackFrame]

enter image description here

$\endgroup$
0
$\begingroup$

A simple answer that I had to find myself: "MathJax_Main" font family. It is automatically becoming MathJax_Math when you use Italic slant. Hope it will help.

$\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.