2

I have a PDF figure created with Export[] in Mathematica 11.0.1.0 on Mac OSX

enter image description here

The figure has these improper white-lines when I zoom-out and make the image smaller (The size it will appear in the document).

I have seen a previous post Avoiding white lines inside filled area in RegionPlot exported as PDF or PS but this does not resolve this issue.

The code used to generate the image is:

f21fps = Show[SmoothDensityHistogram[data21fps,
   PlotRange -> {{0, 200}, {0, 200}}, 
   ColorFunction -> "SunsetColors",
   FrameLabel -> {Text[
      Style["t2-t1", FontSize -> 14, Italic],
       FormatType -> StandardForm], 
     Text[Style["t1", FontSize -> 14, 
       Italic], FormatType -> StandardForm]},
   PlotLabel -> "FPS", LabelStyle -> {FontFamily -> "Times", 14},
   PlotLegends -> 
    BarLegend[Automatic, LegendFunction -> f, 
     LegendMarkerSize -> 368]
   , Mesh -> 0
   ], Plot[x, {x, 0, 200}], ImageSize -> 400, PlotRangePadding -> 0]
 Export["f21fps.pdf",f21fps];

where data21fps is a list of {x,y} values. How could I avoid the undesired white lines when reducing the size of the pdf image?

EDITED 1

Due to comment of @march, I am trying to rasterize the plot but not the axes as it is explained in the post Rasterized image together with vector-graphics axes

which uses this code to make it

rasterizeBackground[g_, res_: 450] := 
 Show[Rasterize[
    Show[g, PlotRangePadding -> 0, ImagePadding -> 0, 
     ImageMargins -> 0, LabelStyle -> Opacity[0], 
     FrameTicksStyle -> Opacity[0], FrameStyle -> Opacity[0], 
     AxesStyle -> Opacity[0], TicksStyle -> Opacity[0], 
     PlotRangeClipping -> False], ImageResolution -> res] /. 
   Raster[data_, rect_, rest__] :> 
    Raster[data, 
     Transpose@OptionValue[AbsoluteOptions[g, PlotRange], PlotRange], 
     rest], Sequence @@ Options[g], Sequence @@ Options[g, PlotRange]]

I have been testing it but gives me error

f21fpsR = rasterizeBackground[f21fps]
Rule::argr: Rule called with 1 argument; 2 arguments are expected.

How could I fix this and make it work with my image?

Thank you very much

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
user1993416
  • 589
  • 1
  • 5
  • 12
  • I have just added the code to generate the image. – user1993416 Aug 10 '17 at 15:49
  • Here is my favorite fix for this problem. Not only does it get rid of the white lines, but it makes the exported pdf's a very reasonable size. Scroll down in that answer to the contourDensityPlot function. That's the one I use. Furthermore, it accepts the same options as ContourPLot and DensityPlot – march Aug 10 '17 at 16:38
  • @march Thank you very much. I have taken a look at that post, but I am still confused. May I ask you what the options or the part of the code I should look are? – user1993416 Aug 10 '17 at 16:54
  • I see that I didn't read your post very carefully: I thought you had a density plot. The answer I think would be to rasterize your plot. I may be able to help, but not right now. – march Aug 10 '17 at 17:18
  • @march thank you. The image is a SmoothDensityHistogram[] plotting a data set of {x,y} points. – user1993416 Aug 10 '17 at 17:32

1 Answers1

4

To fix the error you get when using rasterizeBackground, add the following definitions (remove the old one):

rasterizeBackground[g_Graphics, res_: 450] := 
 Show[Rasterize[
    Show[g, PlotRangePadding -> 0, ImagePadding -> 0, 
     ImageMargins -> 0, PlotLabel -> None, FrameTicks -> None, 
     Frame -> None, Axes -> None, Ticks -> None, 
     PlotRangeClipping -> False], ImageResolution -> res] /. 
   Raster[data_, rect_, rest__] :> 
    Raster[data, 
     Transpose@OptionValue[AbsoluteOptions[g, PlotRange], PlotRange], 
     rest], Sequence @@ Options[g], 
  Sequence @@ Options[g, PlotRange]] 

rasterizeBackground[g_, res_: 450] := 
  ReplacePart[
    g,
    # -> rasterizeBackground[Extract[g, #], res] & 
     /@ Position[g, Graphics[__]]
  ]

The issue with rasterizeBackground is that it works under the assumption that it's argument is the Graphics expression without any wrappers. This assumption is no longer fulfilled when you use PlotLegends, as this causes the result to have head Legended.

The above definition fixes this by searching for anything of the form Graphics[__] and replacing it by a rasterized version (using a modified version of the original rasterizeBackground) inside the original expression.

Update

