This is an incredibly annoying issue that led me to write my own package at one point. While we're dealing with a grid of images of equal sizes, this is easily solvable (see answers of Sjoerd C. de Vries and Alexei Boulbitch).
Unfortunately, we (myself and the topic-starter, at least) often want GraphicsGrid
to behave more like Grid
.
Compare, for example, the very different outputs of Grid
and GraphicsGrid
in the following example:
s0 = Plot[Sin[x], {x, -10, 10}, Frame -> True, FrameLabel -> {"x", "y"},
AspectRatio -> Full, ImageSize -> {550, 300}];
s00 = Plot[Sin[x], {x, -10, 10}, Frame -> True, FrameLabel -> {"x", "y"},
AspectRatio -> Full, ImageSize -> {550, 550}];
GraphicsGrid[{{s0, s0}, {s00, s00}}, Spacings -> 0]
Grid[{{s0, s0}, {s00, s00}}]
So I wrote my own function to arrange plots into grids. I'm afraid, there's far too much code (and bad code, at that) to include in one short answer, but here's the general approach I take when I want to be the one deciding how and where to place Graphics
:
img := Plot[Sin[x], {x, 0, 10},
ImageSize -> RandomInteger[{200, 400}, 2], AspectRatio -> Full,
Frame -> True]
img1 = img; img2 = img; img3 = img; img4 = img;
grid = {{img1, img2}, {img3, img4}};
sizes = Map[ImageDimensions, grid, {2}]
(* {{{315, 229}, {335, 234}}, {{382, 268}, {373, 390}}} *)
rowheights = Max /@ sizes[[All, All, 2]]
(* {234, 390} *)
colwidths = Max /@ Transpose@sizes[[All, All, 1]]
(* {382, 373} *)
positions = Position[grid, _Graphics]
(* {{1, 1}, {1, 2}, {2, 1}, {2, 2}} *)
Having made all these definitions we then gather a tightly packed collection of plots using a bunch of Inset
s. Here the space allocated to each plot is the width of the widest element of the column and the height of the heighest element of the row. Each element is aligned to the bottom-right. This is tweakable with the settings of ImageScaled
and addition/subtraction of the appropriate element of rowheight/colwidth.
Graphics[Table[
Inset[grid[[Sequence @@ index]], {Plus @@
colwidths[[;; index[[2]]]],
Plus @@ rowheights - Plus @@ rowheights[[;; index[[1]]]]},
ImageScaled[{1, 0}]], {index, positions}],
ImageSize -> {Plus @@ colwidths, Plus @@ rowheights},
ImagePadding -> None,
PlotRange -> {{0, Plus @@ colwidths}, {0, Plus @@ rowheights}},
AspectRatio -> Plus @@ rowheights/Plus @@ colwidths,
PlotRangePadding -> None]
This returns

as compared to normal GraphicsGrid
output

Edit
I have a sneaking suspicion, that the spaces automatically spliced in where I use shorthand @@
for Apply
might break the code and make MMA try to divide a List
by Plus
, if that happens, apply parentheses generously.