8
$\begingroup$

I am attempting to dynamically horizontally center a button above the plot window in a manipulate. For example,

Manipulate[Plot[Sin[x], {x, 1, 4}],
 Row[{Spacer[20],Button["A"]}]]

I know I can use Spacer[] to move the button to right a set amount, however, I would like a solution that dynamically centers the button so that when I manually changed the size of the plot window, the button dynamically horizontally centers itself.

enter image description here

It seems like I would need access to the size of the plot window as it changes, but I'm not sure how to get at that information. Any ideas?

$\endgroup$
3
  • $\begingroup$ Cham asked a follow-up question at the bottom of this post but no solution was offered. mathematica.stackexchange.com/questions/108891/… $\endgroup$
    – B flat
    Dec 20, 2021 at 11:34
  • $\begingroup$ From the underlying cell structure... it looks like I need to get at the ImageSizeCache for the plot window. But not sure how to access it. $\endgroup$
    – B flat
    Dec 20, 2021 at 11:47
  • $\begingroup$ This Row[{Spacer[ImageDimensions[g][[1]]/2], Button["A"]}] where g = Plot[Sin[x], {x, 1, 4}] is not really a solution, since it´, indeed, places that button centered, but does not react dynamically. $\endgroup$ Dec 20, 2021 at 12:10

1 Answer 1

9
$\begingroup$

We make plot image size a control variable and use the (undocumented) Method option "ControlAreaDisplayFunction" to adjust the horizontal size of the display area. The display area content is wrapped in Pane with the option Alignment -> {Center, Center} to make display area content stay centered.

Manipulate[Plot[x Sin[x], {x, 0, 2 Pi}, PlotStyle -> color, 
  ImageSize -> Dynamic[imagesize]],
 {{color, Red}, None},
 Button["A", color = color /. {Red->Green, Green->Red}, 
    ImageSize -> {Scaled[.1], Automatic}],
 {{imagesize, {300, 250}}, None}, 
 Method -> {"ControlAreaDisplayFunction" ->
    (Dynamic @ Pane[#, Alignment -> {Center, Center}, 
        ImageSize -> {First @ imagesize, Automatic}] &)}]

enter image description here

Manipulate[Plot[x Sin[a x + b], {x, 0, 2 Pi}, PlotStyle -> color, 
  ImageSize -> Dynamic[imagesize]], 
 Column[{Column[{Control@{a, -1, 1}, 
        Control@{b, {1, 2, 3} Pi/4},
        Control @ {{color, Red}, ColorSlider}}],
      Button["A", color = Darker @ color, ImageSize -> {30, Automatic}]}, 
  Alignment -> Center],
 {{imagesize, {300, 250}}, None}, 
 Method -> {"ControlAreaDisplayFunction" -> 
    (Dynamic @ Pane[#, Alignment -> {Center, Center}, 
        ImageSize -> {First @ imagesize, Automatic} &)}]

enter image description here

$\endgroup$
5
  • 1
    $\begingroup$ All this trouble because ControlPlacement does not allow position specifications like {{Top, Center}}, {{Top, Right}}, {{Right, Center}}, {{Right, Bottom}} etc. $\endgroup$
    – kglr
    Dec 20, 2021 at 15:29
  • 2
    $\begingroup$ Awesome! It does seem like this should be built in. Control placement is pretty important. $\endgroup$
    – B flat
    Dec 20, 2021 at 15:34
  • 1
    $\begingroup$ @kglr, How imagesize does know that it should take the value of the size of Plot? $\endgroup$
    – Rom38
    Dec 21, 2021 at 11:26
  • $\begingroup$ @Rom38, great question! Actually, I did not know that it would work. I had a hunch (based on having seen before that ViewPoint -> Dynamic[vp] tracks viewpoint as we interactively change a 3D graphics object) that it might; tried a simple example ( is = 300; Graphics[{Disk[]}, ImageSize -> Dynamic[is], PlotLabel -> Dynamic[is]]) and saw that it worked:) $\endgroup$
    – kglr
    Dec 21, 2021 at 12:03
  • $\begingroup$ @KGLR, MYstic mma :) $\endgroup$
    – Rom38
    Dec 21, 2021 at 17:58

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.