9
$\begingroup$

Version 12 includes a new Layout->Column option for ListPlot which aligns multiple plots so they share a single horizontal axis. It seemed really useful at first. But data being compared in this way can have very different vertical scales.

It appears that the new capability always sets the PlotRange of all the data sets to the same value:

d1 = Table[{x, .1 Sin[x]}, {x, 0, 3 Pi, Pi/9}];

d2 = Table[{x, Cos[x]}, {x, 0, 4 Pi, Pi/7}];

ListLinePlot[{d1, d2}, PlotLayout -> "Column", 
 InterpolationOrder -> 2, GridLines -> Automatic, 
 PlotRange -> Automatic]

enter image description here

I have tried what seems reasonable to set the ranges separately:

ListLinePlot[{d1, d2}, PlotLayout -> "Column", 
 InterpolationOrder -> 2, GridLines -> Automatic, 
 PlotRange -> {{Automatic, Automatic}, {Automatic, Automatic}}]

ListLinePlot[{d1, d2}, PlotLayout -> "Column", 
 InterpolationOrder -> 2, GridLines -> Automatic, 
 PlotRange -> {{Automatic, {-.1, .1}}, {Automatic, {-1, 1}}}]

But neither of these work. The first gives the same result, and the second throws an error. Does anyone have any insight into this?

EDIT:

Thank you @Szabolcs. Your solution not only solves the range problem, but permits differing scaling functions. (A cross section of a biased semiconductor junction may want to plot potentials from 0 to 10 volts, but also carrier concentrations from 0 to 1E18 on a log scale.)

d3 = Table[{x, Exp[10 Cos[x]]}, {x, 0, 4 Pi, Pi/100}];
GraphicsColumn[
 {
  ListLinePlot[d1, InterpolationOrder -> 2, GridLines -> Automatic, 
   PlotRange -> {{0, 4 Pi}, Automatic}, Frame -> True, 
   FrameTicks -> {{Automatic, None}, {None, None}},
   FrameLabel -> {None, "Linear"}],
  ListLinePlot[d3, InterpolationOrder -> 2, GridLines -> Automatic, 
   PlotRange -> {{0, 4 Pi}, All}, Frame -> True, FrameLabel -> "Log", 
   ScalingFunctions -> "Log"]
  }
 ]

enter image description here

$\endgroup$
  • $\begingroup$ You can use GraphicsColumn[{...}, Spacings -> {0, -30}] if you need. $\endgroup$ – Okkes Dulgerci Apr 21 at 22:40
11
$\begingroup$

There is another new feature in M12.0: GraphicsColumn will now align the frames.

You can use this:

d1 = Table[{x, .1 Sin[x]}, {x, 0, 3 Pi, Pi/9}];
d2 = Table[{x, Cos[x]}, {x, 0, 4 Pi, Pi/7}];

GraphicsColumn[
 ListLinePlot[#, InterpolationOrder -> 2, GridLines -> Automatic, 
                 PlotRange -> {{0, 4 Pi}, Automatic}, Frame -> True] & /@ {d1, d2}
]

enter image description here

While I did need to set the horizontal range explicitly (so that they match), I did not need to fuss with the ImagePadding to ensure that the frames line up. This saves a lot of work.

Here's what the same looks like in M11.3:

enter image description here

The grids and frames are not quite aligned.

$\endgroup$
  • $\begingroup$ Thank you, Szabolcs. That works perfectly. I edited my question to comment further. $\endgroup$ – David Keith Apr 21 at 20:02
3
$\begingroup$

Note: For most tasks, the improved GraphicsGrid functions from version 12.0 are (finally) more than sufficient (see @Szabolcs answer). I post this answer mostly as an alternative for those who need a bit more flexibility/don't have access to Mathematica 12.

You can also use the PlotGrid function from the ForScience` paclet (mostly written by me). It has some added flexibility (shared labels, auto hiding of frame ticks, variable row/column sizes, …) compared to GraphicsGrid, and it is available in Mathematica 11.1+.

Here's how you could use it for your example:

(* load the paclet *)
<< ForScience`

d1 = Table[{x, .1 Sin[x]}, {x, 0, 3 Pi, Pi/9}];
d2 = Table[{x, Cos[x]}, {x, 0, 4 Pi, Pi/7}];
d3 = Table[{x, Exp[10 Cos[x]]}, {x, 0, 4 Pi, Pi/100}];

(* create the plot grid, with some examples for different options *)
Table[
 PlotGrid[
  {
   {ListLinePlot[d1, InterpolationOrder -> 2, GridLines -> Automatic, 
     PlotRange -> {{0, 4 Pi}, Automatic}, Frame -> True, 
     FrameLabel -> {None, "Linear"}]},
   {ListLinePlot[d3, InterpolationOrder -> 2, GridLines -> Automatic, 
     PlotRange -> {{0, 4 Pi}, All}, Frame -> True, 
     FrameLabel -> "Log", ScalingFunctions -> "Log"]
    }
   },
  opts
  ],
 {opts, {
   {},
   {Spacings -> 20},
   {Spacings -> 20, "ShowFrameLabels" -> Full},
   {Spacings -> 20, "ShowFrameLabels" -> Full, 
    FrameLabel -> {"x Axis", "y Axes"}}}
  }
 ]

enter image description here

(the screenshot also shows the "Get coordinates" functionality of the plots, which gives you the proper coordinates for the plot you're currently in)

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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