Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a function that operates on a list of parameters of variable-length $n$. I would like to create a Manipulate[] that has $n$ sliders, one for each list element, each considered a separate parameter. The syntax Manipulate[expr,{u,...},{v,...},...]] does not lend itself to this, as it is geared toward a fixed number of parameters known in advance, and referenced by separate variable names.

I have started exploring preparing a list of arguments to Manipulate[] and then using Apply[], but this seems tricky and complicated.

Anyone come upon this conundrum before?

share|improve this question
2  
See a related SO thread. –  Eli Lansey Feb 2 '12 at 20:35

3 Answers 3

up vote 24 down vote accepted

The Advanced Dynamic Functionality in Mathematica documentation has the following example that looks like what you need.

DynamicModule[{n = 5, data = Table[RandomReal[], {20}]},
Column[{
Slider[Dynamic[n], {1, 20, 1}],
Dynamic[Grid[Table[With[{i = i},
   {Slider[Dynamic[data[[i]]]], Dynamic[data[[i]]]}], {i, n}]
 ]]}]]

nested sliders

It builds a list of controllers (Slider-s in this particular case) by using the fact that you can assign values to not just symbols but also to members of a list by doing data[[1]] = value. Which is exactly the thing that happens inside Dynamic[data[[i]]], as it is equivalent to:

Dynamic[data[[i]], (data[[i]] = #)&]

telling Mathematica to whenever the actual value of data[[i]] is changed, use the new value (#) to update the expression data[[i]].

Also from the Documentation Center, the last example in Manipulate: Neat Examples may be useful:

Manipulate[
ArrayPlot[
Take[data, h, w]], {{data, RandomInteger[{0, 1}, {10, 20}]}, 
ControlType -> None}, {{h, 5}, 1, 10, 1}, {{w, 5}, 1, 20, 1}, 
Dynamic[Panel[
 Grid[Outer[Checkbox[Dynamic[data[[#1, #2]]], {0, 1}] &, Range[h], 
 Range[w]]]]]]

which gives

enter image description here

share|improve this answer
    
This is very helpful---Thanks so much! –  Joseph O'Rourke Feb 2 '12 at 19:42
    
@Joseph, glad the link was helpful. –  kguler Feb 2 '12 at 19:53

Here is a followup to my question, code based on the example provided by kguler. Note there is no longer any need for Manipulate[]— it is all handled by Dynamic[].

data = Table[RandomReal[], {5}];

DynamicModule[ {n = Length[data]},

 Column[{

   Dynamic[
    Grid[
     Table[
      With[{i = i},
       {i,
        Slider[Dynamic[data[[i]]]],
        Dynamic[data[[i]]]
        }
       ],
      {i, n}
      ](*Table*)
     ]],(*Dynamic*)

   Dynamic[ListPlot[data, Joined -> True]]

   }, Center](*Column*)
 ]


     enter image description here

share|improve this answer

This is similar to kguler's solution, but it assumes that there is a more complex updating going on during slider-interaction (namely, both list and total are updated), to illustrate more realistic cases where a single Dynamic object might affect more than one variables. Also it shows how to use Map with a variable number of Slider-s. For localization and elegance, the whole code should be wrapped into DynamicModule, but since this is not the point here, I omitted.

update[n_] := (list = Table[0, {n}]; total = Total@list); (* function called when n is changed *)

n = 5;
update[n]; (* initialize list and total *)

Slider[Dynamic[n, (n = #; update[#]) &], {1, 10, 1}]

Dynamic[total]

Dynamic[Grid[
  {
   #,
   Slider[Dynamic[list[[#]], 
       Function[{x}, list[[#]] = x; total = Total@list]], {0, 1}], 
   Dynamic[list[[#]]]
  } & /@ Range[n]
  ], TrackedSymbols :> {n}]

Mathematica graphics

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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