2
$\begingroup$

This question already has an answer here:

I want to change the slot number inside Manipulate[]. Here is a minimal example which does not work:

Manipulate[Sin[#n] & [0, Pi/2], {n, Range[2]}]

I expect an output of 0 when n=1 and 1 when n=2 (sine evaluated at n-th argument).

I've also tried Slot[n], # n but they do not work either. I couldn't find any similar question.

How would you make it?

EDIT 1

Kuba's answer

Manipulate[Evaluate@Sin[Slot[n]] &[0, Pi/2], {{n, 1}, Range[2]}]

works for the minimal example. In my case i use it while plotting graphics:

Manipulate[
 Module[{min, max, col},
  {min, max} = Through@{Min, Max}@pointslf[1][[All, n]];
  col = {"TemperatureMap", {min, max}};
  Graphics3D[{ColorData[col][#6], PointSize[Large], 
      Point[{#1, #2, #3}]} & @@@ pointslf[1]]
  ],
 {n, Range[6, 7]}
 ]

If i substitute #6 with Evaluate@Slot[n] it doesn't work anymore. pointslf[1] is a matrix with coordinates (first three columns) and other stuff (next columns) i use to define the color.

How should i do it in this case?

$\endgroup$

marked as duplicate by Mr.Wizard Mar 24 '15 at 12:42

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • $\begingroup$ Try Manipulate[ Sin[# n] & /@ {0, Pi/2}, {n, Range[2]} ] $\endgroup$ – Nasser Mar 24 '15 at 9:12
  • $\begingroup$ @Nasser that gives Slot multiplied by n not the nth slot. $\endgroup$ – Gordon Coale Mar 24 '15 at 9:17
  • $\begingroup$ @GordonCoale I thought that is what op wanted. May be I did not read the question carefully. $\endgroup$ – Nasser Mar 24 '15 at 9:18
  • $\begingroup$ Why not simply Manipulate[ sel = {0, Pi/2}; Sin[sel[[n]]], {n, Range[2]} ] $\endgroup$ – Nasser Mar 24 '15 at 9:23
  • $\begingroup$ @Nasser I suspect the op wants a version that works with slot even though its not necessary in this simplified example. $\endgroup$ – Gordon Coale Mar 24 '15 at 9:26
3
$\begingroup$

You can do this:

Manipulate[Evaluate@Sin[Slot[n]] &[0, Pi/2], {{n, 1}, Range[2]}]

but I don't think it is as handy as:

Manipulate[Sin[{0, Pi/2}[[n]]], {{n, 1}, Range[2]}]
$\endgroup$
  • $\begingroup$ But the evaluate version will be much neater and more readable if you are passing in named slots from a dataset, then you can pass a popupmenu string or similar straight into your code. $\endgroup$ – Gordon Coale Mar 24 '15 at 9:35
  • 1
    $\begingroup$ @GordonCoale Probably you are right, it depends of the case. Just keep in mind that Evaluate works only on first level of held expression so for more complex cases you may have to do less readable incjection. P.s. Here Function (...&) is what forces us to use Evaluate. $\endgroup$ – Kuba Mar 24 '15 at 9:38
  • $\begingroup$ @Kuba Your code works for the minimal example, but in my case it does not work. I've edited my post with the real use. $\endgroup$ – Gypaets Mar 24 '15 at 10:10
  • $\begingroup$ @mnunos Try Graphics[Evaluate[...]& @@@ .... $\endgroup$ – Kuba Mar 24 '15 at 10:26
  • $\begingroup$ @Kuba Thanks, that works! Could you explain me why do i have to use Evaluate like that? Before asking i also tried Slot[Evaluate[n]], it didn't work and i dont understand at what level do I have to use it. $\endgroup$ – Gypaets Mar 24 '15 at 10:40
2
$\begingroup$

A simple workaround is to use Part and SlotSequence like this:

ColorData[col][{##}[[n]]]

Another workaround is to generate the function that is applied (@@@) with another function:

pointslf[1] = RandomReal[1, {12, 7}];

Manipulate[DynamicModule[{min, max, col, fn},
  {min, max} = Through@{Min, Max}@pointslf[1][[All, n]];
  col = {"TemperatureMap", {min, max}};
  fn[n_] := {ColorData[col][Slot[n]], PointSize[Large], Point[{#1, #2, #3}]} &;
  Graphics3D[fn[n] @@@ pointslf[1]]],
  {n, Range[6, 7]}
]

This is essentally the same as Kuba's method, merely presented in a different style.
Yet another way to write the same thing:

Graphics3D[With[{n = n}, {ColorData[col][Slot[n]], PointSize[Large], 
     Point[{#1, #2, #3}]} &] @@@ pointslf[1]]

The specific method is not important but rather the evaluation that it achieves. The body of a Function is not evaluated due to Function having the HoldAll attribute. We need to inject the value of n into this body to achieve what you want. In this particular case you can evaluate the entire function body with Evaluate, but in other cases you would not want to do that as unwanted evaluation would occur.

Regarding Evaluate see Explicit use of Evaluate not behaving the way I expect it to

$\endgroup$

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