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:
but the pdf is messed up:




RowandColumn) leads to the same effect. I believe that the core of the problem is thatRowsometimes introduces linebreaks. Maybe the question actually is: how can I force aRowobject to be monolithic, i.e., to forbid line breaks? – Felix Dec 07 '16 at 22:57