1
$\begingroup$

I have the following code, stripped down from the original to the bare essentials:

numbers = Range@30;

Manipulate[Plot[a x^2 - b x^.3 + c x - d, {x, 0, 10}]

 , Grid[{
   {"a", "b", "c", "d"}
   , {Control[{{a, numbers[[3]], ""}, numbers, 
      ControlType -> RadioButtonBar, 
      Appearance -> "Horizontal" -> {Automatic, 6}}]
    , Control[{{b, numbers[[5]], ""}, numbers, 
      ControlType -> RadioButtonBar, 
      Appearance -> "Horizontal" -> {Automatic, 6}}]
    , Control[{{c, numbers[[7]], ""}, numbers, 
      ControlType -> RadioButtonBar, 
      Appearance -> "Horizontal" -> {Automatic, 6}}]
    , Control[{{d, numbers[[9]], ""}, numbers, 
      ControlType -> RadioButtonBar, 
      Appearance -> "Horizontal" -> {Automatic, 6}}]}
   }, Dividers -> {{2 -> True, 3 -> True, 4 -> True}, None}]
 ]

This looks like this:

enter image description here

All is working fine, however, the selection is clumsy, as I have the same selection pane four times. This might even get clumsier in the original, with more selections, and maybe even many more than four times. What I would like to have is the following (a pure mockup that is not working as I wish and describe below):

enter image description here

This should work as follow: Select a variable, e.g. b. Then select the parameter, in this case a number, for b, e.g. 5, using the number pane underneath. Then select another variable, e.g. c and select a number for this variable using the same number pane underneath, etc. In the actual version, the silly number pane will be replaced by a periodic table of elements, and elements are selected for various data presentation.

Addition-------- I probably should have made a more concrete example. So here is a stripped down version much closer to what I try to achieve:

data = {
   {"Mg", 3, 4, 2, 5}
   , {"Si", 6, 4, 7, 2}
   , {"Al", 2, 5, 2, 6}
   , {"Sr", 1, 5, 7, 8}
   };

