6
$\begingroup$

I would like to construct a nested Multipanel with SciDraw. That is, I want the first 5 elements of a 3x2 Multipanel grid to be regular plots, but the last element to be a Multipanel on its own. I hope my goal becomes clear from my attempts so far:

Needs["SciDraw`"]

First try: Nesting Multipanels

Figure[
 {Multipanel[
    {
     FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {1, 1}];
     FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {1, 2}];
     FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {1, 3}];
     FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {2, 1}];
     FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {2, 2}];
     FigurePanel[{
       Multipanel[{              
          FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {1, 1}, 
           XShowTickLabels -> True];
          FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {1, 2}];
          },
         Dimensions -> {1, 2},
         XPanelGaps -> .1
         ];
       },
      {2, 3},
      Frame -> False
      ];
     },
    Dimensions -> {2, 3},
    XPanelGaps -> .1,
    YPanelGaps -> .1
    ];
  },
 CanvasSize -> {5, 3.5}
 ]

enter image description here

Problem here: I can't set tick or axes labels on the two plots at position {3,2}. It seems that the Frame->False of the outer FigurePanel erases anything outside the frame. Also, the outer frame edges seem thinner in the nested multipanel.

Second try: Manual stacking of two Multipanels

Figure[
 {Multipanel[
   {
    FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {1, 1}];
    FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {1, 2}];
    FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {1, 3}];
    },
   Dimensions -> {1, 3},
   XPanelGaps -> .1,
   PanelRegion -> Scaled[{{0, 1}, {0.55, 1}}]
   ];
  Multipanel[{
    FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {1, 1}];
    FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {1, 2}];
    FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {1, 3}];
    FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {1, 4}];
    },
   Dimensions -> {1, 4},
   XPanelGaps -> {.13, 0.13, 0.07},
   XPanelSizes -> {4/3, 4/3, 1, 0.3},
   PanelRegion -> Scaled[{{0, 1}, {0, 0.45}}]
   ];
  },
 CanvasSize -> {5, 3.5}
 ]

enter image description here

Problem here: The vertical alignment and horizontal size adjustment between the top and the bottom row needs to be done manually and is never precise.

Question:

How can I properly define a nested multipanel? That is, how can I combine a mathematically precise alignment of the panels with a full flexibility to use tick and axes labels?

I'm specifically looking for solutions using SciDraw.

$\endgroup$
1
$\begingroup$

I just come across this question when I encountered the same question. After skimming the manual, I think I have found the solution on both your first and second try. I also used a third way to implement this kind of irregular grids(or nested multipanels in your language).

Modification to your first try:

Basically, the idea is correct. But to implement it, we need to achieve : (1) show individual frame label in multipanel (2) suppress the output of exterior frame label in FigurePanel where the inset multipanel is at.

The solution to the first issue can be found here How to do individual axis labeling with use SciDraw multipanel figures?. Basically, we need to add ShowFrameLabel -> True in Multipanel.

The solution to the second issue can be found in the SciDrawGuide.pdf in Page 93. (I am using version 0.0.7, the latest release till now) The option is Clip->False. According to the user's guide, it says

However, with Clip->False, graphics will be allowed to extend out to the edge of the canvas

Therefore, we can set Clip->False to allow the inset multipanel to plot outside the corresponding FigurePanel.

The rest of the adjustments are trivial.

In short, the complete code will look like(I also make the gaps larger in order to fit the frame labels):

Figure[{Multipanel[{FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {1,
        1}];
     FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {1, 2}];
     FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {1, 3}];
     FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {2, 1}];
     FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {2, 2}];
     FigurePanel[{Multipanel[{FigurePanel[{FigGraphics[
             Plot[x, {x, 0, 1}]]}, {1, 1}, XShowTickLabels -> True, 
           XTicks -> LinTicks[0, 1, .5, 5], 
           YTicks -> LinTicks[0, 1, .5, 5]];

          FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {1, 2}, 
           XTicks -> LinTicks[0, 1, .5, 5], 
           YTicks -> LinTicks[0, 1, .5, 5], 
           YShowTickLabels -> True];}, Dimensions -> {1, 2}, 
         XPanelGaps -> .3, ShowFrameLabel -> True];}, {2, 3}, 
      Frame -> False, Clip -> False, PanelLetter -> None];}, 
    Dimensions -> {2, 3}, XPanelGaps -> .2, YPanelGaps -> .1];}, 
 CanvasSize -> {5, 3.5}]

