2

I have three plots defined as:

plot = 
  DateListPlot[data, {{2000, 12, 31}, {2007, 12, 31}}, 
    Frame -> True, Joined -> True, PlotRange -> All, 
    LabelStyle -> {FontSize -> 15}, PlotStyle -> Black, ImageSize -> 900,
    AspectRatio -> 0.3, FrameLabel -> {"", "", Style["Plot", 15]}]

Then I wanted to combine these three plots so that they will be in one column:

GraphicsColumn[{plot1, plot2, plot3}]

The problem is that in this combined plot the individual plots appear narrower than when I plot them separately.

What am I doing incorrectly?

Alexey Popkov
  • 61,809
  • 7
  • 149
  • 368
Johny
  • 71
  • 5
  • Please include some example data. Also loosely related: http://mathematica.stackexchange.com/questions/78192/delete-the-white-areas-in-graphicsgrid/78193 and several related questions under the search query for GraphicsGrid and related functions – LLlAMnYP Apr 13 '15 at 09:46
  • 3
    You're not really doing anything incorrectly, this is just the unpleasant behaviour of GraphicsColumn (-Row, -Grid, etc). These functions generate an object with head Graphics and use Inset to place your plots inside. The problem is, they set the size of the individual plots to {imagewidth, aspectratio*imagewidth} whereas for an individual plot it is the plot range that maintains your aspect ratio setting. In your case your plot is 900*324, but in the column it's 900*270 so to maintain AspectRatio->0.3 it has to be narrowed. – LLlAMnYP Apr 13 '15 at 10:16

1 Answers1

6

This isn't so much an answer as to how to fix this (one workaround is Column[{plot1,plot2,plot3}], instead of GraphicsColumn, but it has its drawbacks), but more of an explanation of what's happening.

First I generate some fake data and create a plot similar to yours:

data = SortBy[RandomReal[10, {10, 2}], First];
plot = ListPlot[data, Frame -> True, Joined -> True, PlotRange -> All,
LabelStyle -> {FontSize -> 15}, PlotStyle -> Black, 
AspectRatio -> .3, ImageSize -> 900, 
FrameLabel -> {"", "", Style["Plot", 15]}]

ImageDimensions[plot]
(* {900, 324} *)

Then do

GraphicsColumn[{plot,plot,plot}]
(* Get result with narrower plots, than desired. Also their height is smaller *)

Now let's take a closer look at the structure of the output.

InputForm[%];
TableForm @@ %

Inset[(*Graphics of plot*), {472.5, -145.125}, ImageScaled[{0.5, 0.5}], {900, 270.}]...

Let's check out the documentation of Inset. It places the point ImageScaled[{.5,.5}] (the center) of plot at the point {472.5,-145.125} in the enclosing graphics object... and resizes plot to {900, 270}. I can't say, why exactly this is done like that, but it explains, why your plots in the column become narrower.

You have specified an AspectRatio of 0.3, which means that the height-to-width of the framed part of your plot is 0.3.

When sticking this into the Inset Mathematica lazily just says "let the height-to-width of the entire inset (including margins for ticks and labels) be 0.3" which is not the same thing. While the correct width of your image is maintained at 900, the height of the plot with margins is now constrained to 270 instead of 324. To maintain the aspect ratio of the plotrange at 0.3 it has to also become narrower. I guess, there's a number of ways to work around this, e.g. pass ImageSize->{900,324}, AspectRatio->Full to your plots. My preferred way (by no means the best) is detailed here

EDIT

Here's a test with DateListPlot:

xdata = DateList /@ Range[3.6*10*^9, 3.63*10*^9, .3*10*^7];
ydata = RandomReal[10, 11];
data = Transpose[{xdata, ydata}];
plot = DateListPlot[data, Frame -> True, Joined -> True, 
   PlotRange -> All, LabelStyle -> {FontSize -> 15}, 
   PlotStyle -> Black, AspectRatio -> Full, ImageSize -> {900, 324}, 
   FrameLabel -> {"", "", Style["Plot", 15]}];
GraphicsColumn[{plot, plot, plot}]

This returns the desired result on my machine (MMA v10.0.1.0, Win7x64 Enterprise)

EDIT2 Here's how I prefer to arrange graphics into grids and such.

