3
$\begingroup$

For example, I have a grid of plot stored in variable plots

   plots = Grid[{{Grid[
     Table[ListDensityPlot[{{1, 1, 1, 1}, {1, 2, 1, 2}, {1, 1, 3, 
         1}, {1, 2, 1, 4}}, Mesh -> All], {i, 2}, {j, 2}]], 
    Plot[x, {x, 0, 1}, PlotLabel -> "yyy"]}}]

and it is looked like in frontend

enter image description here

If I export it to jpg like

Export["test.jpg", plots]

The image looking is exactly the same as it shows in mathematica frontend. However, the resolution is low.

But I want high resolution, however,

Export["test.jpg", plots, ImageResolution -> 600]

gives

enter image description here

So my questions is

  • why ImageResolution affect the looking?
  • how to export plots as high resolution jpg, while keep the same visual looking in frontend?

update

I found even Jens' trick will fail for some complicated grid of graphics. For example, try below

plot = Plot[x, {x, 0, 1}, Frame -> True, AspectRatio -> 1];
plots = Grid[{{Grid[Table[plot, {i, 2}, {j, 2}]], 
     Plot[x, {x, 0, 1}, PlotLabel -> "yyy"]}}];
newplots = 
 Grid[{{Show[plot, ImageSize -> 200, AspectRatio -> 2], plots}}]

and Jens' method

h = First@ImportString[ExportString[newplots, "PDF"]];
Rasterize[h, ImageResolution -> 300]

You will notice significant difference.

After tested many solutions, I found the most stable way to "export" to file and keep exactly the same looking as in front end and keep high resolution is using "save sections as" PDF for the whole cell. You can confirm that this is not equivalent to Export["..pdf",...] using newplots as test. Though an undesirable thing is that the output file will have cell tag.

enter image description here

However, this operation can not batch processing, if we want to save a bunches of files.

So I am wondering, Mathematica do have a mechanism which can keep all the same looking when saving cell, no matter how complicated the graphics is ( grid, even grid of grid). There must be a underlining command that can mimic "save section as" PDF. Does anyone know the command to mimic "save section as" PDF, so we can do batch processing?

$\endgroup$
5
  • 2
    $\begingroup$ Try setting also ImageSize: img = Import@Export["test.png", plots, ImageSize -> 1200, ImageResolution -> 200 ]; $\endgroup$ Commented Apr 29, 2018 at 17:22
  • $\begingroup$ Hi, @HenrikSchumacher, thank you so much. But I don't understand, it seems that even setting ImageSize, if ImageResolution is 600, the image is still wrong. Then why 200? It seems rather arbitary $\endgroup$
    – matheorem
    Commented Apr 29, 2018 at 23:59
  • $\begingroup$ I have to admit that I also do not understand the logic behind it. =( Btw. I would store such plots rather in png. jpg format has the tendency to introduce these ugly block artifacts around lines and text. If you are going to print that, you while often have quite visible gray shadows around each line. png is lossless, so that would not happen. And if the images contain only few colors, png has still a decent file size. $\endgroup$ Commented Apr 30, 2018 at 7:56
  • $\begingroup$ @HenrikSchumacher Thank you so much for your advice. But for smooth color variation like densityplot, it seems that jpg would be smaller for same visual quality : ) $\endgroup$
    – matheorem
    Commented Apr 30, 2018 at 8:03
  • $\begingroup$ That's right. It's about smoothness of the original image. $\endgroup$ Commented Apr 30, 2018 at 8:04

2 Answers 2

1
$\begingroup$

There are (at least) two problems with Mathematica that come into play here. A solution that addresses them both is to wrap all your plots with toPDF as follows, before exporting them:

toPDF[plot_] := 
 First@ImportString[
   ExportString[
    Show[plot, 
     Prolog -> {Opacity[0], Texture[{{{0, 0, 0, 0}}}], 
       VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}}, 
       Polygon[{{0, 0}, {.1, 0}, {.1, .1}}]}], "PDF"]]