a = Sort[ElementData[#, "AtomicNumber"] & /@ Range[40]];
elementsSorted = ElementData[#, "Symbol"] & /@ a;

Manipulate[
 posEl1 = Position[data, el1][[1, 1]];
 posEl2 = Position[data, el2][[1, 1]];
 posEl3 = Position[data, el3][[1, 1]];
 ListPlot[
  Transpose[{Rest@data[[posEl1]], 
    Rest@data[[posEl2]]/Rest@data[[posEl3]]}], 
  PlotRange -> {{0, 10}, {0, 10}}]

 , Grid[{
   {"x-Axis", "y-Axis nom", "y-Axis denom"}
   , {Control[{{el1, elementsSorted[[12]], ""}, elementsSorted, 
      ControlType -> RadioButtonBar, 
      Appearance -> "Horizontal" -> {Automatic, 6}}]
    , Control[{{el2, elementsSorted[[14]], ""}, elementsSorted, 
      ControlType -> RadioButtonBar, 
      Appearance -> "Horizontal" -> {Automatic, 6}}]
    , Control[{{el3, elementsSorted[[38]], ""}, elementsSorted, 
      ControlType -> RadioButtonBar, 
      Appearance -> "Horizontal" -> {Automatic, 6}}]}
   }, Dividers -> {{2 -> True, 3 -> True}, None}]
 ]

The result looks as shown below. As the very reduced dataset only includes 4 elements, only those can be selected to make the plot work. Now, what would be great is, to have a periodic table instead of the pane (actually this is what I would get working). The important bit is to have only one periodic table, and a selector as shown above, for which axis/nominator/denominator I want to select the element.

enter image description here

$\endgroup$
  • $\begingroup$ I guess four integer Manipulator[] controls does not fit the actual use-case? E.g., {a, 1, 30, 1, Appearance -> "Labeled"} etc. (Just checking, because the selector-type controls make the problem seem complicated, to the point of possible needing a custom control.) $\endgroup$ – Michael E2 Jun 29 '16 at 15:27
  • $\begingroup$ I'm not sure I understand the question. It is not important what controls are used. The main thing is to first select for which parameter (a,b,c or d) a variable (in this case a number) is chosen, then choose the actual value. Then do the same with the next variable. $\endgroup$ – Mockup Dungeon Jun 29 '16 at 15:38
  • 1
    $\begingroup$ Wouldn't 4 sliders accomplish that?: The user picks which slider to move (a, b, c, or d) and then chooses the actual value by moving the slider. $\endgroup$ – Michael E2 Jun 29 '16 at 15:48
  • 1
    $\begingroup$ I see your point. The thing is that this is a simplified example. Ultimately, I would want to use a periodic table or else instead of some plain numbers. So imagine a periodic table instead of the number pane. $\endgroup$ – Mockup Dungeon Jun 29 '16 at 18:00
  • 1
    $\begingroup$ Have you seen this? $\endgroup$ – J. M. will be back soon Jul 1 '16 at 17:05
3
$\begingroup$

Second try

Manipulate[
 Module[{x, yNum, yDen},
  {x, yNum, yDen} = {"x-Axis", "y-Axis num", "y-Axis den"} /. data;
  Pane["<your stuff here>"[x, yNum, yDen], {400, 100}]
  ],

 (* selector for axis categories *)
 {{axis, "x-Axis", "select"}, {"x-Axis", "y-Axis num", "y-Axis den"}, 
  SetterBar[
    Dynamic[axis, (axis = #; axiselement = Lookup[data, axis]) &], 
    First@#2, ##3] &},
 Row[{
   ColorData["Atoms", "Panel"] /. e_EventHandler :>
     (e /. {HoldPattern["MouseClicked" :> _] :>  (* replace mouse-click action *)
         ("MouseClicked" :> (axiselement = atomName[e]; data[axis] = axiselement)),
        r_Rectangle :>                           (* add dynamic style to elements *)
         {Dynamic[
           If[axiselement === atomName[e],
            {EdgeForm[Directive[Opacity[1], Thick, Red]], Opacity[0.6], r},
            {EdgeForm[None], r}
            ]]}})
   }],

 (* local variables *)
 {{axiselement, "Mg"}, None},  (* should be initialized to data[axis] *)
 {{data, (* data base for selected categories (axis) *)
   AssociationThread[{"x-Axis", "y-Axis num", "y-Axis den"} -> {"Mg", "Si", "Sr"}]}, None},

 (* options *)
 TrackedSymbols :> {data},
 Initialization :>   (* could add initialization of axis, axiselement, data *)
  (atomName[e_EventHandler] := First@Cases[e, Style[name_String, ___] :> name, Infinity, 1])
 ]

Mathematica graphics

First try

Probably too complicated, but also too cool (imho): Click on element at top. Move the slider to change its value in the table below.

Manipulate[
 datadisplay /. data,
 Dynamic[
  ColorData["Atoms", "Panel"] /. 
   e_EventHandler :> (e /. HoldPattern[
        "MouseClicked" :> _] :> 
          ("MouseClicked" :> (key = atomName[e]; value = Lookup[data, key])))
  ],
 {{key, "H"}, None},
 {{value, 0, Dynamic@key}, 0, 5, 1,
   Manipulator[Dynamic[value, (value = data[key] = #) &], ##2, Appearance -> "Labeled"] &},
 {{data, Association@ Thread[ColorData["Atoms", "ColorRules"][[All, 1]] -> 0]}, None},
 {{datadisplay, ColorData["Atoms", "Panel"] /. e_EventHandler :> First[e]}, None},
 TrackedSymbols :> {data},
 Initialization :>
  (atomName[e_EventHandler] :=
     First@Cases[e, Style[name_String, ___] :> name, Infinity, 1])
 ]

Mathematica graphics

Explanation coming...unless it's totally wrong.

$\endgroup$
  • $\begingroup$ It is cool – but not fully what I try to achieve. I made an edit to my initial question with a more concrete example. Anyway – thanks so far! $\endgroup$ – Mockup Dungeon Jun 30 '16 at 7:07
  • $\begingroup$ In the first version of the question, I interpreted a, b, c, d to represent the elements, which I see is wrong; now it seems they represent the axis/num/.den. (i.e., which category is chosen first), and there are only three choices instead of four -- is that right? $\endgroup$ – Michael E2 Jun 30 '16 at 13:53
  • 1
    $\begingroup$ The number of choices should be flexible, I.e. 3, 4, or even more. $\endgroup$ – Mockup Dungeon Jul 1 '16 at 14:29
  • $\begingroup$ As I understand it, then, you want a control that depends on a control that depends on another control (element selector dep. on choice of axis/etc. selector dep. on a control for the choices). I've shown how a control can depend on another control, maybe it's enough of a start? $\endgroup$ – Michael E2 Jul 1 '16 at 14:42
  • 1
    $\begingroup$ I guess you've seen this already... ;) $\endgroup$ – J. M. will be back soon Jul 1 '16 at 17:06

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.