4
$\begingroup$

I have a set of 9 plots which should be combined into one plot. Each of these plots contains a ListContourPlot, some circles, lines and an Inset containing again a circle, some arrows and some text:

enter image description here

I already tried to use Levelscheme mentioned in this Question: https://stackoverflow.com/questions/5818888/how-to-make-a-grid-of-plots-with-a-single-pair-of-framelabels

In my first attempts with a dummy ContourPlot function it worked pretty fine, but as I tried to use it with my plots it got totally confused:

enter image description here

I think the custom drawn lines/circles are the problem. I used pretty much the same code shown in the thread above:

Get["LevelScheme`"]

Figure[{Multipanel[{{0, 1}, {0, 1}}, {3, 3},
(*XFrameLabels->Text["x [mm]"],
YFrameLabels->Text["y [mm]"],*)
BufferB -> 3,
BufferL -> 3,
TickFontSize -> 18,
FontSize -> 18,
FontFamily -> "FrontPage",
XGapSizes -> 0,(*Abstände zwischen Plots*)
YGapSizes -> 0,
ExtendRange -> 0.05,(*erhöht Raum innerhalb des Frames*)
PanelLetterCorner -> {0.98, 1},
ShowTickLabelsExterior -> {True, True, False, False},
ShowPanelLetter -> False
],

FigurePanel[{1, 1}, PlotRange -> {{-range, range}, {-range, range}}],
RawGraphics[fullAngle[[1, 1]]],
FigurePanel[{1, 2}, PlotRange -> {{-range, range}, {-range, range}}],
RawGraphics[fullAngle[[1, 2]]],
FigurePanel[{1, 3}, PlotRange -> {{-range, range}, {-range, range}}],
RawGraphics[fullAngle[[1, 3]]],
FigurePanel[{2, 1}, 
PlotRange -> {{-range, range}, {-range, range}}, LabL -> Text["y [mm]"]],
RawGraphics[fullAngle[[2, 1]]],
FigurePanel[{2, 2}, PlotRange -> {{-range, range}, {-range, range}}],
RawGraphics[fullAngle[[2, 2]]],
FigurePanel[{2, 3}, PlotRange -> {{-range, range}, {-range, range}}],
RawGraphics[fullAngle[[2, 3]]],
FigurePanel[{3, 1}, PlotRange -> {{-range, range}, {-range, range}}],
RawGraphics[fullAngle[[3, 1]]],
FigurePanel[{3, 2}, 
 PlotRange -> {{-range, range}, {-range, range}}, LabB -> Text["x [mm]"]],
RawGraphics[fullAngle[[3, 2]]],
FigurePanel[{3, 3}, PlotRange -> {{-range, range}, {-range, range}}],
RawGraphics[fullAngle[[3, 3]]]

},
PlotRange -> {{-0.08, 1.01}, {-0.15, 1.01}},
ImageSize -> 600
]

In a second attempt I found this thread: Do I have to code each case of this Grid full of plots separately?

Also the posted function in Jens' answer works mostly pretty well. The only point is, that it also gets confused by the Inset-s in my graphs; the result looks like:

enter image description here

So my questions are:

Is it possible to use Levelscheme with my existing graphs, without modifying/redrawing them? Or is it possible to alter Jens' algorithm to make it fit to my insets?

Or: any other suggestion, that lets me create the desired set of graphs.

EDIT 1:

you can easily reproduce the graph with the following code:

 AngleInset[\[Alpha]_] := Show[Graphics[{Thick, Circle[]}],
  Graphics[{ { Black, Thick, Arrowheads[Large], 
  Arrow[{{0, 0}, {1.1, 0}}]}, {Black, Thick, Arrowheads[Large], 
  Arrow[{{0, 0}, {0, 1.1}}] }}],
 Graphics[{Thick, Circle[{0, 0}, 0.5, {0, (-\[Alpha] Degree)}]}],
 Graphics[{Red, Thick, Arrowheads[Large], 
 Arrow[{{0, 0}, {Cos[-\[Alpha] Degree], Sin[-\[Alpha] Degree]}}]}],
 Graphics[
 Style[Text[
  ToString[-\[Alpha] ] <> "\[Degree]", {0, -0.5}, {0, 0} ], 24]],
 Frame -> True,
 FrameTicks -> False
 ];

