Mathematica: Rasters in 3D graphics
Asked Answered
I

6

18

There are times when exporting to a pdf image is simply troublesome. If the data you are plotting contains many points then your figure will be big in size and the pdf viewer of your choice will spend most of its time rendering this high quality image. We can thus export this image as a jpeg, png or tiff. The picture will be fine from a certain view but when you zoom in it will look all distorted. This is fine to some extent for the figure we are plotting but if your image contains text then this text will look pixelated.

In order to try to get the best of both worlds we can separate this figure into two parts: Axes with labels and the 3D picture. The axes can thus be exported as pdf or eps and the 3D figure as a raster. I wish I knew how later combine the two in Mathematica, so for the moment we can use a vector graphics editor such as Inkscape or Illustrator to combine the two.

I managed to achieve this for a plot I made in a publication but this prompt me to create routines in Mathematica in order to automatize this process. Here is what I have so far:

SetDirectory[NotebookDirectory[]];
SetOptions[$FrontEnd, PrintingStyleEnvironment -> "Working"];

I like to start my notebook by setting the working directory to the notebook directory. Since I want my images to be of the size I specify I set the printing style environment to working, check this for more info.

in = 72;
G3D = Graphics3D[
  AlignmentPoint -> Center,
  AspectRatio -> 0.925,
  Axes -> {True, True, True},
  AxesEdge -> {{-1, -1}, {1, -1}, {-1, -1}},
  AxesStyle -> Directive[10, Black],
  BaseStyle -> {FontFamily -> "Arial", FontSize -> 12},
  Boxed -> False,
  BoxRatios -> {3, 3, 1},
  LabelStyle -> Directive[Black],
  ImagePadding -> All,
  ImageSize -> 5 in,
  PlotRange -> All,
  PlotRangePadding -> None,
  TicksStyle -> Directive[10],
  ViewPoint -> {2, -2, 2},
  ViewVertical -> {0, 0, 1}
 ]

Here we set the view of the plot we want to make. Now lets create our plot.

g = Show[
  Plot3D[Sin[x y], {x, 0, Pi}, {y, 0, Pi}, 
   Mesh -> None,
   AxesLabel -> {"x", "y", "z"}
   ], 
  Options[G3D]
 ]

enter image description here

Now we need to find a way of separating. Lets start by drawing the axes.

axes = Graphics3D[{}, AbsoluteOptions[g]]

enter image description here

fig = Show[g, 
  AxesStyle -> Directive[Opacity[0]],
  FaceGrids -> {{-1, 0, 0}, {0, 1, 0}}
 ]

enter image description here

I included the facegrids so that we can match the figure with the axis in the post editing process. Now we export both images.

Export["Axes.pdf", axes];
Export["Fig.pdf", Rasterize[fig, ImageResolution -> 300]];

You will obtain two pdf files which you can edit in and put together into a pdf or eps. I wish it was that simple but it isn't. If you actually did this you will obtain this:

enter image description here

The two figures are different sizes. I know axes.pdf is correct because when I open it in Inkspace the figure size is 5 inches as I had previously specified.

I mentioned before that I managed to get this with one of my plots. I will clean the file and change the plots to make it more accessible for anyone who wants to see that this is in fact true. In any case, does anyone know why I can't get the two pdf files to be the same size? Also, keep in mind that we want to obtain a pretty plot for the Rasterized figure. Thank you for your time.

PS. As a bonus, can we avoid the post editing and simply combine the two figures in mathematica? The rasterized version and the vector graphics version that is.


EDIT:

Thanks to rcollyer for his comment. I'm posting the results of his comment.

One thing to mention is that when we export the axes we need to set Background to None so that we can have a transparent picture.

Export["Axes.pdf", axes, Background -> None];
Export["Fig.pdf", Rasterize[fig, ImageResolution -> 300]];
a = Import["Axes.pdf"];
b = Import["Fig.pdf"];
Show[b, a]

enter image description here

And then, exporting the figure gives the desired effect

Export["FinalFig.pdf", Show[b, a]]

enter image description here

The axes preserve the nice components of vector graphics while the figure is now a Rasterized version of the what we plotted. But the main question still remains. How do you make the two figures match?

UPDATE:

