2
$\begingroup$

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$
6
  • $\begingroup$ Try Manipulate[ Sin[# n] & /@ {0, Pi/2}, {n, Range[2]} ] $\endgroup$
    – Nasser
    Commented Mar 24, 2015 at 9:12
  • $\begingroup$ @Nasser that gives Slot multiplied by n not the nth slot. $\endgroup$ Commented Mar 24, 2015 at 9:17
  • $\begingroup$ @GordonCoale I thought that is what op wanted. May be I did not read the question carefully. $\endgroup$
    – Nasser
    Commented Mar 24, 2015 at 9:18
  • $\begingroup$ Why not simply Manipulate[ sel = {0, Pi/2}; Sin[sel[[n]]], {n, Range[2]} ] $\endgroup$
    – Nasser
    Commented Mar 24, 2015 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$ Commented Mar 24, 2015 at 9:26

2 Answers 2

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$
8
  • $\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$ Commented Mar 24, 2015 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
    Commented Mar 24, 2015 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
    Commented Mar 24, 2015 at 10:10
  • $\begingroup$ @mnunos Try Graphics[Evaluate[...]& @@@ .... $\endgroup$
    – Kuba
    Commented Mar 24, 2015 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
    Commented Mar 24, 2015 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.