# Remove artifact of PDF images

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

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[
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

• 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

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

rasterizeBackground[g_Graphics, res_: 450] :=
Show[Rasterize[
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[
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.

• 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