ContourPlot[Sin[x]²+Cos[y]^2, {x, 0, 2 Pi}, {y,0,2Pi},
Epilog -> 
Inset[AngleInset[90], {Right, Top}, {Right, Top}, 6, 
Background -> White]]
$\endgroup$
5
  • $\begingroup$ LevelScheme might not be the best option here, because it handles the coordinates a bit differently, and with a superposition of multiple plots with insets, it'll probably go haywire. I think it would be far easier to modify Jens' solution. Notice that only the insets in the plots along the top and right edge are messed up. My guess is this is easy to fix (but I haven't looked at his code in detail yet). Please include the definitions for your plots (with insets) or at least for a single frame which can then be repeated. $\endgroup$
    – rm -rf
    Oct 15, 2012 at 16:17
  • $\begingroup$ you can easily reproduce the graph with the following code: ContourPlot[Sin[x]²+Cos[y]^2, {x, 0, 2 Pi}, {y,0,2Pi}, Epilog -> Inset[AngleInset[90], {Right, Top}, {Right, Top}, 6, Background -> White] $\endgroup$
    – Christian
    Oct 15, 2012 at 18:32
  • $\begingroup$ What's wrong with a simple GraphicsGrid? $\endgroup$
    – wxffles
    Oct 15, 2012 at 20:49
  • $\begingroup$ a graphicsgrid generates a little space between each graph and its a high effort to fine tune the ticks for every graph $\endgroup$
    – Christian
    Oct 15, 2012 at 21:52
  • $\begingroup$ Would you please include the full code for this graphic? i.stack.imgur.com/Ptfsx.png $\endgroup$
    – Mr.Wizard
    Oct 15, 2012 at 22:48

1 Answer 1

1
$\begingroup$

The reason my solution referenced above got confused is that the Inset in your plot has its position specified in scaled coordinates. These coordinates refer to the size of the enclosing graphic including the space created by ImagePadding. In my plotGrid function, I change that setting for ImagePadding and this moves the inset around.

I was able to make your example work by simply changing one thing: in your ContourPlot, replace the position argument of the Inset by an absolut plot coordinate. Here is what that looks like:

AngleInset[\[Alpha]_] := 
  Show[Graphics[{Thick, Circle[]}], 
   Graphics[{{Black, Thick, Arrowheads[Large], 
      Arrow[{{0, 0}, {1.1, 0}}]}, {Black, Thick, Arrowheads[Large], 
      Arrow[{{0, 0}, {0, 1.1}}]}}], 
   Graphics[{Thick, Circle[{0, 0}, 0.5, {0, (-\[Alpha] Degree)}]}], 
   Graphics[{Red, Thick, Arrowheads[Large], 
     Arrow[{{0, 0}, {Cos[-\[Alpha] Degree], 
        Sin[-\[Alpha] Degree]}}]}], 
   Graphics[
    Style[Text[ToString[-\[Alpha]] <> "\[Degree]", {0, -0.5}, {0, 0}],
      24]], Frame -> True, FrameTicks -> False];


c = ContourPlot[Sin[x]^2 + Cos[y]^2, {x, 0, 2 Pi}, {y, 0, 2 Pi}, 
   Epilog -> 
    Inset[AngleInset[90], {2 Pi, 2 Pi}, {Right, Top}, 2, 
     Background -> White]
   ];

Options[plotGrid] = {ImagePadding -> 40};
plotGrid[l_List, w_, h_, opts : OptionsPattern[]] := 
 Module[{nx, ny, sidePadding = OptionValue[plotGrid, ImagePadding], 
   topPadding = 0, widths, heights, dimensions, positions, 
   frameOptions = 
    FilterRules[{opts}, 
     FilterRules[Options[Graphics], 
      Except[{ImagePadding, Frame, FrameTicks}]]]}, {ny, nx} = 
   Dimensions[l];
  widths = (w - 2 sidePadding)/nx Table[1, {nx}];
  widths[[1]] = widths[[1]] + sidePadding;
  widths[[-1]] = widths[[-1]] + sidePadding;
  heights = (h - 2 sidePadding)/ny Table[1, {ny}];
  heights[[1]] = heights[[1]] + sidePadding;
  heights[[-1]] = heights[[-1]] + sidePadding;
  positions = 
   Transpose@
    Partition[
     Tuples[Prepend[Accumulate[Most[#]], 0] & /@ {widths, heights}], 
     ny];
  Graphics[
   Table[Inset[
     Show[l[[ny - j + 1, i]], 
      ImagePadding -> {{If[i == 1, sidePadding, 0], 
         If[i == nx, sidePadding, 0]}, {If[j == 1, sidePadding, 0], 
         If[j == ny, sidePadding, topPadding]}}, AspectRatio -> Full],
      positions[[j, i]], {Left, Bottom}, {widths[[i]], 
      heights[[j]]}], {i, 1, nx}, {j, 1, ny}], 
   PlotRange -> {{0, w}, {0, h}}, ImageSize -> {w, h}, 
   Evaluate@Apply[Sequence, frameOptions]]]

pt = Array[c &, {3, 3}];

plotGrid[pt, 1000, 1000]

plot grid

I had to choose a large image dimension 1000 times 1000 to get the inset scaled in an acceptable proportion. Also, I had to change the size of the Inset in your example plot (called c above) to a smaller number.

$\endgroup$
1
  • $\begingroup$ Thank you Jens, this helps me very much. I think I'll be able to fix the Inset stuff by myself. $\endgroup$
    – Christian
    Oct 16, 2012 at 13:17

Your Answer

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

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