Output of *first* method

Modification to your second try is to use two sets of grid(multipanel array) with allowing empty panel. This is already addressed in @Max answer.

The third way:

This is mentioned in Sec 10.2 Page 98, where you can use RegionExtension and RegionDisplacement to manipulate each single panel. In this case, you may create a 2*4 grid and extend the panel at (1,3) to (1,4) while leaving (1,4) empty. To make equal width, XPanelSizes should be {1,1,.5,.5}.

The code will be like:

fig3 = Figure[{Multipanel[{
     FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {1, 1}];
     FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {1, 2}];
     FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {1, 3}, 
      RegionExtension -> {.35, 0}, RegionDisplacement -> {.35, 0}];
     FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {2, 1}];
     FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {2, 2}];
     FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {2, 3}, 
      XTicks -> LinTicks[0, 1, .5, 5], 
      YTicks -> LinTicks[0, 1, .5, 5], YShowTickLabels -> True];
     FigurePanel[{FigGraphics[Plot[x, {x, 0, 1}]]}, {2, 4}, 
      XTicks -> LinTicks[0, 1, .5, 5], 
      YTicks -> LinTicks[0, 1, .5, 5], YShowTickLabels -> True];
     }, Dimensions -> {2, 4}, XPanelGaps -> .2, YPanelGaps -> 0.2, 
    XPanelSizes -> {1, 1, .5, .5}, ShowFrameLabel -> True]}, 
  CanvasSize -> {5, 3.5}]

enter image description here

Other adjustments like PanelLetter and FrameTextNudge can be easily assigned in each FigurePanel.

P.S. In the documentation, it is said Clip is "under development and subject to change". So IMHO I assume the third way is more preferred by the intention of the author.

$\endgroup$
1
$\begingroup$

@Felix: I use SciDraw's predecessor LevelScheme. However, it may be that some of this code is useful.

I'm unhappy with the magic numbers, (ps, pa), but neverthless offer:

Manipulate[
 Figure[{
   SetOptions[SchemeObject, FontFamily -> "Helvetica LT Std", 
    FontSize -> 08],
   ScaledLabel[{.5, .97}, "Title", FontSize -> 12, 
    FontWeight -> Bold, Offset -> {0, 0}],
   ScaledLabel[{.5, .945}, "subtitle", FontSize -> 10, 
    Offset -> {0, 0}],
   Multipanel[{{0, 1}, {0, 1}},
    {2, 4},
    XPlotRanges -> {0, 1},
    YPlotRanges -> {0, 1},
    XFrameLabels -> {"x1", "x2", "x3", "x4"},
    BufferB -> 5,
    YFrameLabels -> {"y1", "y2"}, 
    BufferL -> 7,
    XFrameTicks -> {LinTicks[0, 1, 1, 1], LinTicks[0, 1, 1, 1], 
      LinTicks[0, 1, 1, 1], LinTicks[0, 1, 1, 1]},
    YFrameTicks -> {LinTicks[0, 1, 1, 1], LinTicks[0, 1, 1, 1]},
    XGapSizes -> .05, YGapSizes -> .1,
    XPanelSizes -> {1, 1, 1, .25},
    YPanelSizes -> {1, 1},
    First -> "A",
    Order -> Vertical
    ],
   FigurePanel[{1, 1}, ShowPanelLetter -> True],
   FigurePanel[{1, 2}, ShowPanelLetter -> True],
   FigurePanel[{1, 3}, ShowPanelLetter -> True, PanelShift -> {ps, 0},
     PanelAdjustments -> {{pa, 0}, {0, 0}}],
   FigurePanel[{2, 1}, ShowPanelLetter -> True],
   FigurePanel[{2, 2}, ShowPanelLetter -> True],
   FigurePanel[{2, 3}, ShowPanelLetter -> True],
   FigurePanel[{2, 4}, ShowPanelLetter -> True]
   },
  ImageSize -> (1*72) *  {PAGEWIDTH, PAGEWIDTH/Sqrt[2]}
  ],
 {{ps, .2, "Shift"}, 0, .5, .01},
 {{pa, .2, "Adj"}, 0, .5, .01}
 ]

