3
$\begingroup$

If I export an ArrayPlot to pdf, I frequently observe that the colored pixels do not end at the top frame edge. Here is an example:

data = Flatten[Table[{x, y, x + y}, {x, 0, 10}, {y, 0, 10}], 1];
plot = Block[{data2, xmin, xmax, ymin, ymax},
   data2 = 
    Reverse[Transpose[
      Partition[data[[All, 3]], 
       Length[DeleteDuplicates[data[[All, 2]]]]]]];
   xmin = Min[data[[All, 1]]];
   xmax = Max[data[[All, 1]]];
   ymin = Min[data[[All, 2]]];
   ymax = Max[data[[All, 2]]];
   Show[ArrayPlot[data2,
     ColorFunction -> "M10DefaultDensityGradient",
     PlotRangePadding -> None,
     FrameTicks -> All,
     DataRange -> {{xmin, xmax}, {ymin, ymax}}],
    PlotRange -> {{xmin, xmax}, {ymin, ymax}}]];
Export["plot.pdf", plot]
Export["plot.png", plot, ImageResolution -> 500]

The png export as well as the graphics in the notebook look fine:

png

Here is zoom-in of the top-left corner:

png_zoom

However, the pdf export has some color outside the frame:

pdf_zoom

Is there a way to fix this?

$\endgroup$
  • $\begingroup$ Simplest thing might be to turn the frame off. $\endgroup$ – bill s Dec 8 '16 at 20:12
  • $\begingroup$ But I want to have a frame with ticks. Maybe I don't understand your suggestion. $\endgroup$ – Felix Dec 8 '16 at 22:15
  • $\begingroup$ PDF export is terrible. One thing to do is to hide the error with FrameStyle -> Directive[Gray, Thickness[Large]] $\endgroup$ – M.R. Dec 9 '16 at 1:47
  • $\begingroup$ Thanks for the suggestion, but that is also not possible for me. The line width of the frame should be consistent with other graphics and cannot be changed. $\endgroup$ – Felix Dec 9 '16 at 4:44
3
$\begingroup$

The pdf export is running into problems because the PlotRange you are using is cutting off half of each cell in the outside perimeter in your array. You can see even more vividly that Mathematica's pdf handling is not very good at dealing with this by exporting and then importing the image:

ImportString[ExportString[plot, "PDF"], "PDF"][[1]]

Mathematica graphics

Here it just gives up completely on trying to properly trim the plot.

The simplest solution is just to use PlotRange -> All if you don't actually need to cut off the cells on the perimeter. If you do need to cut them off, you could double the size of your array and do the trimming yourself.

Double the size of the array by converting each element to four elements, and then remove the outer border:

data3 = ArrayFlatten[Transpose[Table[data2, 2, 2], {3, 4, 1, 2}]][[2 ;; -2, 2 ;; -2]];

Make the ArrayPlot with the appropriate DataRange:

plot = ArrayPlot[data3, ColorFunction -> "M10DefaultDensityGradient",
  DataRange -> {{xmin + 1/4, xmax - 1/4}, {ymin + 1/4, ymax - 1/4}}, 
  PlotRange -> All, FrameTicks -> Table[Range[0, 10], 4], PlotRangePadding -> None
]

Mathematica graphics

Now when exporting and importing, we see that the borders are respected:

ImportString[ExportString[plot, "PDF"], "PDF"][[1]]

Mathematica graphics

$\endgroup$
  • $\begingroup$ Quite a hack but it works. Thanks. $\endgroup$ – Felix Dec 9 '16 at 15:33

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.