4
$\begingroup$

I'm running into an issue with arranging Manipulate controls and a dynamic module around the content pane of the Manipulate. For example:

Manipulate[
 Plot[a b c x, {x, 0, 100}, PlotRange -> {0, 100}],
 {{a, 1}, 0, 2, Appearance -> "Labeled"},
 {{b1, 1}, 0, 2, Appearance -> "Labeled"},
 {{b2, 1}, 0, 2, Appearance -> "Labeled"},

 Dynamic[
  Plot[
   Sin[t], {t, 0, 10}, AspectRatio -> 1.5, ImageSize -> {200, 300}
   ]],

 {{b, 1, Row[{Spacer[300], "a"}]}, 0, 2, Appearance -> "Labeled"},
 {{c, 1}, 0, 2, Appearance -> "Labeled"},
 ContentSize -> {400, 260},

 ControlPlacement -> 
  Flatten[{Table[Left, {4}], Table[Bottom, {1}], Table[Right, {7}]}]
]

Imgur

I want the slider on the bottom, labeled "a" (oops, should have been b), to be sitting right underneath the content of the Manipulate (the linear graph). However, the dynamic module on the left-hand side, which is a plot of a sine function, seems to "push" the control further down than I want it to. How can I fix this?

$\endgroup$
3
$\begingroup$

I had to struggle with similar things before, and I found that the best way to control location of controls with respect to output they affect is to discard the whole Manipulate display area and do everything in the control area itself using Dynamics. This way you can control exactly where each slider/controller is located. This is done using basic Grid layout.

See this demo as an example of how this is done for more complicated layout

http://demonstrations.wolfram.com/DynamicAnalysisOfASecondOrderSystemWithHarmonicLoading/

Using your example:

Mathematica graphics

Manipulate[
 None,

 Grid[{
   {Grid[{
      {Control[{{a, 1, "a"}, 0, 2, .1, Appearance -> "Labeled", ImageSize -> Small}]},
      {Control[{{b1, 1, "b1"}, 0, 2, .1, Appearance -> "Labeled", ImageSize -> Small}]},
      {Control[{{b2, 1, "b2"}, 0, 2, .1, Appearance -> "Labeled", ImageSize -> Small}]},
      {Dynamic@Plot[Sin[a t], {t, 0, 10}, AspectRatio -> 1.5, ImageSize -> {200, 300}]}
      }, Frame -> All, FrameStyle -> Gray],
    Grid[{
      {Dynamic@Plot[a b c x, {x, 0, 100}, PlotRange -> {0, 100}, ImageSize -> 200]},
      {Control[{{b, 1, "b"}, 0, 2, .1, Appearance -> "Labeled", ImageSize -> Small}]}
      }, Frame -> All, FrameStyle -> Gray]
    ,
    Control[{{c, 1, "c"}, 0, 2, .1, Appearance -> "Labeled", ImageSize -> Small}]}
   }, Frame -> All, FrameStyle -> Gray, Alignment -> Top, Spacings -> {.5, .5}],

 SynchronousUpdating -> True, AppearanceElements -> "ManipulateMenu", 
 ControlPlacement -> Left, Alignment -> Center, ImageMargins -> 0, 
 FrameMargins -> 1, ContentSize -> {0}, SynchronousInitialization -> True, 
 ContinuousAction -> True, 
 Alignment -> Center, Paneled -> False, Frame -> False, 
 TrackedSymbols :> {a, b1, b2, c}
 ]

The idea is to use ContentSize -> {0} and just use the control area for everything else, and use standard Grid/Item and such to control where everything is located. The style of the background in the above can all be changed to make it appear as standard Manipulate content area as was done in the above demo.

$\endgroup$
  • $\begingroup$ Excellent! This looks just like what I was looking for. And you'd be able to adjust spacing etc... using Spacer[]'s and such. I've never tried to make a Manipulate in this way but will definitely try it out. Thanks Nasser! $\endgroup$ – madacho Feb 4 '14 at 18:33
3
$\begingroup$

I think you just have to experiment with adjusting the Sine plot. Here is what I got by doing a little trial and error work.

Manipulate[Plot[a b c x, {x, 0, 100}, PlotRange -> {0, 100}],
 {{a, 1}, 0, 2, Appearance -> "Labeled"},
 {{b1, 1}, 0, 2, Appearance -> "Labeled"},
 {{b2, 1}, 0, 2, Appearance -> "Labeled"},
 Dynamic[Plot[Sin[t], {t, 0, 10}, AspectRatio -> 1, ImageSize -> {200, 180}]],
 {{b, 1, Row[{Spacer[300], "b"}]}, 0, 2, Appearance -> "Labeled"},
 {{c, 1}, 0, 2, Appearance -> "Labeled"}, ContentSize -> {400, 260}, 
 ControlPlacement -> 
  Flatten[{Table[Left, {4}], Table[Bottom, {1}], Table[Right, {7}]}]]

manip.png enter image description here

$\endgroup$
  • $\begingroup$ I actually tried this before, but unfortunately my actual situation won't allow me to resize the plot. The real notebook has quite a few more sliders on the left-hand side, and the plot. So, there isn't really enough room to "fit" the plot within the height of the content pane. Is there a way to just snap the "Bottom" sliders to the actual bottom of the content pane? $\endgroup$ – madacho Feb 3 '14 at 20:01

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.