7
$\begingroup$

If we make a framed plot

Plot[Evaluate[Table[BesselJ[i, x], {i, {2, 5, 10}}]],{x, 0, 50}, Frame->True, AspectRatio->1/2, ImageSize->Automatic->300]

enter image description here

The frame ticks appear within the boundary of the plot. However if we want to make a column, or stack, of plots we can use PlotLayout

Plot[Evaluate[Table[BesselJ[i, x], {i, {2, 5, 10}}]], {x, 0, 50}, Frame->True, AspectRatio->1/2, ImageSize->Automatic->300, PlotLayout->{"Column", 1}, FrameLabel->{"X-AXIS", "Y-AXIS"}]

enter image description here

However we can see this changes the frame tick style such that we lose minor ticks, and they point outwards from the frame..

How can we keep the frame tick look of a standard layout plot, while using an option in PlotLayout? One solution is to use Grid, but then defining a common axis label is tricky, and in PlotLayout this is easily achievable. Of course we can use some conditional axis labelling such that the only the middle plot y-axis and lower plot x-axis are labelled, but this falls over for even number of plots and for y-axis labels which are longer than the height of a single plot (the spacing will become irregular).

Grid[Table[{Plot[BesselJ[i, x], {x, 0, 50}, Frame->True, AspectRatio->1/2, ImageSize->Automatic->300, FrameLabel->{"X-AXIS", "Y-AXIS"}]}, {i, {2, 5, 10}}]]

enter image description here

How can we keep interior, default frame ticks when using a specified plot layout?

$\endgroup$

2 Answers 2

6
$\begingroup$

If you don't want to fiddle around with the PlotTicks, you can use the ResourceFunction PlotGrid to build your required arrangement from individual Plots.

First create 2D arrangment of Plots you want to show. In this case it is 3x1 elements:

plots = Table[Plot[Evaluate[BesselJ[i,x]],{x,0,50},Frame->True,AspectRatio->1/2,ImageSize->Automatic->300],{i,{2,5,10}}]//ArrayReshape[#, {3, 1}]&

Then use ResourceFunction["PlotGrid"] to stack the individual plots. As Lukas Lang pointed out in the comments, "ShowFrameLabels" -> Automatic hides the tick labels whenever there is an adjacent plot:

grid = ResourceFunction["PlotGrid"][
    plots, 
    Spacings -> 6,
    "ShowFrameLabels" -> Automatic
  ]

As a last step, add the global axis labels to the plotgrid. This also works for an even number of plots - the labels are always centered on the respective sides.

gridWithLabels = Labeled[grid, {"X-AXIS", "Y-AXIS"}, {Bottom, Left}, RotateLabel -> True]

plotgrid

$\endgroup$
3
  • $\begingroup$ This is a pretty good work around! I'll leave the question open a little longer, but I think this does the trick. $\endgroup$
    – user27119
    Jan 3, 2023 at 13:58
  • 1
    $\begingroup$ You can use "ShowFrameLabels"->Automatic (instead of the default Full) to automatically hide the labels whenever there is an adjacent plot (even with Spacings). Also, you can use the FrameLabels option to get the labels instead of needing an extra Labeled wrapper. So something like ResourceFunction["PlotGrid"][plots, "ShowFrameLabels" -> Automatic, Spacings -> 6, FrameLabel -> {"X-AXIS", "Y-AXIS"}] should do the trick $\endgroup$
    – Lukas Lang
    Jan 3, 2023 at 14:12
  • $\begingroup$ Thanks for pointing out the Automatic option, I edited the answer to include this. However, I kept the extra Labeled wrapper, because I often use the Spacings option in Labeled to adjust the offset of the labels with respect to the graphics, and I think this is not possible when directly specifying the FrameLabels in ResourceFunction["PlotGrid"]. $\endgroup$
    – Mathias
    Jan 3, 2023 at 15:13
1
$\begingroup$

Inspired by the answer which I have accepted, I thought I would add a solution which might work for some others:

Labeled[
        GraphicsGrid[
                        Table[
                                FrameTickStyleSetting = 
                                Switch[
                                        i,
                                        2, {Automatic, Directive[FontOpacity->0, FontSize->0]},
                                        5, {Automatic, Directive[FontOpacity->0, FontSize->0]},
                                        10, {Automatic, Automatic}
                                    ];
                                {
                                    Plot[
                                            BesselJ[i, x], {x, 0, 50}, 
                                            Frame->True, FrameTicksStyle->FrameTickStyleSetting, AspectRatio->1/2, ImageSize->Automatic->300]
                                },  {i, {2, 5, 10}}
                             ], 
                        Spacings->{0, -25}
                   ],
        {"X-AXIS", "Y-AXIS"}, {Bottom, Left}, RotateLabel->True
    ]

The potential negative of this solution is that it requires some conditional code to put the frame tick labels on the right axis.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.