My question has been answered by Alexey Popkov. I would like to thank him for taking the time to look into my problem. The following code is an example for those of you want to use the technique I previously mentioned. Please see Alexey Popkov's answer for useful comments in his code. He managed to make it work in Mathematica 7 and it works even better in Mathematica 8. Here is the result:

SetDirectory[NotebookDirectory[]];
SetOptions[$FrontEnd, PrintingStyleEnvironment -> "Working"];
$HistoryLength = 0;
in = 72;
G3D = Graphics3D[
 AlignmentPoint -> Center, AspectRatio -> 0.925, Axes -> {True, True, True},
 AxesEdge -> {{-1, -1}, {1, -1}, {-1, -1}}, AxesStyle -> Directive[10, Black],
 BaseStyle -> {FontFamily -> "Arial", FontSize -> 12}, Boxed -> False, 
 BoxRatios -> {3, 3, 1}, LabelStyle -> Directive[Black], ImagePadding -> 40,
 ImageSize -> 5 in, PlotRange -> All, PlotRangePadding -> 0,
 TicksStyle -> Directive[10], ViewPoint -> {2, -2, 2}, ViewVertical -> {0, 0, 1}
];
axesLabels = Graphics3D[{
 Text[Style["x axis (units)", Black, 12], Scaled[{.5, -.1, 0}], {0, 0}, {1, -.9}],
 Text[Style["y axis (units)", Black, 12], Scaled[{1.1, .5, 0}], {0, 0}, {1, .9}],
 Text[Style["z axis (units)", Black, 12], Scaled[{0, -.15, .7}], {0, 0}, {-.1, 1.5}]
}];
fig = Show[
  Plot3D[Sin[x y], {x, 0, Pi}, {y, 0, Pi}, Mesh -> None],
  ImagePadding -> {{40, 0}, {15, 0}}, Options[G3D]
];
axes = Show[
  Graphics3D[{}, FaceGrids -> {{-1, 0, 0}, {0, 1, 0}}, 
    AbsoluteOptions[fig]], axesLabels, 
    Epilog -> Text[Style["Panel A", Bold, Black, 12], ImageScaled[{0.075, 0.975}]]
];
fig = Show[fig, AxesStyle -> Directive[Opacity[0]]];
Row[{fig, axes}]

At this point you should see this:

enter image description here

The magnification takes care of the resolution of your image. You should try different values to see how this changes your picture.

fig = Magnify[fig, 5];
fig = Rasterize[fig, Background -> None];

Combine the graphics

axes = First@ImportString[ExportString[axes, "PDF"], "PDF"];
result = Show[axes, Epilog -> Inset[fig, {0, 0}, {0, 0}, ImageDimensions[axes]]];

Export them

Export["Result.pdf", result];
Export["Result.eps", result];

The only difference I found between M7 and M8 using the above code is that M7 does not export the eps file correctly. Other than that everything is working fine now. :)

enter image description here

The first column shows the output obtained from M7. Top is the eps version with file size of 614 kb, bottom is the pdf version with file size of 455 kb. The second column shows the output obtained from M8. Top is the eps version with file size of 643 kb, bottom is the pdf version with file size of 463 kb.

I hope you find this useful. Please check Alexey's answer to see the comments in his code, they will help you avoid pitfalls with Mathematica.

Isonomy answered 10/6, 2011 at 3:26 Comment(2)
have you tried Importing them both and using Show?Albertype
@Albertype Genious! I didn't think about that possibility. This solves the bonus question. No need to use Inkscape anymore to do this. But the main question still remains. How do you get them both to match up? See my edit in the post.Isonomy
I
7

The complete solution for Mathematica 7.0.1: fixing bugs

The code with comments:

(*controls the resolution of rasterized graphics*)
magnification = 5;

