Jens Nöckel's Homepage

Computer Notes Home

profile for Jens on Stack Exchange, a network of free, community-driven Q&A sites

Creating and Post-Processing Mathematica Graphics on Mac OS X

Contents

Introduction — Obtaining Mathematica at the UO

  1. Should I be using Mathematica versions 8, 7, 6 or 5?
  2. Avoiding Mathematica Version graphics incompatibilities between different versions
  3. 3D geometric transformations
  4. Picking coordinates out of a plot using the mouse
  5. Pitfalls of dynamic interactivity
  6. Exporting graphics
  7. Exporting movies
  8. Tick marks
  9. Annotating graphics within Mathematica
  10. Modifying graphics within Mathematica
  11. Pasting PDF graphics into Mathematica
  12. Copying PDF from Mathematica to Adobe Illustrator (and others)
  13. Plot Legends
  14. Align ContourLabels tangentially to the contour
  15. Mathematica density and contour Plots with rasterized image representation
  16. Mathematica graphics shows incorrect fonts in Adobe Illustrator
Introduction — Obtaining Mathematica at the UO

Mathematica runs on many platforms, including Mac OS X. This page is written from a Mac OS X perspective, but if you're on a different platform you may still get some useful information here. In the past, I've also heavily used Mathematica on UNIX and Windows systems, and you shouldn't have any trouble adapting what I'm writing here to those other platforms. However, I have to leave that as an exercise for the reader. I'm trying to keep this page in step with changes in Mathematica, but the process of catching up with the most recent versions is still an ongoing effort.

Of course, if you need real expert help, you could always check one of these resources:

To obtain Mathematica through the University of Oregon site license, first check the information provided by IT Services. If you're a student planning to install Mathematica on your own computer, click on "Login to view available downloads" (bootom of page) and log in with your UO email address. Otherwise, do this:

  1. Request an Activation Key at this web site (you will need to register). Be sure to use your University of Oregon email address, xxx@uoregon.edu
  2. Click on the download link sent by email to create a WolframID, download the executable file, and run the installer on your local machine
  3. Enter the Activation Key (also sent by email) during the installation when prompted, make sure you are connected to the internet
  4. Unless you are upgrading, Mathematica will auto-renew your password as your site license is renewed in future years (no longer a manual process)

