Exporting an image so that the PlotRange has a fixed size in the output
I don't know if the following addresses all of your issues, but there are 2 things I would try:
ImageSize -> Automatic -> size
This option sets the plot range of the plot to have the ImageSize size.
Charting`ScaledFrameTicks[{Identity, Identity}]
This ticks specification draws tick marks, but no labels.
Using the above, you shouldn't have to worry about tweaking the ImageSize
and ImagePadding
options. For example:
Grid[{
{
Plot[x, {x,0,1}, Frame->True, ImageSize->Automatic->{170,170/GoldenRatio},
FrameTicks->{{True,True},{Charting`ScaledFrameTicks[{Identity,Identity}],True}},
FrameLabel->{{f,None}, {None, None}}
],
Plot[y^2, {y,0,1}, Frame->True, ImageSize->Automatic->{170,170/GoldenRatio},
FrameTicks->{{Charting`ScaledFrameTicks[{Identity,Identity}],True},{Charting`ScaledFrameTicks[{Identity,Identity}],True}}
]
},
{
Plot[x^3, {x,0,1}, Frame->True, ImageSize->Automatic->{170,170/GoldenRatio},
FrameTicks->{{True,True},{Automatic,True}},
FrameLabel->{{g,None},{x,None}}
],
Plot[y^4, {y,0,1}, Frame->True, ImageSize->Automatic->{170,170/GoldenRatio},
FrameTicks->{{Charting`ScaledFrameTicks[{Identity,Identity}],True},{Automatic,True}},
FrameLabel->{{None,None},{y,None}}
]
}
}]
Here is an approach based on well-documented Inset[gr, pos, opos, Automatic]
functionality.
It is important to use Scaled
specification for opos
. Benefits:
Using
Scaled
specification foropos
we position inset relative to the corners of its plotting range, not relative to the image corners.We can safely add any
ImagePadding
togr
without altering its position.
Having this in mind, we first choose a convenient constant ImagePadding
for all insets with which we won't care anymore about possibility of cropping in insets themselves:
iP = 100;
Desired size of the plotting range:
{iPRW, iPRH} = {170, 170/GoldenRatio};
Since ImagePadding
is included in ImageSize
, the final ImageSize
for insets is calculated as sum of the size of the plotting range plus doubled ImagePadding
:
iS = {iPRW, iPRH} + 2 iP;
We have to choose horizontal and vertical spacings between plots in the final grid:
{hSpacing, vSpacing} = {10, 10};
ImagePadding
for the whole figure is the only parameter which we tune by hand (although there is a way to obtain it automatically):
iPGrid = {{40, 5}, {40, 3}};
Having it we can calculate the size of the final figure:
iSGrid = 2*{iPRW, iPRH} + {hSpacing, vSpacing} + Plus @@@ iPGrid;
Now the plotting part.
Abbreviations (a fix for this bug is included in t
):
opts = Sequence[Frame -> True, ImageSize -> iS, ImagePadding -> iP];
t = Charting`ScaledFrameTicks[{Identity, Identity}][##][[;; , ;; 3]] &;
Our plots (taking setup of Carl Woll):
plots = With[{opts = opts}, {
{Plot[x, {x, 0, 1}, opts, FrameTicks -> {{True, True}, {t, True}},
FrameLabel -> {{"f", None}, {None, None}}],
Plot[y^2, {y, 0, 1}, opts, FrameTicks -> {{t, True}, {t, True}}]},
{Plot[x^3, {x, 0, 1}, opts, FrameTicks -> {{True, True}, {True, True}},
FrameLabel -> {{"g", None}, {"x", None}}],
Plot[y^4, {y, 0, 1}, opts, FrameTicks -> {{t, True}, {True, True}},
FrameLabel -> {{None, None}, {"y", None}}]}}];
Now we assemble everything into the final figure. It is important to set AspectRatio -> Full
in order to avoid cropping:
grid = Graphics[{
Inset[plots[[2, 1]], {0, 0}, Scaled[{0, 0}], Automatic],
Inset[plots[[2, 2]], Offset[{iPRW + hSpacing, 0}, {0, 0}], Scaled[{0, 0}], Automatic],
Inset[plots[[1, 1]], Offset[{0, iPRH + vSpacing}, {0, 0}], Scaled[{0, 0}], Automatic],
Inset[plots[[1, 2]], Offset[{iPRW + hSpacing, iPRH + vSpacing}, {0, 0}],
Scaled[{0, 0}], Automatic]},
ImageSize -> iSGrid, AspectRatio -> Full, PlotRange -> {{0, 1}, {0, 1}},
ImagePadding -> iPGrid]
Let us check the sizes of the plotting areas using Adobe Acrobat's "Measurement tool":
Export["grid.pdf", grid] // SystemOpen