2
$\begingroup$

I am trying to prepare a grid of DensityPlots (or actually ArrayPlots because they are faster). The plots should have color scale bars attached, which I do using the Row command because here because GraphicsRow and GraphicsGrid really don't let you align the objects nicely (also see this post).

Now the question is: If plot1, plot2, ..., plotn are each plots generated by combining two DensityPlots using Row, like

plot1=Row[subplot1,colorbar1]

how can I show these plots a grid and export that grid to pdf, without linebreaks in the middle of a row (see also here and here).

Basically, what I tried is

allPlots = Grid[Transpose[{{plot1,plot2}, {plot3, plot4}}];
Export["figure.pdf", allPlots];

Now the color bars are in a separate row and not next to their plots, as intended.

When I output the result in the notebook, everything looks fine. There, the only problem is that working with the notebook becomes very laggy (scrolling, typing, etc.), but that is not really part of the question.

One comment: I realized that the plots, created by Row, are no graphics objects. Maybe it would be a solution to convert each plot into a graphics object, but how? See also this question.

Edit:

To illustrate the problem, here is a code to reproduce the issue:

(* Function to generate the color bar legend *)

customBarLegend[zmin_, zmax_, label_, colorFunction_: Automatic] := 
 Module[{},
  Show[ArrayPlot[
    Table[{zmax + zmin - y}, {y, zmin, zmax, (zmax - zmin)/100}],
    ColorFunction -> colorFunction,
    ColorFunctionScaling -> False,
    DataRange -> {{0, 1}, {zmin, zmax}},
    Frame -> True,
    FrameLabel -> {{None, None}, {None, label}},
    FrameTicks -> {{None, All}, {None, None}},
    PlotRangePadding -> 0,
    AspectRatio -> 20,
    Axes -> False],
   PlotRange -> {{0, 1}, {zmin, zmax}}]]

(* Function to convert a regular (ugly) BarLegend into a custom bar
legend that has the same height as the plot. *)

convertBarLegend[plot_, imPad_, barPad_, size_] := 
 Module[{zmin, zmax, zlabel, colorFunction, bar},
  {zmin, zmax} = (List @@ (List @@ plot)[[2]][[1]])[[1]][[2]];
  zlabel = LegendLabel /. (List @@ (List @@ plot)[[2]][[1]])[[3]];
  colorFunction = (List @@ (List @@ plot)[[2]][[1]])[[1]][[1]];
  bar = customBarLegend[zmin, zmax, zlabel, colorFunction];
  Row[{Show[(List @@ plot)[[1]], ImageSize -> {Automatic, size}, 
     ImagePadding -> imPad], 
    Show[bar, ImageSize -> {Automatic, size}, ImagePadding -> barPad]}]
  ]

(* Test data *)

data = Flatten[Table[{x, y, x + y}, {x, 0, 50}, {y, 0, 50}], 1];

 (* Plot the test data as ArrayPlot because ListDensityPlot increases 
the output file size by a factor 20 *)

uglyplot = Block[{data2, xmin, xmax, ymin, ymax, zmin, zmax},
   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]]];
   zmin = Min[data[[All, 3]]];
   zmax = Max[data[[All, 3]]];
   ArrayPlot[data2,
    ColorFunction -> 
     ColorData[{"M10DefaultDensityGradient", {zmin, zmax}}],
    ColorFunctionScaling -> False,
    PlotRangePadding -> None,
    FrameTicks -> {{Automatic, None}, {Automatic, None}},
    DataRange -> {{xmin, xmax}, {ymin, ymax}},
    PlotLegends -> BarLegend[Automatic, LegendLabel -> "z"]]];
imPad = {{50, 7}, {60, 
   10}}; (*{{left,right},{bottom,top}}*)
barPad = {{1, 100}, 
  imPad[[2]]};(* bottom and top should be the same as imPad. *)
plot =
  convertBarLegend[uglyplot, imPad, barPad, 300];

(* Arrange the plots in a grid *)
plotgrid = 
 Grid[{{plot, plot}, {plot, plot}}]

(* Export *)
Export["plotgrid.pdf", plotgrid];
Export["plotgrid.png", plotgrid];

The png file looks fine:

png

but the pdf is messed up:

pdf

$\endgroup$
  • 1
    $\begingroup$ Related: (65211). $\endgroup$ – corey979 Dec 7 '16 at 21:35
  • $\begingroup$ True, but the solution there (using a combination of Row and Column) leads to the same effect. I believe that the core of the problem is that Row sometimes introduces linebreaks. Maybe the question actually is: how can I force a Row object to be monolithic, i.e., to forbid line breaks? $\endgroup$ – Felix Dec 7 '16 at 22:57
7
$\begingroup$

If you want to prevent line breaks in the exported image, you can use LineBreakWithin -> False (here I'm using ExportString instead of Export just for convenience):

row = Row@Table[Plot[x, {x, 0, 1}], 10];
First@ImportString[ExportString[row, "PDF"], "PDF"]

Mathematica graphics

First@ImportString[ExportString[Style[row, LineBreakWithin -> False], "PDF"], "PDF"]

Mathematica graphics

$\endgroup$
  • $\begingroup$ Yes, exactly what I was looking for! $\endgroup$ – Felix Dec 8 '16 at 3:13

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.