undistortedGraphicsColumn[list_] := 
 Module[{sizes = ImageDimensions /@ list, width},
  width = Max@sizes[[All, 1]];
  sizes = sizes[[All, 2]];
  Graphics[Table[
    Inset[list[[i]], {0, -Plus @@ sizes[[;; i]]}, 
     ImageScaled[{0, 0}]], {i, Length[list]}],
   ImageSize -> {width, Plus @@ sizes}, ImagePadding -> None, 
   PlotRange -> {{0, width}, {-Plus @@ sizes, 0}},
   AspectRatio -> Plus @@ sizes/width, PlotRangePadding -> None]]

Now this line will return the plots in a column exactly how they look individually:

undistortedGraphicsColumn[{plot,plot,plot}]

If you go with your original code now:

plot = 
  DateListPlot[data, {{2000, 12, 31}, {2007, 12, 31}}, 
    Frame -> True, Joined -> True, PlotRange -> All, 
    LabelStyle -> {FontSize -> 15}, PlotStyle -> Black, ImageSize -> 900,
    AspectRatio -> 0.3, FrameLabel -> {"", "", Style["Plot", 15]}]

And stick it into my function, you don't get the problem with enormous ticks and the column shows the plots as they are originally defined.

LLlAMnYP
  • 11,486
  • 26
  • 65
  • Thanks, @LLIAMnYP. But I do not understand where should I pass ImageSize->{900,324}, AspectRatio->Full. To the specification of plot1, plot2 and plot3 or to the specification of GraphicsColumn? :) – Johny Apr 15 '15 at 18:30
  • To the specs of the individual plots. – LLlAMnYP Apr 15 '15 at 18:34
  • It returns me charts on which there are only vertical lines, @LLIAMnYP – Johny Apr 16 '15 at 06:20
  • I've included a test with DateListPlot in my edited answer. If it still doesn't work, it probably has to do with your data. In that case please include the code you're trying. – LLlAMnYP Apr 16 '15 at 09:02
  • I want to plot list of numbers: list={13963.5, 18885.9, 16710.5, 14753.5, 11214.6, 98779.5,...} The code you have posted works for me as well. Is it possible that it is because I manually add the range of data for horizontal axes as specs of DateListPlot? (see above: DateListPlot[data, {{2000, 12, 31}, {2007, 12, 31}},...]) @LLIAMnYP – Johny Apr 16 '15 at 09:40
  • I have tried replacing the code-snippet DateListPlot[data... in my example with DateListPlot[ydata, {{2000, 12, 31}, {2007, 12, 31}}... (my ydata is also a list of real numbers) and this also returns the correct result. Try passing your list to my code, i.e. DateListPlot[list, {{2000, 12, 31}, {2007, 12, 31}}... while keeping everything else as I have posted. It should work... – LLlAMnYP Apr 16 '15 at 10:06
  • @LLIAMnYP, it is caused by the date->if the time interval is wide enough, it is OK even with my data. However, when I have narrower date range such as {{2011, 12, 31}, {2015, 04, 20}}, it does not work. – Johny Apr 19 '15 at 22:09
  • hmm. then try posting your data, so we can see if there's a workaround. – LLlAMnYP Apr 19 '15 at 22:23
  • Sorry, @LLIAMnYP, but since I am working not on my personal notebook but on the notebook of my employer, I will not be able to post the data. But it really looks like list={13963.5, 18885.9, 16710.5, 14753.5, 11214.6, 98779.5,...}. There are more than 100.000 of rows in Excel. Your code perfectly works for my data in case when the period is sufficiently long, but if it is only for e.g. two years, it does not work. Does your code work on your PC for period of two years (e.g. {{2013, 04, 20}, {2015, 04, 20}})? – Johny Apr 20 '15 at 14:17
  • I see your problem now, though I can't say, why this is happening. The vertical lines are the ticks which don't play nice with the AspectRatio->Full spec, while the height of the actual plot becomes constrained within a very narrow strip. I've encountered that before, will try some things out now. – LLlAMnYP Apr 20 '15 at 15:42
  • I'm afraid, I cannot offer you a very quick solution. The problem you are now encountering is described here: http://mathematica.stackexchange.com/questions/19656/distorted-graphics-when-using-custom-ticks-and-aspectratio-full . I'll add another piece of code to my answer, which avoids using AspectRatio->Full – LLlAMnYP Apr 20 '15 at 15:51
  • @LLIAMnYP, your EDIT2 resolves my problem! Thanks a lot! – Johny Apr 22 '15 at 09:42