plots = Grid[{{Grid[
      Table[
        toPDF@
        ListDensityPlot[{{1, 1, 1, 1}, {1, 2, 1, 2}, {1, 1, 3, 1}, {1,
            2, 1, 4}}, Mesh -> All], {i, 2}, {j, 2}]], 
     toPDF@Plot[x, {x, 0, 1}, PlotLabel -> "yyy"]}}];

Export["test.jpg", plots, ImageResolution -> 600]

(* ==> "test.jpg" *)

The result looks the same as in the notebook. The first issue I'm addressing with toPDF is the incorrect scaling of the ticks and frame for which I suggested the PDF export and re-import trick here. The second issue is that this trick doesn't work properly with the DensityPlot output, but this can be fixed by triggering automatic rasterization upon export. I do this with another earlier hack by adding an invisible textured polygon to each plot.

$\endgroup$
6
  • $\begingroup$ Hi,@Jens. Thank you so much for answering. I just found that the problem with densityplot is probably a bug. For example, Export["density.pdf",plots] and Import["density.pdf"] will also cause "Unsupported Shading type 7" error. What is wrong? $\endgroup$
    – matheorem
    Commented Apr 30, 2018 at 5:14
  • $\begingroup$ And an unexpected effect is that your current solution takes too much memory(because I set memory limit of roughly 3GB for mma, and it quickly blows it, so I notice the memory usage...) $\endgroup$
    – matheorem
    Commented Apr 30, 2018 at 5:21
  • $\begingroup$ and I tried to set ImageResolution as 300, it works this time. But look at the image, I found that the font size is obviously smaller... $\endgroup$
    – matheorem
    Commented Apr 30, 2018 at 5:24
  • $\begingroup$ You should definitely also set an explicit ImageSize to control the bounding box of the export. But personally what I almost always do if I want to preserve the exact appearance in the notebook is to take a screenshot instead of using Export, because it's not realistic in practice to always remember how to add all those options and wrappers... the other error you mention is related to the fact that MMA can't properly import its own exported PDF - that's why I added the `Texture' hack. $\endgroup$
    – Jens
    Commented Apr 30, 2018 at 16:16
  • $\begingroup$ Hi, @Jens, Thanks for reply. I don't understand "explicit ImageSize to control the bounding box of the export." What is bounding box? And I updated my post. Have a look? : ) $\endgroup$
    – matheorem
    Commented May 1, 2018 at 1:53
1
$\begingroup$

You may use the ImageSize option for Graphics; both of these functions have the same options as Graphics.

The issue is that the default value for ImageSize is Automatic. This fits the graphic to the size of its the container. In Grid this resizes the graphics when they go through the export process.

You may add any setting to the option for the the graphics. ImageSize -> Small or any other setting will work.

plots = 
 Grid[{
  {Grid[Table[
    ListDensityPlot[{{1, 1, 1, 1}, {1, 2, 1, 2}, {1, 1, 3, 1}, {1, 2, 1, 4}}, 
      Mesh -> All, 
      ImageSize -> Small], 
    {i, 2}, {j, 2}]], 
   Plot[x, {x, 0, 1}, 
     PlotLabel -> "yyy", 
     ImageSize -> Small]}
  }];

Export["test.jpg", plots, ImageResolution -> 600]

enter image description here

Hope this helps.

$\endgroup$
2
  • $\begingroup$ Seems working. Thank you so much. $\endgroup$
    – matheorem
    Commented May 1, 2018 at 3:58
  • $\begingroup$ However, I got a new problem. Check this test = DensityPlot[x, {x, 0, 1}, {y, 0, 1}, PlotRange -> All, FrameLabel -> {"w", "E"}, LabelStyle -> Directive[Bold, 13, Black]]; Export["iii.pdf", Grid[{{test, test}}], ImageResolution -> 600]. It seems that font will be wrong, if we set LabelStyle. Is there a workaround? $\endgroup$
    – matheorem
    Commented May 1, 2018 at 4:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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