The thin right frame in Panel H is a result of moving it too far towards the right.

enter image description here

$\endgroup$
  • $\begingroup$ Thanks for the code. Could you post a picture of the output, since it does not run with SciDraw? Thanks! $\endgroup$ – Felix Jul 24 '17 at 3:05
  • $\begingroup$ Thanks, now I understand your idea. Definitely +1. But the problem is the manual adjustment of panel E, which I would prefer to automate. Let's see if someone else has another idea. $\endgroup$ – Felix Jul 24 '17 at 4:21
1
$\begingroup$

I think I have your answer!

You just use two canvas-sized Multipanels with different grids. Empty grid spaces are allowed. In your example, the first five plots would be on a 2x3 grid, and the last two plots would be on a 2x6 grid. Here's my code (with some styling to prevent issues):

fooPlot = Plot[x, {x, 0, 1}, PlotRange -> {{0, 1}, {0, 1}}];

DefineStyle["fooStyle", {FigurePanel -> {XPlotRange -> {0, 1}, 
    YPlotRange -> {0, 1}, YTickLabelRange -> {0.2, 1}, 
    FrameLabel -> None}}]

Figure[{
  Multipanel[{

    FigurePanel[{FigGraphics[fooPlot];}, {1, 1}, PanelLetter -> "(a)"];
    FigurePanel[{FigGraphics[fooPlot];}, {1, 2}, PanelLetter -> "(b)"];
    FigurePanel[{FigGraphics[fooPlot];}, {1, 3}, PanelLetter -> "(c)"];
    FigurePanel[{FigGraphics[fooPlot];}, {2, 1}, PanelLetter -> "(d)"];
    FigurePanel[{FigGraphics[fooPlot];}, {2, 2}, PanelLetter -> "(e)",
      XTickLabelRange -> {0.2, 1}];

    },
   Dimensions -> {2, 3},
   XPanelGaps -> 0.1,
   YPanelGaps -> 0.1
   ];

  Multipanel[{

    FigurePanel[{FigGraphics[fooPlot];}, {2, 5}, PanelLetter -> "(f)"];
    FigurePanel[{FigGraphics[fooPlot];}, {2, 6}, PanelLetter -> "(g)"];

    },
   Dimensions -> {2, 6},
   XPanelGaps -> 0.2, (* this should be n times bigger than XPanelGaps for the first Multipanel, where n is how much smaller the panel sizes are, which is proportional to Dimensions. So here, 6/3=2 times bigger. *)
   YPanelGaps -> 0.1,
   XTicks -> None
   ];

  },
 CanvasSize -> {3, 2}*3,
 Style -> "fooStyle"
 ]

enter image description here

If you want any panels to be different sizes, you can use XPanelSizes->{list of widths}.

$\endgroup$
  • $\begingroup$ Can you make the combined panels (f)+(g) the exact same size as panel (c)? $\endgroup$ – Felix Feb 23 at 4:13
  • $\begingroup$ @Felix Ah huh I hadn’t noticed that. It seems XPanelGaps defaults to different values for the two grids. Just set XPanelGaps->0.1 (or your desired value) for both grids and the panel sizes should match up, with all horizontal gaps between panels equal. $\endgroup$ – Max Feb 24 at 6:39
  • $\begingroup$ Can you demonstrate what you mean? If I'm not mistaken, your code already includes XPanelGaps->0.1 for both panels and the graphs do not align. $\endgroup$ – Felix Feb 24 at 19:29
  • $\begingroup$ @Felix, you're right, I didn't realize XPanelGaps was relative, not absolute. I've fixed it by making the second XPanelGaps->0.2 instead of 0.1. If you decide to play around with XPanelSizes, you may need to adjust XPanelGaps more to make it look good. $\endgroup$ – Max Feb 26 at 21:11
  • 1
    $\begingroup$ Looks great! Even if it has not all the power of really including a sub-multipanel (like easily changing dimensions and spacing within the sub-panel), I'll accept this as the proper answer. $\endgroup$ – Felix Feb 28 at 0:20

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.