5
$\begingroup$

Exporting very dense DensityPlot or Plot3D figures as vectors (pdf, eps) become very huge in size. for example, exporting this fig as pdf gives 85MB in size

plot2d = DensityPlot[Sin[x] Sin[y], {x, -4, 4}, {y, -3, 3}, 
  PlotPoints -> 200, 
  LabelStyle -> {FontFamily -> "LM Roman 12", Black, FontSize -> 16}, 
  FrameLabel -> (MaTeX[#, FontSize -> 17] &) /@ {"X", "Y"}, 
  ImageSize -> 200, ColorFunction -> Hue]   

enter image description here

Is it possible to Rasterize only the plot profile without frames or labels such that when exporting as pdf they are still in vector form (frame and labels)?

and can it be done also for Plot3D (As I know labels can not be in vector style in Plot3D but at least can we Rasterize plot profile and Axes with labels independently? so we can assign high Rasterize on labels and low for plot profile )

Plot3D[Sin[x] Sin[y], {x, -4, 4}, {y, -3, 3}, PlotPoints -> 200, 
 LabelStyle -> {FontFamily -> "LM Roman 12", Black, FontSize -> 16}, 
 AxesLabel -> (MaTeX[#, FontSize -> 17] &) /@ {"X", "Y"}, 
 ImageSize -> 200, ColorFunction -> Hue, BoxRatios -> {1, 1, 2}, 
 ViewPoint -> {1, -1.3, 0.5}, PlotTheme -> "Detailed"]     

enter image description here

update

For DensityPlot the problem was solved in this answer. Now, we are left with the case of Plot3D, is it possible to do a similar thing as in DensityPlot?

i.e. I want to export the output of Plot3D as a vector style (pdf/eps) where only axes are in vector style and plot profile is arbitrary RasterSize in the background.

$\endgroup$
9
  • 1
    $\begingroup$ Hi, can you please elaborate a bit on how is this question not a duplicate of Rasterized density plot with vector axes $\endgroup$
    – rhermans
    Jul 4, 2022 at 8:11
  • $\begingroup$ thanks, @rhermans, yes it perfectly does for DensityPlot but not for Plot3D. $\endgroup$ Jul 4, 2022 at 8:31
  • $\begingroup$ I still get poor resolution of labels even with RasterSize -> 4000.. it would be nice if one can Rasterize` profile and axes with labels independently and then combine all $\endgroup$ Jul 4, 2022 at 8:38
  • $\begingroup$ And how do you propose to combine the low-resolution plot with the high-resolution axis? I like your question, I think the main issue is to get the 2D projection of the axis and frame to overlap perfectly on the bitmap. Probably you could split the problems into parts. Given a Plot3D, ViewProjection and ViewPoint, extract the Line and Text that constitute Frame and Axis Lines, project them into a 2D Graphics with the rasterised Plot3D bitmap as the background. $\endgroup$
    – rhermans
    Jul 4, 2022 at 10:59
  • $\begingroup$ I was thinking about Legended to do that, I know not an elegent way to do it! $\endgroup$ Jul 4, 2022 at 11:11

2 Answers 2

4
$\begingroup$

For Plot3D, here is a try and hope experts can improve it,

first for the plot profile

Rast1 = Rasterize[
  Plot3D[Sin[x] Sin[y], {x, -4, 4}, {y, -3, 3}, PlotPoints -> 200, 
   LabelStyle -> None, AxesLabel -> None, Axes -> False, 
   Boxed -> False, ColorFunction -> Hue, BoxRatios -> {1, 1, 1.5}, 
   ImagePadding -> 30, ViewPoint -> {1, -1.3, 0.5}, PlotTheme -> None,
    Mesh -> None], RasterSize -> 800, Background -> None, 
  ImageSize -> 200]    

enter image description here

and then for axes and labels

Rast2 = Rasterize[
  Plot3D[Sin[x] Sin[y], {x, -4, 4}, {y, -3, 3}, PlotPoints -> 10, 
   LabelStyle -> {FontFamily -> "LM Roman 12", Black, FontSize -> 16},
    AxesLabel -> (MaTeX[#, FontSize -> 17] &) /@ {"X", "Y"}, 
   PlotStyle -> None, Mesh -> None, BoundaryStyle -> None, 
   BoxRatios -> {1, 1, 1.5}, ImagePadding -> 30, 
   ViewPoint -> {1, -1.3, 0.5}, PlotTheme -> "Detailed"], 
  RasterSize -> 4000, ImageSize -> 200]    

enter image description here

finally, combine both

Overlay[{Rast2, Rast1}]    

enter image description here

$\endgroup$
4
  • 1
    $\begingroup$ Can you explain the advantage of this over doing a high resolution raster of the original plot? I would haven wanted to see the axis as vector drawings. $\endgroup$
    – rhermans
    Jul 5, 2022 at 6:59
  • 1
    $\begingroup$ For publication or presentations, I want labels, frames, and axes to be in high resolution or a vector style with an acceptable size of the file as in DensityPlot as in the answer you posted in the comment. Since can not get axis as vector style with Plot3D (as I know), then my idea was to highly raster labels, frames, and axes and moderate for the profile (which has the large weight in the file size due to colors ). If I raster the whole 3D plot the size will be large again. $\endgroup$ Jul 5, 2022 at 7:10
  • $\begingroup$ Isn't the axis high-resolution picture already going to be large and heavy? You are not even restricting the number of colours of the axis raster. Probably you could show explicitly how the total file size turns out smaller at the end. $\endgroup$
    – rhermans
    Jul 5, 2022 at 7:47
  • $\begingroup$ No, you can assign the same RasterSize for the profile and axes and export it as pdf separately, the size of the profile will be much more larger. e.g. for RasterSize->4000 axes are 120KB and profile 1200KB, 10 times larger $\endgroup$ Jul 5, 2022 at 8:42
1
$\begingroup$

EDIT:

It appears the 3D case may be hopeless. After Mathematica 10.0 it appears 3D graphics is always rasterized when exporting to vector graphics and there's no good way around it. Full discussion here: Export Plot3D in Mathematica 10.1 is Rasterized by default. They provide some workarounds in there, but none of them seem to work for me. It appears having a rasterized element will trigger the entire PDF to rasterize even in the proposed workarounds (e.g. using right-click, print graphic or insetting into a 2D Graphics). I believe this is simply a Mathematica limitation, which is a shame. If you have a way to revert to Mathematica 10.0 or before, my approach or another approach given in that answer, might work for you.

Original Answer:

Here's a simple approach that gives vectorized axes and labels but a rasterized graph. Basically just make your graph without the axes or labels, Rasterize that, then add that image as an Inset in Graphics with the appropriate axes and labels. So for your 2d case (MaTeX was giving me problems so I omitted it):

graph = DensityPlot[Sin[x] Sin[y], {x, -4, 4}, {y, -3, 3}, 
   PlotPoints -> 200, ImageSize -> 200, ColorFunction -> Hue, 
   Frame -> False];
im = Rasterize[graph, Background -> None, ImageSize -> 400];
Graphics[Inset[im, {-4, -3}, {0, 0}, {8, 6}], 
 PlotRange -> {{-4, 4}, {-3, 3}}, Frame -> True, 
 LabelStyle -> {FontFamily -> "LM Roman 12", Black, FontSize -> 16}, 
 FrameLabel -> (Style[#, FontSize -> 17] &) /@ {"X", "Y"}, 
 AspectRatio -> 1, ImageSize -> 300]

2d

For the 3d case:

graph3D = 
  Plot3D[Sin[x] Sin[y], {x, -4, 4}, {y, -3, 3}, PlotPoints -> 200, 
   ImageSize -> 200, ColorFunction -> Hue, BoxRatios -> {1, 1, 2}, 
   ViewPoint -> {1, -1.3, 0.5}, Axes -> False, Boxed -> False, 
   Background -> Opacity[0]];
im3d = Rasterize[graph3D, Background -> None, ImageSize -> 200];
Graphics3D[Inset[im3d], PlotRange -> {{-4, 4}, {-3, 3}, {-1, 1}}, 
 AxesEdge -> {{-1, -1}, {1, -1}, Automatic}, 
 LabelStyle -> {FontFamily -> "LM Roman 12", Black, FontSize -> 16}, 
 Axes -> True, 
 AxesLabel -> (Style[#, FontSize -> 17] &) /@ {"X", "Y"}, 
 ImageSize -> 250, BoxRatios -> {1, 1, 2}, 
 ViewPoint -> {1, -1.3, 0.5}, 
 FaceGrids -> {{0, 1, 0}, {-1, 0, 0}, {0, 0, 1}, {0, 0, -1}}, 
 Boxed -> False]

3da

If you want to keep all the options from PlotTheme -> "Detailed" you can make a "graph" with a trivial, transparent graph so you're just left with the axes, grids, and labels then Show that together with the Rasterized image. I.e.

axes3D = Plot3D[0, {x, -4, 4}, {y, -3, 3}, PlotPoints -> 2, 
   LabelStyle -> {FontFamily -> "LM Roman 12", Black, FontSize -> 16},
    AxesLabel -> (Style[#, FontSize -> 17] &) /@ {"X", "Y"}, 
   ImageSize -> 200, ColorFunction -> (Opacity[0] &), Mesh -> None, 
   BoundaryStyle -> None, BoxRatios -> {1, 1, 2}, 
   ViewPoint -> {1, -1.3, 0.5}, PlotTheme -> "Detailed"];
Show[axes3D, Graphics3D[Inset[im3d]], ImageSize -> 250] 

3db

There's a lot of playing around with these approaches you can do to get the styling you like. Inset can be a bit finicky when you resize things, but it shouldn't be hard to set the options in Inset and Graphics such that it looks like you want. Plus this has the advantage that you can explicitly control what gets rasterized and what stays vectorized.

Here's a super zoomed in version of the final PDF of the 2d plot. As you can see, the axes are indeed vectorized.

zoom2d

$\endgroup$
6
  • $\begingroup$ actually, your approach is similar to mine in the above answer. However, exporting as pdf my approach gives higher resolution with a smaller size than yours and of course with MaTex working fine. $\endgroup$ Jul 7, 2022 at 6:57
  • $\begingroup$ and thank you for sharing your thoughts:-) $\endgroup$ Jul 7, 2022 at 7:08
  • $\begingroup$ @valarmorghulis you can choose the options for resolution when you rasterize and/or export. However, my solution gives you vector graphics for your axes as you requested. I can confirm this on my Mac, I added it to the answer. If you don't see vectorized axes, what system and version of Mathematica are you using? Exporting to vector graphics is notoriously buggy in Mathematica and different versions and OS's may produce different results. $\endgroup$
    – bRost03
    Jul 7, 2022 at 13:22
  • $\begingroup$ it gives a vector for DensityPlot (read my update of the question) but axes can't be in a vector when exporting Plot3D. Does the picture you posted for Plot3D or DensityPlot? my problem now is for Plot3D only. $\endgroup$ Jul 7, 2022 at 13:37
  • 1
    $\begingroup$ @valarmorghulis I see, I can confirm my solution does rasterize the axes in 3D. This appears to be a known issue in Mathematica. I'm updating my answer to provide all the details about it. $\endgroup$
    – bRost03
    Jul 7, 2022 at 13:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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