2
$\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$
5
  • $\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, 2016 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$ Jun 29, 2016 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, 2016 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$ Jun 29, 2016 at 18:00
  • 1
    $\begingroup$ Have you seen this? $\endgroup$ Jul 1, 2016 at 17:05

1 Answer 1

4
$\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$
9
  • $\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$ Jun 30, 2016 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, 2016 at 13:53
  • 1
    $\begingroup$ The number of choices should be flexible, I.e. 3, 4, or even more. $\endgroup$ Jul 1, 2016 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, 2016 at 14:42
  • 1
    $\begingroup$ I guess you've seen this already... ;) $\endgroup$ Jul 1, 2016 at 17:06

Your Answer

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

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