SetOptions[$FrontEnd, PrintingStyleEnvironment -> "Working"]
(*Turn off history for saving memory*)
$HistoryLength = 0;
(*Epilog will give us the bounding box of the graphics*)
g1 = Plot3D[Sin[x y], {x, 0, Pi}, {y, 0, Pi}, 
   AlignmentPoint -> Center, AspectRatio -> 0.925, 
   Axes -> {True, True, True}, 
   AxesEdge -> {{-1, -1}, {1, -1}, {-1, -1}}, 
   BaseStyle -> {FontFamily -> "Arial", FontSize -> 12}, 
   Boxed -> False, BoxRatios -> {3, 3, 1}, 
   LabelStyle -> Directive[Black], ImagePadding -> All, 
   ImageSize -> 5*72, PlotRange -> All, PlotRangePadding -> None, 
   TicksStyle -> Directive[10], ViewPoint -> {2, -2, 2}, 
   ViewVertical -> {0, 0, 1}, AxesStyle -> Directive[Opacity[0]], 
   FaceGrids -> {{-1, 0, 0}, {0, 1, 0}}, Mesh -> None, 
   ImagePadding -> 40, 
   Epilog -> {Red, AbsoluteThickness[1], 
     Line[{ImageScaled[{0, 0}], ImageScaled[{0, 1}], 
       ImageScaled[{1, 1}], ImageScaled[{1, 0}], 
       ImageScaled[{0, 0}]}]}];
