I am a little bit confused by the documentation for Apply (@@).

I want to define a list of parameters, for instance:

parameters = {{1/2, 1/2}, {1, 1/3}, {2, 1/4}, {0.5, 1/5}};

Then I have a function:


Now I want to map the pair (a,b) to the values defined in parameters and generate a plot for each pair of parameters in the same graph.

Now the plot syntax would look something like this:

p = Plot[Evaluate[myfunction /@ parameters], {x, 0, 3},
         AxesOrigin -> {0, 0}, AxesLabel -> {x, f}, PlotStyle -> styles]

What I struggle with, is getting the syntax right in the following part:

myfunction /@ parameters

How do I need to define this so I get a proper map of (a,b) to my list of parameters? To be honest, I am not very satisfied with the documentation for Map. Are there better tutorials?

  • 2
    $\begingroup$ Though old and extremely limited in scope , there's always the Flash tutorials. $\endgroup$ Commented May 6, 2012 at 4:33

4 Answers 4


There are two main ways of accomplishing this, both have their merits, but Map may be easier to understand initially. For instance, using (b/a)*((a/x)^(b+1)) I would do the following,

(#[[2]]/#[[1]])(#[[1]]/x)^(#[[2]]+1)& /@ parameters

where #[[1]] and #[[2]] are a and b, respectively. But, this makes it difficult to read, alternatively you can use With to improve the readability, as follows,

With[{a = #[[1]], b = #[[2]]}, (b/a)*((a/x)^(b+1))]& /@ parameters

It is longer, but it is more readable. I tend to use With in this way. The second method is to use Apply, as outlined by R.M. Here With can also be used,

With[{a = #1, b = #2}, (b/a)*((a/x)^(b+1))]& @@@ parameters

but it is less likely to be confusing when you come back to the code a month later.

  • $\begingroup$ Ok! Does the "#" in front designate it as a parameter? Does the number designate the order, so that the program knows which value from {number1, number2} to map? Why do we have 3 @'s. How does this "level" theory work? $\endgroup$
    – Chris
    Commented May 6, 2012 at 3:15
  • $\begingroup$ @Chris The # is a formal parameter known as a Slot. # is shorthand for #1. In my example using Map, #[[1]] refers to the first element of the first parameter. As noted by RM, Apply differs in that it replaces the Head of an expression, so Apply[f, {x,y}] (shorthand f@@{x,y}) becomes f[x,y]. The @@@ is shorthand for Apply[f, {{1,2},{3,4}}, {1}] which results in {f[1,2], f[3,4]}. Because the elements become arguments, #1 becomes a and #2 becomes b in your question. $\endgroup$
    – rcollyer
    Commented May 6, 2012 at 3:20
  • 1
    $\begingroup$ For the last approach (using @@@) you could use Function[{a, b}, (b/a)*((a/x)^(b + 1))] instead of With. $\endgroup$ Commented May 6, 2012 at 4:19

Here's another way:

parameters = {{1/2, 1/2}, {1, 1/3}, {2, 1/4}, {0.5, 1/5}};

myfunction[{a_, b_}] := (b/a)*((a/x)^(b + 1))

Plot[myfunction /@ parameters, {x, 0, 3}, Evaluated -> True]

Mathematica graphics

Using plain x here is not local; you should consider using \[FormalX] instead. The example above is "safe" because x is localized by Plot (it would not be if you used Plot[ Evaluated @ ... ] instead of Evaluated -> True). On the other hand if you accidentally assign a value to x and then try something like myfunction[{1, 1/3}] /. x -> 5 it will not behave as expected. Formal Symbols are symbols that Mathematica will not let you assign a value to, protect you from yourself in a case like this. It is a good idea to use them if you are going to create a definition with a "floating" undefined symbol like x in the example above.

  • $\begingroup$ Can you expand upon \[FormalX] and why it is useful? Why does it work here, when x would not? $\endgroup$
    – rcollyer
    Commented May 6, 2012 at 3:14
  • 1
    $\begingroup$ @rcollyer well here it is not needed because Evaluated -> True rather than Evaluated @ localizes x anyway, but generally speaking it's a bad idea to float around a global variable that's not supposed to have a value, because at some point it might be assigned one accidentally. That's what the Formal Symbols are for. (I know you know this.) $\endgroup$
    – Mr.Wizard
    Commented May 6, 2012 at 3:23
  • 1
    $\begingroup$ Well, it does change, but I can't think of an instance where I have not desired this behaviour... $\endgroup$
    – rm -rf
    Commented May 6, 2012 at 5:22
  • 2
    $\begingroup$ Incidentally, the Evaluated trick is on Szabolcs' web page. It is about 1/3 the way down the page. $\endgroup$
    – rcollyer
    Commented May 6, 2012 at 14:02
  • 1
    $\begingroup$ @rcollyer outside of SE I can track it back to at least this. $\endgroup$
    – Mr.Wizard
    Commented May 6, 2012 at 18:33

You can define your function as an anonymous function and use Apply at level 1 or @@@:

myfunction[x_] := #2/#1 ((#1/x)^(#2 + 1)) &
Plot[Evaluate[myfunction[x] @@@ parameters], {x, 0, 3},  
    AxesOrigin -> {0, 0}, AxesLabel -> {x, f}]

enter image description here

Think of Apply as something that replaces the Head of an expression. For example, the head of g[a, b] is g. Now if you apply f to that expression, you get:

f @@ g[a, b]
(* Out= f[a, b] *)

You see that the head has been replaced with f. The long form of Apply also takes a third argument, where you can specify the Level that you want it to act on i.e., you can write Apply[f, expr, {level}].

Apply at level 1 is used very often, that it has its own shorthand, which is @@@ and is what I've used above. Here's an example showing the difference between @@ and @@@:

f @@ g[h[a, b], h[c, d]]
(* Out= f[h[a, b], h[c, d]] *)

f @@@ g[h[a, b], h[c, d]]
(* Out= g[f[a, b], f[c, d]] *)
  • $\begingroup$ I was working so hard to include both methods, but you stole my thunder, +1. :) $\endgroup$
    – rcollyer
    Commented May 6, 2012 at 3:09
  • $\begingroup$ Is that & at the end of the line where myfunction is defined necessary? Why can't I defined the function, put a ; at the end and then run the plot? $\endgroup$
    – Chris
    Commented May 6, 2012 at 3:25
  • $\begingroup$ @Chris he's being clever. As pointed out by Mr.Wizard, x is global, and within the bounds of Evaluate it would take on it's global value. What that construct does is localize x to the local form. $\endgroup$
    – rcollyer
    Commented May 6, 2012 at 3:29
  • $\begingroup$ @Chris Yes, it is necessary. The & is what completes the pure function definition and it won't work without it. My definition above is a mix of named patterns (x_) which localizes the variable x and slots (#) which take the parameter values when you apply at level 1. $\endgroup$
    – rm -rf
    Commented May 6, 2012 at 3:30

Here's another solution, which uses replacement rules, and is syntactically closest to your original code (and, unlike most other solutions, doesn't require you to rewrite either myfunction or parameters).

p = Plot[Evaluate[myfunction /. {a->#1, b->#2}& @@@ parameters], {x, 0, 3},
                  AxesOrigin -> {0,0}, AxesLabel -> {x,f}, PlotStyle -> styles]

However, in case you can rewrite myfunction, the simplest solution would be to make it a function of the parameters:

myfunction[a_, b_] := (b/a)*((a/x)^(b+1))
p = Plot[Evaluate[myfunction @@@ parameters], {x, 0, 3},
                  AxesOrigin -> {0,0}, AxesLabel -> {x,f}, PlotStyle -> styles]

Or maybe cleaner (but slightly more verbose):

myfunction[a_, b_, x_] := (b/a)*((a/x)^(b+1))
p = Plot[Evaluate[myfunction[##,x]& @@@ parameters], {x, 0, 3},
                  AxesOrigin -> {0,0}, AxesLabel -> {x,f}, PlotStyle -> styles]

On the other hand, if you cannot change myfunction, but can change how your parameters are written, you could directly write the latter as rules:

parameters = {{a->1/2, b->1/2}, {a->1, b->1/3}, {a->2, b->1/4}, {a->0.5, b->1/5}};

Then your plot call would just read

p = Plot[Evaluate[myfunction /. parameters], {x, 0, 3},
                  AxesOrigin -> {0,0}, AxesLabel -> {x,f}, PlotStyle -> styles]

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.