To calculate with Mathematica within your web browser, use one of these online tools:


  1. 3D geometric transformations
    • 3D Shadows Mathematica's way to produce "shadows" is not at all related to the way shadows are produced in ray tracers (for comparison, see e.g. my notes on how to get shadows from a partly transparent texture in Blender). Instead, MMA simply squishes a copy of the 3D object to a really thin pancake in the projection direction. So there doesn't have to be an actual surface onto which the shadow falls, and the shadow itself is actually a 3D object with all the complexity of the original.

      I have written a function that uses the above technique to create shadows as projections of an object onto an arbitrarily tilted plane: planarShadow, listed here with an example. You can use this to re-create the old ShadowPlot3D, too. With the function planarShadow from that page, the ominous bunny is created like this:

      data = ExampleData[{"Geometry3D", "StanfordBunny"}, 
        "VertexData"]; bunny = 
       ListSurfacePlot3D[data, MaxPlotPoints -> 50, Boxed -> False, 
        Axes -> None, Mesh -> False];
      z0 = Min[data[[All, 3]]];
      Show[bunny, planarShadow[bunny, z0 {2, -11, 1}, {0, 0, 1}]]
      	      
    • 3D Arrows

      It's possible to use Mathematica as a 3D modeling tool, in particular when dealing with shapes that are created and positioned programmatically. In earlier versions (below 6), this requires loading various packages to be able to specify standard shapes, rotate objects etc. (Geometry`Rotations`, Graphics`Shapes`, Graphics`Polyhedra`,...) In Mathematica 6 and up, much of this can be done without loading additional packages.

      The Cylinder command has become more flexible, and a built-in command for drawing a 3D arrow was introduced in version 7; but it has some "quirks". E.g., here is what you get with Graphics3D[Arrow[Tube[{{0, 0, 0}, {1, 0, 0}}, Scaled[.05]]]]: (yes, there is an arrowhead hidden in the hole because it didn't scale with the tube). To fix this, the arrowhead has to be scaled separately, like so: Graphics3D[{Arrowheads[.2],Arrow[Tube[{{0, 0, 0}, {1, 0, 0}}, Scaled[.025]]]}]. This syntax requires some care: the length in Arrowheads[.2] is a scaled quantity relative to the size of the graphic. The length determining the radius of the Tube, however, must be written as Scaled[.025] to have the same relationship to the graphic dimensions. If you inadvertently type both length scales the same way by entering Arrowheads[Scaled[.2]], Mathematica version 7 will initially show no output, and then crash when you try to correct the mistake. An additional directive that you may want to group with the Arrow command is CapForm["Butt"].

      Presumably many users have devised their own 3D arrows in version ≤ 5, and none of these are likely to work with Mathematica 6 and above. As an illustration for how things work in version 6, here is my way of making an arrow. It requires no added packages, and scales the arrow head relative to the arrow thickness, not independently of it.


      arrowLine[{p1_, p2_}, radius_:.1, headScale_:3] :=
       (* p1 and p2 are 3D points. They are passed as a list, to conform with the version-6 syntax for Cylinder[] *) 
       Module[{p3, scale2, norm, pyramidHeight = 3/2},
        scale2 = headScale*radius;
        norm = Norm[p2 - p1];
        If[norm > scale2*pyramidHeight,
         p3 = p1 + (p2 - p1)/norm (norm - scale2 pyramidHeight);
         {
          EdgeForm[],
          Cylinder[{p1, p3}, radius],
          GeometricTransformation[
           GraphicsComplex[{{0, 0, pyramidHeight}, {0, -1, 0}, {0, 1, 0}, {-1, 0, 0}, {1, 0, 0}},
            Polygon[{{3, 4, 1}, {4, 2, 1}, {2, 5, 1}, {5, 3, 1}, {5, 2, 4, 3}}]],
           Composition[
            TranslationTransform[p3],
            Quiet[
             RotationTransform[{{0, 0, 1}, p2 - p1}], {RotationMatrix::degen, RotationTransform::spln}],
            ScalingTransform[scale2 {1, 1, 1}]]
           ]
          },{}
         ]]
      

      The head is intentionally made of few polygons to limit memory usage when drawing a large number of arrows (and because the orientation of corners in the arrowhead can convey additional visual information).

      The first argument is the pair of start and end points. The two last arguments [optional] are the cross-sectional radius of the arrow stem and the size of the arrowhead, as a multiple of the radius. The default values are 0.1 for the radius and 3 for the relative scale of the arrow head. The module returns a list that can be displayed with a statement like Graphics3D[arrowLine[{{0,0,0},{1,0,0}}]]. If the arrow is too short compared to the head, an empty list is returned which displays as nothing.

      Click on this link to open a Notebook (PlaneWaveField.cdf) that illustrates the use of such vector drawings in electromagnetism (in particular showing polarization rotation in the Faraday effect).

      Note: Since Mathematica version 7, there are the new functions VectorPlot3D and ListVectorPlot3D, which also let us draw 3D arrows using the option VectorStyle->"Arrow3D". You can also define your own arrow heads in those plots, as in VectorStyle -> Graphics3D[{EdgeForm[], GraphicsComplex[{{tipHeight, 0, 0}, {0, 0, -1}, {0, 0, 1}, {0, -1, 0}, {0, 1, 0}}, Polygon[{{3, 4, 1}, {4, 2, 1}, {2, 5, 1}, {5, 3, 1}, {5, 2, 4, 3}}]]}], where tipHeight=2 (e.g.). However, there seems to be no way to scale the thickness of the cylindrical shaft independently of its length.

      If you do define your own vector plots as I did, but prefer smooth round arrows to my definition above, you can try the newly available standard 3D arrows (see image on the right) as in Graphics3D[{Arrowheads[.2], Arrow[Tube[{{0, 0, 0}, {0, 0, 1}}, .01]]}, Method -> {"TubePoints" -> 3, "ConePoints" -> 4}]. The Method option here is important when you need to speed up the rendering; default settings will make interactive 3D rotation feel sluggish when the number of arrows is large.

    • 3D field lines

      Instead of using an array of arrows to visualize three-dimensional vector fields, it can be more informative to display the field lines. These are one-dimensional curves whose tangent vectors are everywhere parallel to the given field. Such a representation is clearly useful when the field describes a physical flow of some kind, but it is also often used in electromagnetism. In 2D, Mathematica provides this plotting functionality in the function StreamPlot. For 3D fields, the function fieldLinePlot described on the linked page attempts to do the same thing.

    • 3D Text Labels

      Axes labels in Mathematica's 3D plots always try to adjust themselves so as to face the reader. This is often quite nice, but it also means that the author doesn't have definitive control over the label orientation at the time the graphic is produced. In a recent discussion on the Mathematica users group, I posted a relatively compact way of putting textual labels into a 3D plot in such a way that they are themselves Graphics3D objects that can subsequently be rotated, translated etc. An improved version of that function is discussed on the linked page, "Labels in Mathematica 3D plots".

      This function requires MMA version 8. It can be invoked with any expression as the first argument, so it can also be used to embed 2D graphics into a Graphics3D (essentially a rasterized version of StackGraphics).

      The picture on the right shows an application of these labels from a past lecture where I was illustrating spherical coordinates. The purple labels are created with the new function, the others are the standard type. The difference between these two types of labels is that the purple ones share the three-dimensional orientation of the object they refer to.

  2. Picking coordinates out of a plot using the mouse

    In 2D plots, it isn't always easy to accurately read off data by eye. In all earlier versions of Mathematica, you can examine the numerical values corresponding to positions in your plot by highlighting the graphic, then pressing Command. The current mouse position then appears at the bottom left of the Notebook window. You can click the mouse to make marks, and even copy marked coordinates by pressing Command-C.

    In Mathematica ≥ 6, this must be done differently.
    To get almost the same functionality as in version 5, you first click on the image, then press the period (. key), to get a cursor looking like a cross-hair (it incorrectly appears as a normal cursor in the screenshot). Also shown is the drawing tools pallette that contains this function; it's activated by pressing Ctrl-t. The orange dots under the curve are marked coordinates, and the hovering coordinate display follows the mouse.

    In Mathematica 7 and above, additional functionality has been added. See the video tutorial. There are some other interesting features that appear in the detailed description ("More Information") under CoordinatesToolOptions: The options "DisplayFunction" and "CopiedValueFunction".

    You may want to play with these options for several reasons. One is illustrated in the screen shot on the left. First note that the ContourLabels option has changed its meaning in version 7 from version 6, and the documentation does not reflect this: the choice Automatic now plots no labels, but makes tooltips appear over the contour lines. Here I was trying to see the value of a contour from ContourPlot[Cos[x] + Cos[y], {x, 0, 4 Pi}, {y, 0, 4 Pi}, ContourLabels -> Automatic], but at the same time tried to see the (x,y) coordinates. But there is a conflict between the two floating boxes, in that the coordinate display partly or completely obscures the tooltip containing the contour height! It would be nice to be able to control the justification of the tooltips, but as an alternative one could do the following:

    f[x_, y_] := Cos[x] + Cos[y]; ContourPlot[f[x, y], {x, 0, 4 Pi}, {y, 0, 4 Pi}, CoordinatesToolOptions -> {"DisplayFunction" -> (Append[#,f @@ #] &)}]

    With this, you get all three numbers in a single "Get Coordinates" tooltip. Of course this is only worth doing if the function value can be calculated quickly, but it can be done equally well for DensityPlot, e.g.


    Alternatives for real-time display:
    A real-time coordinate display can also be produced using dynamic interactivity. In particular, enter the following anywhere in the Notebook:
    Dynamic[MousePosition["Graphics"]]
    and the result is a continuously updated mouse position, whenever you hover over a plot. The coordinates here are those of the graph's PlotRange. If the option "Graphics" is omitted, the coordinates are referenced to the Notebook window.

    You can even get almost the old (version-5) behavior back by drawing your graphics using the StatusArea command, as shown in this example from the documentation:
    Dynamic[StatusArea[Plot[Sin[x], {x, 0, 10}], MousePosition["Graphics"]]]
    Of course, this may eventually only have sentimental value since the coordinates in the status area are actually harder to read than a normal Notebook line.

    Alternatives for coordinate copying:
    Arguably a more useful operation is to actually copy and save the mouse coordinates at selected points in the plot. To get a snapshot of the mouse coordinates in the graph every time the mouse is clicked, enclose all plotting commands in a ClickPane directive, e.g.,
    ClickPane[ Plot[Cos[x], {x, -π, π}, Frame -> True, FrameLabel -> {α, "cos α"}], (pt = #) &]
    which will update the variable pt at every mouse click in the plot. Now you have to dynamically display this variable somewhere in the Notebook:
    Dynamic[pt]
    That captures the desired coordinates.

    If you don't want to re-evaluate the expression that draws your plot, just to make it clickable, there is a more indirect way:

    1. Copy the plot
    2. Type ClickPane[
    3. Paste the graphic image at the cursor position
    4. Finish by typing , (pt = #) &]. This is what it might look like:
    5. The new cell contains a copy of the image which is now clickable, and the coordinates can be read off using
      Dynamic[pt]

    How accurate the coordinates are that you picked in the above approaches depends on how well you can position the mouse. However, in some cases, such as ListPlot, you may want exactly the coordinates of a discrete data point, even when you only manage to click somewhere in its neighborhood. The simplest way to do this is to wrap the data list in Tooltip to get a floating display of the data coordinates, similar to what I showed in the ContourPlot example above. But that doesn't let you easily copy the coordinates from the tool tip.

    For such cases, we can "augment" the Tooltip functionality by piggy-backing a PopupWindow on each of the Tooltip instances contained in the plot. This requires one simple replacement rule:

    popup window
    toolRule=Tooltip[x__]:>PopupWindow[Tooltip[x],Last[{x}]]; 

    which can be appended to any plot (or arbitrary expression) to convert simple Tooltips into clickable popup windows. For example, here is a plot of two data sets, illustrating how you would simply wrap all the data in a single Tooltip first, and then apply my rule:

    ListPlot[Tooltip@Evaluate[
     Table[N@Table[p+Exp[-t/10] { Cos[t],Sin[t]}/2,{t,0,10,1}],
       {p,{{.5,0},{1,0}}}
       ]],
      Joined->True, PlotMarkers->Automatic
    ]/.toolRule 

    The resulting plot is shown in the screen shot, after clicking one of the data points.

  3. Pitfalls of dynamic interactivity fractal tree

    The main problem can be summarized in one word: speed. I just looked at one of the featured (May 2011) interactive demonstrations at demonstrations.wolfram.com: "TreeBender." It's a nice interactive fractal tree. But it appears to be only a minor adaptation of another online demo that has, since 2010, been one of the all-time favorites at openprocessing.org: "Advanced Tree Generator," created by my son James Nöckel in Processing, a Java-based language. Compare for yourself which of these demos runs more smoothly and feels more responsive (James implemented a delay for more physical, smooth response, and you can crank up the number of branchings much higher). There are more dramatic examples, but the message is: Java, Flash and (lately) even Javascript can often beat Mathematica when interactivity is required.

    You will notice speed issues as well when you try my above Clickpane[] suggestion with a reasonably large plot, containing so many data points that it takes a perceptible time to draw. The mouse clicks will then be registered with an annoying time delay. This is, I think, a real stumbling block in data-intensive applications. To boil this issue down to its core, I've tried the following simple experiment: Copy the following code into two Mathematica Input lines:

    x = Dynamic[MousePosition[]]
    {ListPlot[
      Evaluate[
       Table[{.5, 0} + Exp[-t/100] {0.5 Cos[t], 0.5 Sin[t]}, {t, 0, 100, .001}]],
      Frame -> True], x}
    

    This may take a second or two to generate the graph of a dense spiral. The main thing to observe here is the displayed mouse position: Its coordinates are updated very sluggishly, both in the Out[] line of the assignment x = , and in the Out[] line containing the graphics object together with the value of x in a list.

    Now edit the above input so that the graphics object does not appear combined with the current mouse position, by changing the x at the very end to "x". Note that the Mouse position displayed as the first output line is now much more responsive.

    There is absolutely no difference between the graphics objects I am defining in either case, but the mere fact that the dynamic variable shares the same output cell as the graphics object in the first example causes a dramatic slow-down of the user interface. The delay doesn't seem to be caused directly by a redundant redrawing of the graphics object, but the Front End event handling is clearly inefficient. I'm currently waiting to hear back from Wolfram's experts on this; stay tuned.

  4. Exporting graphics

    The focus here is on exporting as PDF or EPS.

    • Avoiding artifacts in plots with VertexColors

      Many Mathematica graphics functions use VertexColors, a feature which is not supported by all but the most recent versions of PDF. To avoid difficulties with external applications, export such graphics by selecting them, then choosing the menu item File > Save Selection As..., and opening the Options dialog. There, choose "Use bitmap representation" for graphics containing smooth shading. Alternatively, export directly to a bitmap format such as PNG.

    • Avoiding artifacts in shaded contour and density plots

      In Mathematica 5.2, the command im0 = ContourPlot[Im[(x + I y)^(1/2)], {x, -1, 1}, {y, -1, 1}, Contours -> 21, PlotPoints -> 200, ColorFunction -> Hue] produces the illustration shown on the left. The shaded areas are made from stacks of uniformly colored shapes, and their number is of the order of the number of contours. There is no degradation in quality when exporting this plot.

      However, in Mathematica 6, 7 and 8, you may see something quite ugly if you create a plot like im1 = ContourPlot[Im[(x + I y)^(1/2)], {x, -1, 1}, {y, -1, 1}, Contours -> 20]: in the exported EPS or PDF, you get something that looks as if it has been put together as a 1000-piece puzzle, with white lines crisscrossing the shaded areas, see the screenshot on the right.

      This is because the polygons defining the shaded areas have invisible edges, and don't quite overlap. The large number of polygons is a clear step backwards compared to version 5.2, but at least the "puzzle piece" artifact can be removed by giving the edges the same color as the polygons. Here is a command that makes the necessary replacement, and then exports to PDF:
      Export["plot.pdf", im1 /. {EdgeForm[], r_?(MemberQ[{RGBColor, Hue, CMYKColor, GrayLevel}, Head[#]] &), i___} :> {EdgeForm[r], r, i}]
      The file exported as "plot.pdf" no longer shows the white lines and presents a contiguous, smooth appearance.
      If you also need to apply this trick to the graphics in the notebook itself, then it may be convenient to define a rule once and for all:
      contourPlotRule=({EdgeForm[], r_?(MemberQ[{RGBColor, Hue, CMYKColor, GrayLevel}, Head[#]] &), i___} :> {EdgeForm[r], r, i});
      Then you can type the shorter expression im1/. contourPlotRule to get an improved shading.
      If the artifacts still aren't quite gone after applying the above rule, you may want to add one more thing:
      contourPlotRule=({EdgeForm[], r_?(MemberQ[{RGBColor, Hue, CMYKColor, GrayLevel}, Head[#]] &), i___} :> {EdgeForm[{r,Thickness[Small]}], r, i});
      This sets the edge thickness just large enough to avoid the empty spaces between tiles.

      I even had the crisscross artifacts appear on screen on one of my Mathematica installations. This problem was fixed as follows: Quit Mathematica and move the user directory ~/Library/Mathematica out of the way. After relaunching Mathematica, this directory was rebuilt and the issue disappeared.

      The root cause of the puzzle-piece artifacts is the large number of triangles with which Mathematica represents contour shading and density plots. artifacts This in itself is a problem that can come back to bite you in an external graphics program because it not only increases the exported file size but also makes it slow to render. On the right is a snapshot I took in Illustrator while resizing a PDF produced with the following command:
      ContourPlot[ Sin[4 (x^2 + y^2)]/Sqrt[x^2 + y^2], {x, -1.5, 1.5}, {y, -1.5, 1.5}, PlotPoints -> 60, PlotRange -> {{-1.5, 1.15}, {-1, 1.5}, {-5, 5}}, Contours -> 1, Frame -> True, FrameLabel -> {"x", "y"}, Axes -> True]
      To create a PDF that is four times smaller and renders much faster, I wrote a different plotting function contourDensityPlot that superimposes a contour plot on the rasterized version of a density plot. See the definition and an example here. It should accept most of the options that DensityPlot and ContourPlot understand.

      For more information, see this separate page:
      "Mathematica density and contour Plots with rasterized image representation"

    • Exporting graphics with opacity effects

      Mathematica V. 6 has introduced the ability to create opacity effects, both in 2D and in 3D graphics. Transparent portions can be useful in Mathematica graphics because they let you display several objects without having them obscure each other. A simple example in 2D plots are intesecting areas such as those created by the Filling option. In 3D, surfaces with opacity less than one let us reveal axes and other objects that might otherwise be obscured.

      That's all very well as long as you're content with Mathematica itself as the vehicle for disseminating your work. But normally this isn't where you'd want to stop. You'd go on to export your graphics for inclusion in some other media, e.g. PDF or HTML, or for post-processing in a graphics program.

      What happens to transparency then?

      For the most part, what you really want is for the graphic to look the same in the external application as in your Mathematica Notebook. That means, once opacity has done its job of revealing various hidden things in your Mathematica plots, there is no need for the exported graphic to "remember" that it came from a partly transparent object. In that case you'll be fine choosing any export format that's convenient, making sure to think twice about using vector formats when exporting 3D graphics (because the files can get huge).

      Things get a bit more difficult if you insist on maintaining transparency as a property of the exported graphics. There are not too many formats that support this.

      • The most well-known bitmap format that does this is GIF, but one can also use PNG or TIFF instead. Not among the eligible formats is the popular JPEG. In Mathematica, GIF is the most flexible choice, because it supports the option TransparentColor. Here is the syntax:

        Export["plot.gif", Style[%, Magnification -> 2], "TransparentColor" -> White]

        If you want to get a transparent PNG or TIFF, replace the option "TransparentColor" -> White above by Background->None. Alternatively, if transparency is desired for other parts of the image, you could first use the command Export["plot.png", Style[%, Magnification -> 2]] (version-6 syntax), and then process the result along the lines of the notes on transparency in bitmap graphics. The option Magnification -> 2 magnifies graphics including plot labels, whereas an option such as ImageSize -> 600 makes the plot labels look smaller compared to the graphics. More on Magnification below.

      • As for vector formats, the good old EPS format is out when transparency is desired. But you can export as PDF or as SVG. Since PDF is the most familiar one, that may be preferred by many. If you open such a PDF in Illustrator, it will retain the opacity settings from Mathematica. You don't see that at first, though, because the PDF is by default exported with a solid background. To get the transparent appearance back, export your plot as follows:
        Export["plot.pdf", Style[%, Background -> None]] (V 6 syntax).
        For completeness: you can remove the background in version 5 PDFs, too, by typing Export["plot.pdf", %, ConversionOptions -> {"Background" -> None}]]

        The picture on the right shows a Mathematica-generated PDF, with a black gradient added in Illustrator to show that the sphere is translucent.

        If you choose SVG export, then the default is to include no background, so there's no additional step involved. The disadvantage of SVG is mainly the lack of full support for its specification in many graphics editors and browsers. Adobe Illustrator does a good job with SVG, but for complex SVG graphics I would recommend Inkscape, which is free but very capable, with SVG as its native file format. The newest version of Inkscape can also read PDF files. In my experience, Inkscape was able to handle even SVG files that Illustrator choked on.


        Note: although I chose 3D graphics as an example, remember that it's generally not a good idea to export 3D graphics as 2D vector graphics, because 3D rendering is ultimately pixel-based. In the case of Mathematica 7, this is compounded by the fact that PDF export is somewhat unreliable: Everything seems fine with the simple command Export["sphere.pdf", Graphics3D[Sphere[]]], creating a file that can be read by Illustrator CS 3 (although it complains "An unknown image construct was encountered"). The PDF file uses vertex colors to draw the sphere exactly as it looks in Mathematica. However, you can clearly see a "jigsaw tile" effect in the last screenshot, in which I added Opacity with Export["sphere.pdf", Graphics3D[{Opacity[.5], Sphere[]}]]. The resulting uniform polygons visible in the screenshot are probably undesirable for most purposes. This brings us back to the bitmap workaround mentioned earlier. Last but not least, bitmap representations of 3D data usually render much faster than vector formats. This is important if you want to embed your pictures in a PDF document (a big vector graphic can stall the page display and strain the reader's patience).

      • Magnification in PDF

        Note: If you use Magnification and the resulting graphic ends up wider than the current Notebook window width, the graphic sometimes stops being scaled whereas the fonts continue to be magnified. This inconsistent behavior arises when the graphic you're magnifying doesn't have a specific setting for ImageSize.

        See also this StackExchange post. In general, when you're planning to export a graphic, it's a good idea to create it with an explicit ImageSize, or by setting ImageSize→Medium to enforce the default width.

        You may wonder if the Magnification setting in a PDF Export command is affected by the global value that one can set in the Mathematica Preferences (Preferences > Advanced > Formatting Options > Font Options > Magnification). The answer is no: the latter magnifies everything that gets displayed on the screen, but not the exported graphics.

        The default setting for Magnification in PDF Export is 0.8, so the exported image will look smaller than on screen. As discussed on stackoverflow, you could change the PrintingStyleEnvironment option of your notebook. Another simple way to get a faithful PDF representation is to click on the graphic in your notebook, then choose Copy as... → PDF from the Edit menu, and paste the result into (e.g.) Preview via "New from Clipboard."

        Warning: Don't try to copy complex 3D graphics as PDF — the file is likely going to be impractically large. See the related question on StackExchange.

      • Exporting 3D graphics as PDF/EPS

        As mentioned above, PDF files with 3D graphics become too unwieldy when Mathematica overburdens them with the immense numbers of polygons, each drawn individually. In addition, for 3D graphics, there is no cure for the mesh-line artifacts shown in the translucent sphere above. So if you want to export 3D graphics to PDF, it's best to rasterize the output. Mathematica does this by default when it decides that the correct display of the graphic would require features that aren't standard in typical PDF viewers. When that happens, the rasterization is performed behind the scenes and the user doesn't even have to think about it; the resolution is appropriate for preint documents. One can turn this default action off by setting the Export option "AllowRasterization"->False, but for 3D graphics I would actually suggest making it mandatory.

        Unfortunately, forcing rasterization with "AllowRasterization"->True as an export option doesn't quite produce the desired result: the image resolution in the resulting PDF file is too low and would have to be adjusted manually. So instead, one should force Mathematica to decide on its own that rasterization is the right thing to do, because then it somehow manages to set the correct print resolution automatically. One way to do this is to add some part to your 3D graphic that contains vertex colors, a feature that triggers automatic rasterization.

        One could, for example, add a polygon with a texture to each plot before exporting. Instead of doing this manually for all plots of interest, it may be more convenient to put the following in the initialization section of your notebook:

        Map[SetOptions[#, 
            Prolog -> {{EdgeForm[], Texture[{{{0, 0, 0, 0}}}], 
               Polygon[#, VertexTextureCoordinates -> #] &[{{0, 0}, {1, 
                  0}, {1, 1}}]}}] &, {Graphics3D, ContourPlot3D, 
           ListContourPlot3D, ListPlot3D, Plot3D, ListSurfacePlot3D, 
           ListVectorPlot3D, ParametricPlot3D, RegionPlot3D, RevolutionPlot3D,
            SphericalPlot3D, VectorPlot3D}]; 
        3d plot

        This creates an invisible triangle (with a transparent texture) and adds it as a Prolog to all 3D plotting functions. I chose to use the Prolog option for this trick because I'm assuming it's rarely used with 3D graphics. If you do need to use a Prolog of your own in some plots, just include the above polygon as part of the Prolog.

        As an example, you can verify that both the surface features and the tick marks of the following plot are well resolved when it's exported in a standard way:

        a = Show[ParametricPlot3D[{16 Sin[t/3], 15 Cos[t] + 7 Sin[2 t], 
            8 Cos[3 t]}, {t, 0, 8 \[Pi]}, PlotStyle -> Tube[.2], 
           AxesStyle -> Directive[Black, Thickness[.004]]], 
          TextStyle -> {FontFamily -> "Helvetica", FontSize -> 12}, 
          DefaultBoxStyle -> {Gray, Thick}]
        
        Export["highRes.pdf",a]  

        The file size is reduced from over 200 MBytes to just 350 KBytes by applying the above trick to this example. The same also works when exporting to EPS format.

    • Exporting Graphics with Tooltips

      In contour plots, tooltips by default show the height of the function when the mouse hovers over a contour. This feature is preserved to a certain extent when you export to HTML or XML. Click on the image to see a web page illustrating the point. For example, create a contour plot, highlight the notebook cell and choose Save Selection As ... from the File menu. Export as "Web Page" (or "HTML" to create a page fragment without headers). Open the result in a web browser, and you will see tooltips appearing over the contours, too. The labeling isn't as accurate as ain Mathematica, and most browsers have an intentional delay before the tooltip appears. This feature could be useful to convey at least a rough feeling of interactivity. The way this is done is to use an HTML imagemap. Unfortunately, the tooltip labels are quantitatively unreliable and hence may do more to confuse than to clarify. In the example linked on the right, I chose a plot that combines contours and vector plots, and exported by saving the entire notebook as XML. One of the tooltips contains extraneous characters that I would have to clean up by hand. Most of the time, the tooltip that appears is not correct for the contour you're hovering over. Another problem with image maps is that they can't be rescaled easily on the HTML page. With HTML5 and HTML Canvas (see the drawing program here for example), the limitations of this old-style image map approach could be overcome (I haven't had time to work on this yet).

  5. Exporting movies

    In Mathematica you can easily animate groups of plots, and of course such animations need to be exported once in a while.

    My advice: don't waste your time trying to export movies from Animate or related Manipulate cells. It's just too inflexible, and QuickTime will not be available. Instead, before exporting a movie, always create a list of frames so that you know exactly what you're getting.

    Let's say you have 250 plots in your notebook and want to turn them into frames of a movie. Here are some options:

    • QuickTime

      QuickTime (.mov or .qt) is a popular movie format, especially on Mac platforms. This format was not available directly in the Export command prior to Mathematica version 8, but in V 5 it's easy to produce via the Frontend menu item Edit → Save Selection As.... As the name implies, one selects a sequence of graphics cells and gets the QuickTime movie. One additional step is required in the Compression Settings dialog: Shift-Option-Click on the preview to make it fit into the pre-defined movie bounding box (however, this never worked reliably).

      In Mathematica V 6, 7, exporting QuickTime has become slightly more complicated, but the results are better. In tose older versions, the Export command still doesn't know about QuickTime, whereas Import does (To import frames from a file "movie.mov", type Import["movie.mov", "ImageList"]). In Mathematica V 8, Export works with MOV format. This means QuickTime movies can now be created fully automatically, without manually selecting cells and choosing menus. However, the manual route may still be useful sometimes, particularly because it brings you to a convenient menu with options for the movie quality etc. So let's assume you want to manually make such a movie from a Table of graphics along the lines of
      a = Table[ Plot[Sin[ω t], {t, 0, 10}, PlotRange -> {-1, 1}, ImageMargins -> .4], {ω, .1, 2, .1}]
      (note: the , ImageMargins -> .4 option helps avoid losing parts of the plot due to cropping on Export). Then you'll be disappointed to find that selecting the output and going to the QuickTime export window via File → Save Selection As..., Mathematica only lets you make a single picture of all frames combined. To get the old behavior back, we first have to unravel the list in which the graphics is wrapped. After making the list as described, add the following line:
      Map[Print, a]
      This will create all the plots conveniently bracketed in a CellGroup which you can select with a single click. With this, QuickTime export can proceed as desired. The bounding box of the movie seems to be correctly set, even without the manual Shift-Option-Click adjustment mentioned above for V 5. In order to avoid color artifacts, choose a large value for the color depth (this helped me fix an issue with unexpected black areas appearing in ListPlot-generated frames).

      Mathematica cannot generally import movie files. Even QuickTime movies exported from Mathematica itself as described above cannot be re-imported. Import seems to work only for a narrow range of formats, such as the one in the documentation (Import["ExampleData/clip.mov", "Animation"]).

    • Flash

      Flash .swf export is a new feature of Mathematica V 6. To make a Flash movie from your list of plots (a), the usual syntax Export["a.swf", a] will do the job. Unfortunately, the interatcivity provided by Manipulate controls is not preserved in Flash export, and the animation is ratserized so that you are not making use of most of Flash's main selling points. To export a single plot (such as a = Plot[...] as a Flash file, enclose it in a list, as in Export["a.swf", {a}].

    • Export an image sequence

      The reason I started this page was the need to post-process Mathematica graphics externally, and I still think most graphics manipulation jobs are best done outside of Mathematica. Making a movie out of single JPEG images is very quick with the shell command ffmpeg -sameq %04d.jpg output.mp4 (available from fink or macports) and although Mathematica can do this too, the effort is greater and the output options are more limited. Specialized free software with superior performance include: GraphicsMagick / ImageMagick, ffmpeg, the Gimp, and Blender (the overlap with Mathematica decreases roughly in this order).

      If you want really fast and fine-tuned movie creation from Mathematica plots, export them as an image sequence and create the movie in one of the above applications.

      Here is an export function that utilizes multiple cores if available, to speed up the export:

      exportFrames[baseName_, a_, ext_:"png"] := Module[{l = Length[a], d}, d = Length@IntegerDigits[l];
       ParallelDo[
        Export[baseName <> IntegerString[i, 10, d] <> "." <> ext, a[[i]]], 
        {i, l}]
       ]	      
      If your images are in a list a (as in the above QuickTime example), the function call exportFrames["movie", a] will create files named movie001.png etc. in the current directory. The number of zeros in the running index (001) is automatically adjusted to the number of frames. With the image sequence exported to the disk, you are now ready to follow my instructions for creating movies in Blender, or use any of the multitude of other available tools.

      In Mathematica version 8, there is also a new export format "VideoFrames" which accomplishes the same task. For the example above, you'd just type:

      Export["movie001.png", a, "VideoFrames"]	      

      The digits 001 specify where the file numbering should start, and the minimum number of digits to be appended to the base name. Although this built-in command cannot be parallelized, it is a fast and convenient solution.

    • GIF animations

      The GIF bitmap format supports animations, but unlike regular movies these animations don't play in a video controller with a playhead and controls such as a "Pause" button. That's perfectly sufficient for many purposes, and GIF export works without problems in Mathematica. To save a list of graphics a as a GIF89 animation, type Export["anim.gif", a, "DisplayDurations" -> .05] where 0.05 is the frame duration. By specifying a list of durations, you can control the delay between individual frames. There is also an option to choose a transparent background, as in "TransparentColor" → White (best used with static images because animations are made by stacking images without disposing of previous frames, so the latter show through wherever the new frame is transparent). To add looping, one can use the option AnimationRepetitions -> Infinity (this is an infinite loop).

  6. Tick marks

    A long-standing issue with any kind of tick marks in Mathematica is that the default setting is not acceptable for scientific publication. This applies both to the style of major and minor tick marks and to their placement. An excellent solution to this problem is CustomTicks, part of LevelScheme, a free package by Mark Caprio. See a post with an example here (I also address an installation issue in that post).

    However, Mathematica notebooks sometimes need to be stand-alone, independent of additional packages. For example, in a class setting you would like to be able to distribute notebooks without having to worry about students (mis-)installing required packages.

    I don't have a better solution to this issue yet. It is something that Wolfram seriously needs to work on. It also turns out that the size of tick marks doesn't scale properly when you apply Magnify to a plot. For two-dimensional graphics, you can work around this by first converting the ticks to standard graphics primitives using FullGraphics.

  7. Annotating graphics within Mathematica

    One of the new features in the Mathematica 6 user interface is the ability to do interactive drawing and typing directly in a plot. For example, to add an arrow with some explanation to a plot, just highlight the graphic, press the "a" key and drag the mouse to get an arrow. Then press "t" to get a text field. You can enter both text and equations here.

    Even if you have inserted formula labels programmatically (using TraditionalForm[HoldForm[...]] to get traditional math typesetting), you may later wish to re-position it. As shown below, all you have to do is double-click until the orange selection rectangle appears, which can then be dragged freely:

    The annotated picture can be copied as PDF (I found I have to select the bar on the right of the graphic first), and pasted into other applications (e.g., Preview). Likewise, the selected picture can be saved to a PDF file via Edit → Save Selection As.... With that added drawing capability, Mathematica makes it much easier to create plots that don't require post-processing in other applications such as Adobe Illustrator. You can now go from Mathematica to your LaTeX document, or another document preparation system, without detour.

    However, use manual annotations with care: If you generated a plot programmatically and annotate it manually, then you will lose your manual edits when you later decide to change the programmatic part. Let's say you have a plot containing two curves, and manually added text to one of the curves. Later on, you decide to change the plot parameters of the other curve so you re-plot the graphic. Mathematica fortunately keeps your earlier annotated graphic in a separate Notebook cell, but the re-evaluated plot will of course have none of your manual annotations. So you have to proceed as in any other graphics editor: click to select your annotation in the original picture, and copy it. Then double-click back on the new plot to get a grey border around it, and do a paste. You should now have the old annotation in the new plot, at the correct relative position.

  8. Modifying graphics within Mathematica

    When it comes to manipulating graphics, one should distinguish between annotations (adding content to the picture), and edits (in the sense of actually modifying the pictorial content). In Mathematica, you can do both. In the screenshot to the right, the spikes are not a malfunction, they were edited in by hand. What you do to edit a plot like this, is to double-click on the graphic, then double-click on the curve. This makes the individual points of the curve editable. The mouse can now be used to drag them around. In MMA version ≤ 8, you cannot directly select the axis and tick labels and edit. However, MMA 8 lets you edit these labels to a certain extent after you outline all fonts as described below.

    The same warning applies here as above: manual edits are "fragile", they get shoved aside when you re-evaluate your notebook cells. Use this with care!


  9. Pasting PDF graphics into Mathematica

    On OS X, there are some nice PDF viewer applications such as Preview or Skim. In some cases you may find yourself copying PDF selections from one of those viewers directly into Mathematica, perhaps as part of a Mathematica-based presentation. This involvles selecting a rectangle in the original PDF file, copying to the system clipboard, and then pasting into a Notebook. However, when pasting from Preview into Mathematica 7.0.1 the rectangle that you origionally selected is ignored, and instead Mathematica displays the whole page from which the selection was taken. The fix for this is a script that can be found here. Some discussion of the issue took place on the Mathematica users mailing list.

    In MMA version 8, this problem no longer occurs, so my workaround script isn't needed here. However, there's a new bug: PDF that has been copied and pasted from external applications will look jagged in the Notebook when the view magnification is not 100%, and the PDF cannot be exported again. While this bug isn't fixed, you may want to try the work-around on this page.

  10. Copying PDF from Mathematica to Adobe Illustrator (and others)

    Copying graphical output from Mathematica to Illustrator, the main issue concerns the fonts and how to preserve them. This is dealt with below.

    • Invisible points outside the plot range

      Another problem that occurs more sporadically is that Illustrator may complain about your attempt to paste the PDF: "Can't paste objects". This can happen because Mathematica may have created invisible points in your plot that are excessively far outside the plot range.

      An example where this occurs are parametric plots, as shown in this Illustrator screen shot with everything selected, to reveal points outside the plot region. In Illustrator CS3, such plots can still be pasted by using "Paste in front" instead of the general paste function. However, this no longer appears to work in CS4, so we'll need a different solution. Specifying a PlotRange tells Mathematica only which points are cropped from the displayed graphic (by the "MediaBox", the black rectangle in the screen shot), but these points are nonetheless present as hidden baggage in the exported PDF. That's fine with most PDF viewers, but not when pasting into Illustrator. So how do you get rid of these unwanted parts of the plot, if Illustrator doesn't let you paste? The answer is to specify not only the PlotRegion->{{xmin,xmax},{ymin,ymax}}, but also RegionFunction -> Function[{x, y}, (xmin < x < xmax) && (ymin < y < ymax). This will force all the points outside the specified rectangle to be dropped instead of just being hidden from view.

      The example plot here is properly truncated by the following code:

      With[{xMin = -10, xMax = 10, yMin = -10, yMax = 10}, 
        ParametricPlot[Evaluate[Table[
           {u + Sin[u] Exp[-v], v - Cos[u] Exp[-v]},
           {u, -\[Pi], \[Pi], \[Pi]/10}]], {v, -10, 10}, Frame -> True, 
         FrameLabel -> {"x", "y"}, 
         PlotRange -> {{xMin, xMax}, {yMin, yMax}},
         RegionFunction -> 
          Function[{x, y}, (xMin < x < xMax) && (yMin < y < yMax)]]] 
      
    • Mathematical formulas

      What if I want to copy a Mathematica formula as PDF, e.g., for a presentation? There is the menu item Edit → Copy As → PDF, which is often sufficient — this option inexplicably doesn't show up in the right-click context menu for a Notebook selection, so you have to go through the menu bar. However, you'll get a more customizable and predictable result using the following definition, which converts arbitrary Mathematica expressions (except images) to a vector drawing based on TraditionalForm:

      toPDF[x_, opts : OptionsPattern[]] := 
        If[!ImageQ[x], 
         First@ImportString[
           ExportString[
            Pane[Style[TraditionalForm[HoldForm[x]], 
              FilterRules[{opts}, Options[Style]]], 
             FilterRules[{opts}, ImageSize], 
             BaseStyle -> {FontFamily -> "Times New Roman", 
               Background -> (Background /. {opts} /. {Background -> 
                    None})}], "PDF"], "PDF", "TextMode" -> "Outlines"]
         ];
      SetAttributes[toPDF, HoldFirst]
      

      Now enter your formula as shown in this example:
      toPDF[Integrate[1 + Sin[x]^2, {x, 0, Pi}], FontSize -> 18]
      and you'll get a cropped graphics cell containing the PDF rendering (copying the formula from another cell works just as well, no matter what form it was in): .

      The main features of this approach are:

      • the fonts in the resulting PDF are outlined and hence will work in all external applications (see the related issue with Adobe Illustrator).
      • My preference for TraditionalForm typesetting is hardcoded into the function.
      • The conversion can be done without having to navigate through menus with the mouse.
      • You can specify additional options for the conversion to PDF.

      To immediately copy the PDF to the clipboard, simply wrap the whole command in CopyToClipboard.

      Here is another example showing different options for fonts, colors and magnification:

      If the formula is too long, you can influence the line-wrapping by specifying the width w of the PDF using ImageSize -> w.

      An alternative approach is to copy the formula expression as LaTeX, as described on a separate page.
      But toPDF achieves almost the same thing without the intermediate step involving a LaTeX engine.


  11. Plot Legends

    I find Mathematica's PlotLegends package unusable, both for aesthetic and functional reasons. So we'll have to craft our own legends. The challenge is how to do this in a simple but flexible way that doesn't degenerate to a completely manual process. By "manual," I mean to hand-edit the legend using the drawing tools. That could be a last resort — but here I'll explore alternatives.

    The documentation for Inset, under "Applications," contains a custom legend construct of the form Epilog -> Inset[Panel[Grid[ ...]]], and I'll try to improve on that.

    • Finding colors and marker symbols when Automatic setting is used

      In list plots with many data series, Mathematica provides great freedom of choice for the symbols identifying each series. The limits of this freedom are set by your imagination and by the bugs in ListPlot (see here for a version-7 bug that's been fixed in MMA 8.

      In practice it may not be worth your time to try and make up new plot markers. Since Graphics accepts the Axes and Frame options now, one can in principle make lower-level constructs to create customized list plots, which however forgoes the convenience of ListPlot options such as DataRange.

      If you let Mathematica make the choice for you with PlotMarkers → Automatic, it generates a reproducible but arbitrary combination of shapes and colors for different sets of data in the same plot (i.e., when plotting {dataSet1, dataSet2, ...}, you get a unique plot marker style for each dataSeti). In such plots, it is important to have a legend that explains the meaning of the symbols.

      As a prerequisite to making your own customized legends for a ListPlot you need the list of plot symbols and colors that Mathematica uses by default, so you can tabulate them in your legend. This information isn't easily extracted from the plot itself because it's converted into graphics commands, so functions like AbsoluteOptions don't reveal it. There is an undocumented function Graphics`PlotMarkers[] that provides the sequence of plot symbols, and the color information is available separately through ColorData[1]; but I don't like Graphics`PlotMarkers[] because it's syntax-colored as if it were an undefined variable. As a solution, I devised the following function:

      markerSymbols[n_] := 
       Drop[Drop[
          ListPlot[Transpose[{Range[n]}], PlotMarkers -> Automatic][[1, 2]][[1]],
           -1] /. Inset[x_, i__] :> x, None, -1]
      

      It takes an integer argument n which is the number of different plot markers you're using. The output is a list with n entries representing the successive plot markers from 1 to n. Each entry contains a list made up of the color information and the symbol. The list format of the output allows you to call this function once and store all the plot markers for later use. If you just want to know, e.g., what the 4-th plot marker looks like, the syntax would be markerSymbols[4][[4]].

    • Creating custom legends

      As an application of the markerSymbols function above, let's now make a plot legend. Using Epilog -> Inset[Panel[Grid[...]]] produces a result that looks nice on screen, but its smooth, rounded appearance is lost when you convert to PDF/EPS. The default style for Panel also causes fonts to be different from the rest of the plot, so it could be better to replace Panel by Pane.

      It is also possible to get a rounded appearance for our legend inset by means of Framed[]. To proceed, it's useful to define the following function, which takes a set of text labels as its argument. Options you can specify include: the PlotStyle directives (i.e., color), the marker symbols (provided by markerSymbols, together with the colors), and the options accepted by Frame:

      Options[legendMaker] = 
        Join[FilterRules[Options[Framed], 
          Except[{ImageSize, FrameStyle, Background, RoundingRadius, 
            ImageMargins}]], {FrameStyle -> None, 
          Background -> Directive[Opacity[.7], LightGray], 
          RoundingRadius -> 10, ImageMargins -> 0, PlotStyle -> Automatic, 
          PlotMarkers -> None, "LegendLineWidth" -> 35, 
          "LegendLineAspectRatio" -> .2, "LegendMarkerSize" -> 8, 
          "LegendGridOptions" -> {Alignment -> Left, Spacings -> {.4, .1}}}];
      
      legendMaker[textLabels_, opts : OptionsPattern[]] := 
        Module[{f, lineDirectives, markerSymbols, n = Length[textLabels], 
          x}, lineDirectives = ((PlotStyle /. {opts}) /. 
             PlotStyle | Automatic :> Map[ColorData[1], Range[n]]) /. 
           None -> {None};
         markerSymbols = 
          Replace[((PlotMarkers /. {opts}) /. 
               Automatic :> (Drop[
                    ListPlot[Transpose[{Range[n]}], 
                       PlotMarkers -> Automatic][[1, 2]][[1]], -1] /. 
                   Inset[x_, i__] :> x)[[All, -1]]) /. {Graphics[gr__], 
               sc_} :> Graphics[gr, 
               ImageSize -> ("LegendMarkerSize" /. {opts} /. 
                   Options[legendMaker, 
                    "LegendMarkerSize"] /. {"LegendMarkerSize" -> 8})], 
            PlotMarkers | None :> 
             Map[Style["", Opacity[0]] &, textLabels]] /. 
           None | {} -> Style["", Opacity[0]];
         lineDirectives = PadRight[lineDirectives, n, lineDirectives];
         markerSymbols = PadRight[markerSymbols, n, markerSymbols];
         f = Grid[
           MapThread[{Graphics[{#1 /. None -> {}, 
                If[#1 === {None} || (PlotStyle /. {opts}) === None, {}, 
                 Line[{{-.1, 0}, {.1, 0}}]], 
                Inset[#2, {0, 0}, Background -> None]}, 
               AspectRatio -> ("LegendLineAspectRatio" /. {opts} /. 
                   Options[legendMaker, 
                    "LegendLineAspectRatio"] /. 
                    {"LegendLineAspectRatio" -> .2}), ImageSize -> ("LegendLineWidth" /. {opts} /. 
                   Options[legendMaker, 
                    "LegendLineWidth"] /. {"LegendLineWidth" -> 35}), 
               ImagePadding -> {{1, 1}, {0, 0}}], 
              Text[#3, FormatType -> TraditionalForm]} &, {lineDirectives, 
             markerSymbols, textLabels}], 
           Sequence@
            Evaluate[("LegendGridOptions" /. {opts} /. 
                Options[legendMaker, 
                 "LegendGridOptions"] /. {"LegendGridOptions" -> 
                 {Alignment -> Left, Spacings -> {.4, .1}}})]];
         Framed[f, 
          FilterRules[{Sequence[opts, Options[legendMaker]]}, 
           FilterRules[Options[Framed], Except[ImageSize]]]]];
      	      

      Next, create an example plot:

      plotExample = ListPlot[Evaluate[Table[RandomInteger[3 i, 10] + 2 i, {i, 3}]], 
      PlotMarkers -> Automatic, Joined -> True]
      	      

      Finally, combine the plot with a legend:

      Overlay[{plotExample, 
        legendMaker[{"August", 
          "September", "October"}, PlotMarkers -> Automatic, Background -> LightOrange, 
         RoundingRadius -> 10]}, Alignment -> {Right, Top}]
      	      

      This procedure can be equally well applied to any other type of plot. The placement of the legend is controlled by the Overlay option Alignment -> {Right, Top}. Further discussion and examples of this function can be found in my post on StackExchange and a follow-up here. These links contain additional higher-level functions that can create legends "semi-automatically".

      I decided to use overlays for legends because that makes it easier to place a single legend even when you're displaying several plots in a grid (see this post). A potential disadvantage is that the RoundingRadius is not referenced to the size of the actual plot, so you may have to adjust it manually after visual inspection. An overlay can't be mdified with the graphics editing tools in Matheamatica. That's why I defined a function deployLegend in the StackExchange post mentioned before, that flattens the legend into a graphics object combined with the plot. If you want to get a custom legend (from legendMaker) as a Graphics object that can be used in an Inset, the easiest way to do that is to use the function toPDF I defined above and insert toPDF@legendMaker[...].

  12. Align ContourLabels tangentially to the contour

    It is conventional in contour plots to label selected contours by their height value. Often the labeling becomes clearer if we also rotate that label so that it is parallel to the corresponding contour. This alignment makes the association between labels and contours easier to discern, in particular when there are many contours close together. Mathematica does not do this, and instead prints all labels horizontally. The ContoutLabel option allows you to customize labels but cannot be used to rotate them. This is because the only information passed to each label consists of the local coordinate and plot height at the position of the label. For a rotation, you'd need to know the direction of the contour through that point. Of course we could get this information by calculating the gradient of the function being plotted, but that will work only with ContourPlot, and not with ListContourPlot (which plots lists of points instead of a function).

    To at least partially solve this shortcoming, I wrote a function rotateContourLabels which post-processes Mathematica's contour plots to rotate all included contour labels. The function assumes that you have already made a contour plot with the option ContourLabels->All or ContourLabels->True. In the post-processing, you can then specify an arbitrarily fancy label style, which will be applied to the end result after the necessary rotations have been calculated. This works for ContourPlot and ListContourPlot. As an example, let's go back to the test plot in an earlier ContourPlot issue,
    im1 = ContourPlot[Im[(x + I y)^(1/2)], {x, -1, 1}, {y, -1, 1}, Contours -> 20, ContourLabels -> True].

    With the function as defined in the linked file contourPlotLabelsDescription.cdf, you can then invoke the following command to get the output shown on the right:

    rotateContourLabels[im1, Text[#3, {#1, #2}, Background -> White] &]
    

    The second argument is a function following the same guidelines as in the Mathematica help for ContourLabels.


  13. "Mathematica density and contour Plots with rasterized image representation"

    The page linked here contains some custom density and contour plotting functions that produce more efficient graphics than the built-in Mathematica functions.

  14. Mathematica graphics shows incorrect fonts in Adobe Illustrator

    Mathematica's interactive drawing tools are only a meager subset of what a program like Adobe Illustrator can do, and so the interoperability between these two programs remains an important issue. I'll assume Illustrator CS 3 and Mathematica Version 6 here. If you're interested in older versions, check the web archive.

    As you can tell from the archive link above, this page has been online for many years, and for historical reasons has been geared toward EPS as the main format. With Mathematica V6, EPS format has ceased to be the optimal vector format because it doesn't support transparency or gradients well. So we should aim for PDF export instead, in particular on a Mac where this is the native graphics format.

    The official solution:
    It turns out that we can completely fix all of Illustrator's font problems with PDF and EPS by executing the following cell in Mathematica (assuming Mac OS X):

    With[{temp = Directory[]}, 
    If[ $Failed =!= SetDirectory["~/Library/Application\ Support/Adobe/Fonts/"],
     If[! MemberQ[FileNames[], "Mathematica"], 
      CreateDirectory["Mathematica"];
      Run["/bin/ln -s " <> $InstallationDirectory <> 
        "/SystemFiles/Fonts/Type1 " <> $HomeDirectory <> 
        "/Library/Application\\ Support/Adobe/Fonts/Mathematica/"];
      SetDirectory["Mathematica"];
      Print[Style["Created symbolic link\n", Green], FileNames[], 
       Style["\nin folder\n", Green], Directory[]], 
      Print[Style[
        "Nothing to be done, folder already exists.\nTo re-install, first remove\n", 
        Red], Directory[] <> "/Mathematica"]];
     SetDirectory[temp]]
    ]
    

    This creates a new directory Mathematica in the folder ~/Library/Application\ Support/Adobe/Fonts/, and places a symbolic link to Mathematica's Type1 fonts in it. The symlink prescription was sent to me by Aron Yoffe who got it from at Wolfram Tech Support; I made it into a Mathematica script and added an extra level to the directory structure to avoid potential naming conflicts in Adobe's Fonts folder.

    If you prefer to install the fonts for multiple users, replace ~/Library by /Library and $HomeDirectory by $RootDirectory. This cell only has to be re-evaluated if the Adobe directory "/Library/Application Support/Adobe/Fonts/" is modified (i.e., after updating Adobe products); but there is no harm in repeating the instructions (the procedure does nothing if the needed directory is already in place).

    Once you press shift-return on the above cell, you'll even be able to copy Mathematica graphics to the clipboard and paste it directly into Illustrator without the dreaded font substitution dialog. This is something that the two alternative methods below don't allow.

    At this point it's worth pointing to a remark on another page that also applies here: when exporting annotated graphics from Illustrator, it's a good idea to create outlines from fonts (Type > Create Outlines) first.

    Avoid font problems by outlining text:
    In Mathematica version 8, it is possible to implement within Mathematica my original approach of outlining all text in a graphic before exporting it. One advantage of doing this within Mathematica rather than in an external program is that you can ship the exported file directly to other users without worrying whether they have the necessary fonts installed.

    To convert all text in a Graphics object gr to outlines (which are then filled curves and can be manipulated as such), type

    outlinedGraphics = First@ImportString[ExportString[gr,"PDF"],"PDF","TextMode" -> "Outlines"]
    	  

    The output can then be exported as PDF (or any other format) and will not contain any fonts that could trip up external programs. This approach works in MMA version 8. In version 7, the same approach produces buggy outlines in which separate glyphs are connected by extraneous lines.

    Obsolete solutions:
    Below are my older workarounds for the Mathematica font problem (in particular the first one still works fine). You may want to explore these alternatives if you're not able or willing to make the symbolic link as described above. The potential advantage of these methods is that they are more compatible with standard installations, if you want to exchange graphics files with other people.

    1. Export as EPS with advanced options
    2. Use a custom export function
    3. Save as LaTeX: Mathematica ≥ 6 exports graphics as EPS files, so this yields results similar to the above.
    Now for the details.
    1. Export as EPS with advanced options:

      Exporting from Mathematica to Illustrator works flawlessly if you make sure not to include special fonts in the exported file by setting the corresponding option as described below. To reiterate this point: you can use all the special fonts in your plot, but do not embed them in the exported EPS file so that Illustrator can instead look them up on its own among the Mathematica (and other) fonts it has available.

      • My starting point is that I can select and use all of the Mathematica Fonts from the Illustrator Type/Font Menu. Try this - if you can type greek letters after choosing Mathematica 1 Regular, then we're on the same page. If you do not have these fonts available in Illustrator, then go to /Applications/Mathematica.app/SystemFiles/Fonts/TrueType/ (e.g., by right-clicking on Mathematica and selecting "Show Package contents"), and open the file MathematicaFonts.dfont that's located there. That should launch Fontbook and ask you if you want to install these fonts. When that's done, you should have Mathematica fonts available in all applications (including Illustrator).
      • In Mathematica, generate any kind of graphics you wish, then export it as an EPS file using the following option (see the screenshot above):
        Export["test.eps",%, "EmbeddedFonts" -> False]). This syntax is for Version 6. In earlier versions, you would replace the option by ConversionOptions -> {"IncludeSpecialFonts" -> False}.
      • Now the EPS file without included fonts can be opened by Adobe Illustrator (either from the file menu or by dragging the file onto the Illustrator icon, or any way you like), and the Mathematica fonts should all be there, including Greek letters etc. This will work provided that all the fonts you are using in the Mathematica output are also available in Illustrator. Unfortunately, other file formats such as PDF don't support the "EmbeddedFonts" option.
      An example plot in Mathematica: The result in Illustrator (from an earlier version):

      This is a random item from my thermodynamics lecture, and the formula in the plot uses various different fonts, including FontFamily → "Helvetica Neue" for the Latin text. Bold Italic and simply Bold weights appear (by accident, but it's good as an example). The formula is actually rendered better in Illustrator.

    2. Use a custom export function

      There are other programs that can convert EPS to PDF or other formats, and one can go through such a third program before importing into Illustrator. In particular, you can use ghostscript to strip away all fonts that cause trouble when importing into Illustrator, replacing them by outlines that are visually equivalent but can't subsequently be edited as text. Define the following Mathematica function:

      epsExportNoFonts[exportName_, ob_] := Module[{},
          Export[exportName, ob, "EPS"];
          Run["gs -sDEVICE=epswrite -dNOCACHE -sOutputFile=nofont-" <> 
              exportName <> " -q -dbatch -dNOPAUSE "  <> exportName <> " -c quit"]]
      

      Then use this function instead of the built-in Export[] to write your Mathematica plot as an eps file: epsExportNoFonts["myfile.eps", graphics]. This function writes two EPS files: one called myfile.eps and a second one called nofont-myfile.eps. The file with nofont- prepended can be imported into Illustrator and should cause no font substitution problems. If Mathematica returns with a "0", there was no error. If the return code is something else, it may be because gs is not found. This could mean that you don't have ghostscript installed, or that you need to provide the path information, by replacing, in the above code, Run["gs... with Run["/sw/bin/gs (or whatever the path is that you get from which gs in the Terminal). On my system, this is not necessary because I have a file .MacOSX/environment.plist through which this path information is provided to applications such as Mathematica.


noeckel@uoregon.edu
Last modified: Tue Dec 25 10:48:37 PST 2012