Consider the following arbitrary figure generated in MATLAB as an example. The basic idea is that I have a contour plot and I want to showcase selected slices from it in subplots on the right. Is there an equivalent of subplot in mma?
The work around that I have right now is to have just the contour plot with the slices and the arrows and the two slice-plots separately and then put them together in latex. However, I'd like to be able to do this within mma. How do I go about doing this?
An idea that I had is to generate a the contour plot with a full vertical & half horizontal aspect ratio, the two plots with half vertical & half horizontal aspect ratio, and then use GraphicsGrid
to align them up. But this still gave me the plots as a list, not a composite figure. Is this the only way or is there a nicer, more elegant way of doing it?
I know that Multipanel
in LevelScheme can probably let you do what you want - but I don't have much experience with it and the examples in the docs are fairly sparse.
I've already pasted one of the examples into this SO answer, so have a look there and see what you think!
Here's my attempt with GraphicsGrid
.
The thing that Multipanel
lets you do but GraphicsGrid
doesn't
is to let you use varying Column/Row sizes.
This means that I struggled to get the arrows drawn in programmatically, and resorted to hand drawing them using the "Drawing Tools" panel ( :D )
With[{yslice1 = .5, yslice2 = -.8},
GraphicsGrid[
{{DensityPlot[Sin[15 x y], {x, -1, 1}, {y, -1, 1},
ColorFunction -> "PlumColors", AspectRatio -> 2,
Epilog -> {Dashed, White, Line[{{-1, yslice1}, {1, yslice1}}],
Line[{{-1, yslice2}, {1, yslice2}}]}],
Plot[Sin[15 x yslice1], {x, -1, 1}, Axes -> False, Frame -> True]},
{SpanFromAbove,
Plot[Sin[15 x yslice2], {x, -1, 1}, Axes -> False,
Frame -> True]}},
Spacings -> {Scaled[0.2], Scaled[0.0]}]]
Edit:
Here's the same thing using LevelScheme
, note that the frames line up.
It should be possible to add arrows - since LevelScheme
has lots of new arrow directives - but I'll leave that as a homework problem!
<< "LevelScheme`"
{yslice1 = .5, yslice2 = -.8};
Figure[{
SetOptions[Multipanel,
ShowTickLabels -> {True, False, False, True}, Background -> Wheat,
PanelLetterFontSize -> 10, Margin -> {{40, 40}, {40, 0}}],
Multipanel[{{0, 1}, {0, 1}}, {2, 2},
XPlotRanges -> {-1, 1}, YPlotRanges -> {-1, 1},
XFrameLabels -> textit["x"], YFrameLabels -> textit["y"],
TickFontSize -> 10, XFrameTicks -> LinTicks[-1, 1, .5, 4],
YFrameTicks -> LinTicks[-1, 1, .5, 4],
BufferL -> 1.5, BufferB -> 3, Order -> Vertical,
XPanelSizes -> {1, 1}, XGapSizes -> 0.25, YGapSizes -> 0.2],
FigurePanel[{1, 2}],
RawGraphics[
Plot[Sin[15 x yslice1], {x, -1, 1}, Axes -> False, Frame -> True]],
FigurePanel[{2, 2}],
RawGraphics[
Plot[Sin[15 x yslice2], {x, -1, 1}, Axes -> False, Frame -> True]],
FigurePanel[{2, 1}, PanelAdjustments -> {{0, 0}, {0, +1.2}}],
RawGraphics[
DensityPlot[Sin[15 x y], {x, -1, 1}, {y, -1, 1},
ColorFunction -> "PlumColors", AspectRatio -> 2],
Graphics[{Dashed, Thick, White,
Line[{{-1, yslice1}, {1, yslice1}}],
Line[{{-1, yslice2}, {1, yslice2}}]}]]},
PlotRange -> {{0, 1}, {0, 1}}, ImageSize -> 2*72*{5, 3}
]
Re the OPs comment about GraphicsGrid, you can use FullGraphics@GraphicsGrid@{...} to get a single graphics object out. This is necessary to get copy as PDF to work also.
Here is a first pass at making Simon's solution dynamic. The arrows are hard coded for this particular image. Later I shall try to implement them more generally.
dp1 = DensityPlot[Sin[15 x y], {x, -1, 1}, {y, -1, 1},
ColorFunction -> "PlumColors", AspectRatio -> 2, PlotPoints -> 30];
Manipulate[
Show[
GraphicsGrid[{{dp1 ~Append~
(Epilog -> {Dashed, White,
Line[{{-1, yslice1}, {1, yslice1}}],
Line[{{-1, yslice2}, {1, yslice2}}]}),
Plot[Sin[15 x yslice1], {x, -1, 1}, Axes -> False,
Frame -> True]}, {SpanFromAbove,
Plot[Sin[15 x yslice2], {x, -1, 1}, Axes -> False,
Frame -> True]}}, Spacings -> {Scaled[0.2], Scaled[0.0]}],
Graphics[{Red, {Arrowheads[Large],
Arrow[{{380, Rescale[yslice1, {-1, 1}, {-646, -46}]}, {440, -170}}],
Arrow[{{380, Rescale[yslice2, {-1, 1}, {-646, -46}]}, {440, -530}}]
}}],
ImageSize -> 600
],
{{yslice1, 0.5, "Slice 1"}, -1, 1},
{{yslice2, -0.8, "Slice 2"}, -1, 1}
]
Here is a slightly different method that puts the arrows inside Epilog
, which links their position to the left plot, perhaps easier to use.
dp1 = DensityPlot[Sin[15 x y], {x, -1, 1}, {y, -1, 1},
ColorFunction -> "PlumColors", AspectRatio -> 2, PlotPoints -> 30,
PlotRangeClipping -> False,
ImagePadding -> {{Automatic, 100}, {Automatic, Automatic}}];
Manipulate[
Show[
GraphicsGrid[{{dp1~
Append~(Epilog -> {{Dashed, White,
Line[{{-1, yslice1}, {1, yslice1}}],
Line[{{-1, yslice2}, {1, yslice2}}]}, {Red,
Arrowheads[Large],
Arrow[{{1, yslice1}, {1.7, 0.88}}],
Arrow[{{1, yslice2}, {1.7, -0.9}}]
}}),
Plot[Sin[15 x yslice1], {x, -1, 1}, Axes -> False,
Frame -> True]}, {SpanFromAbove,
Plot[Sin[15 x yslice2], {x, -1, 1}, Axes -> False,
Frame -> True]}}, Spacings -> {Scaled[-0.2], Scaled[0.0]}],
ImageSize -> 600
],
{{yslice1, 0.5, "Slice 1"}, -1, 1},
{{yslice2, -0.8, "Slice 2"}, -1, 1}
]
来源:https://stackoverflow.com/questions/5429204/how-do-i-create-subplots-in-mathematica-using-levelscheme