(*The options list should NOT contain ImagePadding->Full.Even it is \
before ImagePadding->40 it is not replaced by the latter-another bug!*)
axes = Graphics3D[{Opacity[0], 
    Point[PlotRange /. AbsoluteOptions[g1] // Transpose]}, 
   AlignmentPoint -> Center, AspectRatio -> 0.925, 
   Axes -> {True, True, True}, 
   AxesEdge -> {{-1, -1}, {1, -1}, {-1, -1}}, 
   AxesStyle -> Directive[10, Black], 
   BaseStyle -> {FontFamily -> "Arial", FontSize -> 12}, 
   Boxed -> False, BoxRatios -> {3, 3, 1}, 
   LabelStyle -> Directive[Black], ImageSize -> 5*72, 
   PlotRange -> All, PlotRangePadding -> None, 
   TicksStyle -> Directive[10], ViewPoint -> {2, -2, 2}, 
   ViewVertical -> {0, 0, 1}, ImagePadding -> 40, 
   Epilog -> {Red, AbsoluteThickness[1], 
     Line[{ImageScaled[{0, 0}], ImageScaled[{0, 1}], 
       ImageScaled[{1, 1}], ImageScaled[{1, 0}], 
       ImageScaled[{0, 0}]}]}];
(*fixing bug with ImagePadding loosed when specifyed as option in \
Plot3D*)
g1 = AppendTo[g1, ImagePadding -> 40];
(*Increasing ImageSize without damage.Explicit setting for \
ImagePadding is important (due to a bug in behavior of \
ImagePadding->Full)!*)
g1 = Magnify[g1, magnification];
g2 = Rasterize[g1, Background -> None];
(*Fixing bug with non-working option Background->None when graphics \
is Magnifyed*)
g2 = g2 /. {255, 255, 255, 255} -> {0, 0, 0, 0};
(*Fixing bug with icorrect exporting of Ticks in PDF when Graphics3D \
and 2D Raster are combined*)
axes = First@ImportString[ExportString[axes, "PDF"], "PDF"];
(*Getting explicid ImageSize of graphics imported form PDF*)
imageSize = 
 Last@Transpose[{First@#, Last@#} & /@ 
    Sort /@ Transpose@
      First@Cases[axes, 
        Style[{Line[x_]}, ___, RGBColor[1.`, 0.`, 0.`, 1.`], ___] :> 
         x, Infinity]]
(*combining Graphics3D and Graphics*)
result = Show[axes, Epilog -> Inset[g2, {0, 0}, {0, 0}, imageSize]]
Export["C:\\result.pdf", result]

Here is what I see in the Notebook:

screenshot

And here is what I get in the PDF:

screenshot

Irrationality answered 10/6, 2011 at 14:0 Comment(11)
In Win7/M8.01 I don't see the axes and tick labels when running the above code.Margaretamargarete
@Sjoerd @belisarius I think we can conclude that some graphics functionality is broken in v.8... ;)Irrationality
@Alexey, thank you for trying a different approach. I'll be checking on this once I install M8.Isonomy
@Alexey, I think the problem is that M8 does not export png or rasterized images with transparent background. For this reason, when you attempt to place g2 on top then you see no axes and tick labels (background of rasterized image is white).Isonomy
@Isonomy Please see edited version of the answer. It seems that I got it (at least for Mathematica 7.0.1)!Irrationality
@Alexey, I ran that your code in M7 but I get this i.imgur.com/70AEo.png. You mentioned that some graphics functionality is broken in v.8, For instance, lets just try: Export["test.png", Plot3D[Sin[x y], {x, 0, Pi}, {y, 0, Pi}], Background -> None] in M7 and M8. What's the difference? M7 has transparent background, M8 has white background. Sigh*. I wonder if they changed something in M8 for Plot3D that makes the background white. Notice that if you try Export["test.png", Graphics3D[{Sphere[{0, 0, 0}, 1]}], Background -> None] in M8 you get a transparent background.Isonomy
@Isonomy I use v.7.0.1 for Windows. Which version you use exactly? Red coloring of your image indicates error messages. What messages you get after pressing "+" button in the right upper corner of the output cell?Irrationality
@Isonomy I apologize. I have made a mistake on the final stage of preparation of the code for publication. Please see updated answer with corrected and checked version.Irrationality
@Alexey, Thank so you so much for this fix in M7. I really like it better than what I obtain in M8. I will try to see if this works in M8 after I clean your code. Would you mind if I write an update with a cleaned up version of your code? By the way, ImageDimensions seems to work well. I replaced that to obtain the size of the image. I'll write once I check that everything works in M7 and M8. Thank you again. :)Isonomy
@Alexey, post has been updated with a modified version of your answer. Could you check to see if this also works on your machine? I'm curious to see the extent of Mathematica portability.Isonomy
@Isonomy With your code I get PDF file that looks as you have showed in the UPDATED section of your question. Thank you for clearing up the code.Irrationality
A
3

Just checking (Mma8):

SetOptions[$FrontEnd, PrintingStyleEnvironment -> "Working"];
in = 72;
G3D = Graphics3D[AlignmentPoint -> Center, AspectRatio -> 0.925, 
   Axes -> {True, True, True}, 
   AxesEdge -> {{-1, -1}, {1, -1}, {-1, -1}}, 
   AxesStyle -> Directive[10, Black], 
   BaseStyle -> {FontFamily -> "Arial", FontSize -> 12}, 
   Boxed -> False, BoxRatios -> {3, 3, 1}, 
   LabelStyle -> Directive[Black], ImagePadding -> All, 
   ImageSize -> 5 in, PlotRange -> All, PlotRangePadding -> None, 
   TicksStyle -> Directive[10], ViewPoint -> {2, -2, 2}, 
   ViewVertical -> {0, 0, 1}];
g = Show[Plot3D[Sin[x y], {x, 0, Pi}, {y, 0, Pi}, Mesh -> None, 
    AxesLabel -> {"x", "y", "z"}], Options[G3D]];
axes = Graphics3D[{}, AbsoluteOptions[g]];
fig = Show[g, AxesStyle -> Directive[Opacity[0]], 
   FaceGrids -> {{-1, 0, 0}, {0, 1, 0}}];
Export["c:\\Axes.pdf", axes, Background -> None];
Export["c:\\Fig.pdf", Rasterize[fig, ImageResolution -> 300]];
a = Import["c:\\Axes.pdf"];
b = Import["c:\\Fig.pdf"];
Export["c:\\FinalFig.pdf", Show[b, a]]

enter image description here

Airtight answered 10/6, 2011 at 12:25 Comment(4)
With Mathematica 7.0.1 with this code I get the same image as showed in the question.Irrationality
@Alexey I think we can conclude that the Export to PDF feature was fixed in v8 ...Airtight
So... all this time I've had problems because of Mathematica 7? Dear lord! I've also been having lots of problem using Graphics. Maybe switching to M8 will solve the problems. Anyway, thank you for checking. Now I'm wondering, which answer should I accept? Mathematica is simply broken.Isonomy
@belisarius I hope that once I change to Mma 8 all the problems I had previously go away. Thank you. :)Isonomy
I
2

In Mathematica 8 the problem may be solved even simpler using new Overlay function.

Here is the code from the UPDATE section of the question:

SetOptions[$FrontEnd, PrintingStyleEnvironment -> "Working"];
$HistoryLength = 0;
in = 72;
G3D = Graphics3D[AlignmentPoint -> Center, AspectRatio -> 0.925, 
   Axes -> {True, True, True}, 
   AxesEdge -> {{-1, -1}, {1, -1}, {-1, -1}}, 
   AxesStyle -> Directive[10, Black], 
   BaseStyle -> {FontFamily -> "Arial", FontSize -> 12}, 
   Boxed -> False, BoxRatios -> {3, 3, 1}, 
   LabelStyle -> Directive[Black], ImagePadding -> 40, 
   ImageSize -> 5 in, PlotRange -> All, PlotRangePadding -> 0, 
   TicksStyle -> Directive[10], ViewPoint -> {2, -2, 2}, 
   ViewVertical -> {0, 0, 1}];
axesLabels = 
  Graphics3D[{Text[Style["x axis (units)", Black, 12], 
     Scaled[{.5, -.1, 0}], {0, 0}, {1, -.9}], 
    Text[Style["y axis (units)", Black, 12], 
     Scaled[{1.1, .5, 0}], {0, 0}, {1, .9}], 
    Text[Style["z axis (units)", Black, 12], 
     Scaled[{0, -.15, .7}], {0, 0}, {-.1, 1.5}]}];
fig = Show[Plot3D[Sin[x y], {x, 0, Pi}, {y, 0, Pi}, Mesh -> None], 
   ImagePadding -> {{40, 0}, {15, 0}}, Options[G3D]];
axes = Show[
   Graphics3D[{}, FaceGrids -> {{-1, 0, 0}, {0, 1, 0}}, 
    AbsoluteOptions[fig]], axesLabels, 
   Epilog -> 
    Text[Style["Panel A", Bold, Black, 12], 
     ImageScaled[{0.075, 0.975}]]];
fig = Show[fig, AxesStyle -> Directive[Opacity[0]]];

And here is the solution:

gr = Overlay[{axes, 
   Rasterize[fig, Background -> None, ImageResolution -> 300]}]
Export["Result.pdf", gr]

In this case we need not to convert fonts to outlines.

UPDATE

As jmlopez pointed out in the comments to this answer, the option Background -> None does not work properly under Mac OS X in Mathematica 8.0.1. One workaround is to replace white non-transparent points by transparent:

gr = Overlay[{axes, 
   Rasterize[fig, Background -> None, 
     ImageResolution -> 300] /. {255, 255, 255, 255} -> {0, 0, 0, 0}}]
Export["Result.pdf", gr]
Irrationality answered 9/10, 2011 at 11:28 Comment(8)
Something is not working when I try it. I only get fig with a white background. Is as if Rasterized ignored the background option.Isonomy
@Isonomy Are you using Mathematica 8.0.1? I use Windows version. The output looks good both inside of the Notebook and in PDF viewer. But exporting to EPS in this case works not so well.Irrationality
I'm using MMA 8.0.1 in Mac OS X. I think there is a problem with Graphics3D or Rasterize. Take for instance: Overlay[{fig, Plot[x, {x, 1, 2}]}] with fig as defined in your post. Then overlay works. But if you try: Overlay[{fig, Graphics3D[]}] then it doesn't show fig. It might be a bug on the mac version.Isonomy
@Isonomy Try Overlay[{fig, Rasterize[Graphics3D[], Background -> None]}]. This works on my system. With the original code from my answer you could try also Rasterize[fig,Background->None,ImageResolution->300]/.{Repeated[255,{4}]}->{0,0,0,0}.Irrationality
That works. Unfortunately that seems to take longer to compute than in the previous method. Well, hopefully by the next release it will be fixed on the mac.Isonomy
@Isonomy My usage of Repeated was a little overkill. Simple replacement with obvious rule {255, 255, 255, 255} -> {0, 0, 0, 0} gives double speedup over Repeated.Irrationality
I don't think Repeated was the problem with speed. It still takes a while to generate the final pdf file. I just tried it again and noticed something about the size of the file. If we do it as I originally posted in the update, the pdf file size is about 500 kb. Using the overlay with ImageResolution set to 300 gives us a file 1.9 mb. I'm kind of surprised that ImageResolution is working, (that's why you suggested to magnify it and rasterize it) maybe this is why the file size increased. Are these the same numbers you are getting in your machine?Isonomy
let us continue this discussion in chatIsonomy
I
2

Here I present another version of the original solution which uses the second argument of Raster instead of Inset. I think that this way is a little more straightforward.

Here is the code from the UPDATE section of the question (modified a bit):

SetOptions[$FrontEnd, PrintingStyleEnvironment -> "Working"];
$HistoryLength = 0;
in = 72;
G3D = Graphics3D[AlignmentPoint -> Center, AspectRatio -> 0.925, 
   Axes -> {True, True, True}, 
   AxesEdge -> {{-1, -1}, {1, -1}, {-1, -1}}, 
   AxesStyle -> Directive[10, Black], 
   BaseStyle -> {FontFamily -> "Arial", FontSize -> 12}, 
   Boxed -> False, BoxRatios -> {3, 3, 1}, 
   LabelStyle -> Directive[Black], ImagePadding -> 40, 
   ImageSize -> 5 in, PlotRange -> All, PlotRangePadding -> 0, 
   TicksStyle -> Directive[10], ViewPoint -> {2, -2, 2}, 
   ViewVertical -> {0, 0, 1}];
axesLabels = 
  Graphics3D[{Text[Style["x axis (units)", Black, 12], 
     Scaled[{.5, -.1, 0}], {0, 0}, {1, -.9}], 
    Text[Style["y axis (units)", Black, 12], 
     Scaled[{1.1, .5, 0}], {0, 0}, {1, .9}], 
    Text[Style["z axis (units)", Black, 12], 
     Scaled[{0, -.15, .7}], {0, 0}, {-.1, 1.5}]}];
fig = Show[Plot3D[Sin[x y], {x, 0, Pi}, {y, 0, Pi}, Mesh -> None], 
   ImagePadding -> {{40, 0}, {15, 0}}, Options[G3D]];
axes = Show[
   Graphics3D[{}, FaceGrids -> {{-1, 0, 0}, {0, 1, 0}}, 
    AbsoluteOptions[fig]], axesLabels, 
   Prolog -> 
    Text[Style["Panel A", Bold, Black, 12], 
     ImageScaled[{0.075, 0.975}]]];
fig = Show[fig, AxesStyle -> Directive[Opacity[0]]];
fig = Magnify[fig, 5];
fig = Rasterize[fig, Background -> None];
axes2D = First@ImportString[ExportString[axes, "PDF"], "PDF"];

The rest of the answer is the new solution.

At first, we set the second argument of Raster so that it will fill the complete PlotRange of axes2D. The general way to do this is:

fig = fig /. 
   Raster[data_, rectangle_, opts___] :> 
    Raster[data, {Scaled[{0, 0}], Scaled[{1, 1}]}, opts];

Another way is to make direct assignment to the corresponding Part of the original expression:

fig[[1, 2]] = {Scaled[{0, 0}], Scaled[{1, 1}]}

Note that this last code is based on the knowledge of internal structure of the expression generated by Rasterize which is potentially version-dependent.

Now we combine two graphical objects in a very straightforward way:

result = Show[axes2D, fig]

And export the result:

Export["C:/Result.pdf", result];
Export["C:/Result.eps", result];

Both .eps and .pdf are exported perfectly with Mathematica 8.0.4 under Windows XP 32 bit and look identical to the files exported with the original code:

result = Show[axes2D, 
  Epilog -> Inset[fig, Center, Center, ImageScaled[{1, 1}]]]
Export["C:/Result.pdf", result];
Export["C:/Result.eps", result];

Note that we need not necessarily to convert axes to outlines at least when exporting to PDF. The code

result = Show[axes, 
  Epilog -> Inset[fig, Center, Center, ImageScaled[{1, 1}]]]
Export["C:/Result.pdf", result];

and the code

fig[[1, 2]] = {ImageScaled[{0, 0}], ImageScaled[{1, 1}]};
result = Show[axes, Epilog -> First@fig]
Export["C:/Result.pdf", result];

produce PDF files looking identical to both previous versions.

Irrationality answered 8/11, 2011 at 10:58 Comment(0)
M
0

This looks like much ado about nothing. As I read it, the problem you want to solve is the following:

  • You want to export in a vector format, so that when printed the optimal resolution is used for fonts, lines and graphics
  • In your edit program you don't want be bothered by the slowness of rendering a complex vector drawing

These requirements can be met by exporting as .eps and using an embedded rasterized preview image.

Export["file.eps","PreviewFormat"->"TIFF"]

This will work in many applications. Unfortunately, MS Word's eps filter has been changing wildly over the last four versions or so, and whereas it once worked for me in one of the older functions it doesn't anymore in W2010. I've heard rumors that it might work in the mac version, but I can't check right now.

Margaretamargarete answered 10/6, 2011 at 14:30 Comment(4)
I think that the idea of the question is really interesting from the practical point of view. I thought of this earlier but I found it too difficult or impossible. We have too many problems with PDF export of Graphics3D (and even Graphics!) in Mathematica. Any workarounds are interesting and possibly helpful for others.Irrationality
@Isonomy I added the requested line of code for those unable or unwilling to find it in the doc center.Margaretamargarete
Unless I'm not using it correctly all I obtain is a file with size bigger than without using that option. Try this in M7.0.1 Export["FIG.eps", Graphics3D[Sphere[{0, 0, 0}, 1], Axes -> True], Background -> None, "PreviewFormat" -> "TIFF"] with and without the option. The idea like you said: "optimal resolution is used for fonts, lines and graphics". More specifically, fonts and simple lines in vector graphics, complex figures such as surfaces in rasterized versions. This should reduce file size and give you some good looking plots.Isonomy
@Isonomy A bigger file size is to be expected. An eps with embedded preview contains both the vector description and a preview of how these should look like when rendered. The idea is that your text editor should show the preview as a quick placeholder and should send the postscript stuff to the printer.Margaretamargarete
P
0

Mathematica 9.0.1.0 / 64-bit Linux: In general, it seems to be very tricky to place the vectorized axes at the correct position. In most applications it will be sufficient to simply rasterize everything with a high resolution:

fig = Plot3D[Sin[x y], {x, 0, 3}, {y, 0, 3}, Mesh -> None];

Export["export.eps", fig, "AllowRasterization" -> True, 
  ImageResolution -> 600];

The code exports the graphic to an EPS-file using a high quality rasterization of both the 3D content and the axis. Finally, you can convert the EPS-file to a PDF using for example the Linux command epspdf:

epspdf export.eps

This is probably sufficient for most of the users and it saves you a lot of time. However, if you really want to export the text as vector graphic, you might want to try the following function:

ExportAsSemiRaster[filename_, dpi_, fig_, plotrange_, 
   plotrangepadding_] := (
   range = 
    Show[fig, PlotRange -> plotrange, 
     PlotRangePadding -> plotrangepadding];
   axes = Show[Graphics3D[{}, AbsoluteOptions[range]]];
   noaxes = Show[range, AxesStyle -> Transparent];
   raster = 
    Rasterize[noaxes, Background -> None, ImageResolution -> dpi];
   result = 
    Show[raster, 
     Epilog -> Inset[axes, Center, Center, ImageDimensions[raster]]];
   Export[filename, result];
   );

You need to explicitly specify the PlotRange and the PlotRangePadding. Example:

fig = Graphics3D[{Opacity[0.9], Orange, 
    Polygon[{{0, 0, 0}, {4, 0, 4}, {4, 5, 7}, {0, 5, 5}}], 
    Opacity[0.05], Gray, CuboidBox[{0, 0, 0}, {4, 5, 7}]}, 
   Axes -> True, AxesStyle -> Darker[Orange], 
   AxesLabel -> {"x1", "x2", "x3"}, Boxed -> False, 
   ViewPoint -> {-8.5, -8, 6}];
ExportAsSemiRaster["export.pdf", 600, 
  fig, {{0, 4}, {0, 5}, {0, 7}}, {.0, .0, .0}];
Print[Import["export.pdf"]];
Prodrome answered 3/7, 2014 at 12:48 Comment(1)
I cannot check in MMa 9.01 right now but in MMa 8.0.4 your ExportAsSemiRaster function gives incorrect positioning of the axes. Also possibly you can find this useful (have not checked myself).Irrationality

© 2022 - 2024 — McMap. All rights reserved.