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:

  1. ImageSize -> Automatic -> size

This option sets the plot range of the plot to have the ImageSize size.

  1. 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}}
    ]
    }
}]

enter image description here


Here is an approach based on well-documented Inset[gr, pos, opos, Automatic] functionality.

It is important to use Scaled specification for opos. Benefits:

  1. Using Scaled specification for opos we position inset relative to the corners of its plotting range, not relative to the image corners.

  2. We can safely add any ImagePadding to gr 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]

output

Let us check the sizes of the plotting areas using Adobe Acrobat's "Measurement tool":

Export["grid.pdf", grid] // SystemOpen

screesnhot