Fully working example: The below code produces the expected result for me (fresh kernel, MMA 11.1). I basically copied your code and created some sample data.

(*some random data*)
data21fps = 200 {#1 #2, Sin[#1 + #2]^2} & @@@ RandomReal[{0, 1}, {100000, 2}];
(*the original plot*)
f21fps = Show[
  SmoothDensityHistogram[data21fps, PlotRange -> {{0, 200}, {0, 200}},
    ColorFunction -> "SunsetColors", 
   FrameLabel -> {Text[Style["t2-t1", FontSize -> 14, Italic], 
      FormatType -> StandardForm], 
     Text[Style["t1", FontSize -> 14, Italic], 
      FormatType -> StandardForm]}, PlotLabel -> "FPS", 
   LabelStyle -> {FontFamily -> "Times", 14}, 
   PlotLegends -> 
    BarLegend[Automatic, LegendFunction -> "Panel", 
     LegendMarkerSize -> 368], Mesh -> 0], Plot[x, {x, 0, 200}], 
  ImageSize -> 400, PlotRangePadding -> 0]

(*the fixed version of rasterizeBackground for Graphics expressions*)
rasterizeBackground[g_Graphics, res_: 450] := 
 Show[Rasterize[
    Show[g, PlotRangePadding -> 0, ImagePadding -> 0, 
     ImageMargins -> 0, PlotLabel -> None, FrameTicks -> None, 
     Frame -> None, Axes -> None, Ticks -> None, 
     PlotRangeClipping -> False], ImageResolution -> res] /. 
   Raster[data_, rect_, rest__] :> 
    Raster[data, 
     Transpose@OptionValue[AbsoluteOptions[g, PlotRange], PlotRange], 
     rest], Sequence @@ Options[g], 
  Sequence @@ Options[g, PlotRange]] 

(*the extension for wrapped Graphics expressions*)
rasterizeBackground[g_, res_: 450] := 
 ReplacePart[
  g, # -> rasterizeBackground[Extract[g, #], res] & /@ 
   Position[g, Graphics[__]]]

(*test it*)
rasterizeBackground[f21fps]

rasterizeBackground[Column@{Panel[f21fps], "Works anywhere"}, 10]

Update 2

As noted in the comments, the original version of rasterizeBackground has some issues and produced a white bar at the top of the plot range. The reason for this was that labels, frames, etc. were only hidden (with Opacity[0]) instead of removed. The updated version (see above) now simply removes all these features using None.

Lukas Lang
  • 33,963
  • 1
  • 51
  • 97
  • 1
    I have tested rasterizeBackground[f21rand] but the output is the function without evaluation i.e. out[73]= rasterizeBackground[theImage, 425]. Please, can you tell me what am I doing wrong? Thank you very much. – user1993416 Aug 11 '17 at 11:06
  • Did you also add the original definition of rasterizeBackground? – Lukas Lang Aug 11 '17 at 11:20
  • Yes, the function is evaluated before of this new one – user1993416 Aug 11 '17 at 11:20
  • Do I have to make Clear befor using rasterizeBackground?. I have made the clear but still is not giving an output with a image. Thank you very much for your help. – user1993416 Aug 11 '17 at 12:35
  • You should not have to use Clear in theory... I updated the answer with a fully working example, can you check whether that works for you? – Lukas Lang Aug 11 '17 at 12:55
  • Thank you very much. Now it looks fine in the final TeX document, without the white lines. However, the rasterized image looks like it shrinks the y-dimension because there is a blank space with the uppermost axis line. How can I make the image look similar to the original plot? – user1993416 Aug 11 '17 at 13:48
  • I have noticed that the new figure has a frame that is also a little smaller than the original figure. This is not really important because all figures will have the same size in the TeX file. – user1993416 Aug 11 '17 at 14:04
  • it is not clear for me how to solve the issue of axis alignment in the rasterized plot. Please, How could I fix it? – user1993416 Aug 11 '17 at 16:34
  • I updated the answer with a modified version of rasterizeBackground that doesn't have the white bar at the top. However, I'm not sure what you mean with the axis alignment. Can you elaborate? – Lukas Lang Aug 11 '17 at 17:25
  • Awesome code. I am very grateful. It works perfectly – user1993416 Aug 11 '17 at 17:54
  • What I meant was that placed side by side the rasterized version looks just a little smaller, but there is no need to change because all figures of the same type will be generated the same. – user1993416 Aug 11 '17 at 18:00
  • I have just notice that the function rasterizeBackground[g_Graphics, res_: 450] vectorize the frame of the density plot but not the legend. Therefore, the ticks labels are clearer than the ticks labels of the legend. Please, can you make the function also working for ticks of the legend? Note: I am going to put a separated question for this. – user1993416 Aug 13 '17 at 15:59