Group Abstract Group Abstract

Message Boards Message Boards

0
|
18 Views
|
8 Replies
|
0 Total Likes
View groups...
Share
Share this post:

Pass function call (including parameters) as parameter to user defined function

Posted 15 hours ago

How can i write a function that i can call like this?

(* will have some postprocessing of graphics created by plot later... *)

MyPlotWrapper[Plot[Sin[x], {x,0,Pi}]]

So with each MyPlotWrapper call i want to be able to specify the function that is used to plot (Plot, Plot3D...) and also the function that should be plotted (including all the additional parameters to specify range, lengends... which may be of arbitrary number).

POSTED BY: Ralph Schenn
8 Replies

Have you tried

Hold[Plot[Sin[x], {x, 0, Pi}]]
POSTED BY: Gianluca Gorni
Posted 4 hours ago

Is there any possibility to use the pattern p_ and interpret p as a function head and call that function whatever its name name may be (passing it the arguments that were supplied for p)? There are more then two Plot functions and at the end i may also want to call other (non plotting) functions this way. Because of that i would prefer to avoid a switch with a limited number of cases. p_ may be any function that may be passed as argument to Export[] to create an image of it.

POSTED BY: Ralph Schenn
Posted 3 hours ago

Sure! But it would really help to know what you want to do with these plot expressions in your function. Each plot function could have different options or different argument patterns, so if you're inspecting the expression inside your function, you probably can't avoid some special-casing.

Anyway, the function MyPlotWrapper that I showed you has "knowledge" of all the parts of the plot expression, so you can just assemble the pieces together when you're ready to execute the plot. Or, you can just name the whole argument pattern, and avoid having to reassemble the pieces.

SetAttributes[MyPlotWrapper, HoldFirst];
MyPlotWrapper[p_[fns_, range_, options___]] :=
 Column[
   {"head: " <> ToString[p], 
    "function(s): " <> ToString[fns], 
    "range: " <> ToString[range], 
    "options: " <> ToString[{options}], 
    Row[{"the plot", p[fns, range, options]}]}]

Or

SetAttributes[MyPlotWrapper, HoldFirst];
MyPlotWrapper[expr : p_[fns_, range_, options___]] :=
  Column[
    {"head: " <> ToString[p], 
     "function(s): " <> ToString[fns], 
     "range: " <> ToString[range], 
     "options: " <> ToString[{options}], 
     Row[{"the plot", expr}]}]
POSTED BY: Eric Rimbey
Posted 5 hours ago

Thank you for the answer. I hope that now it is clear how to get the arguments that were supplied to Plot.

But how can i get the (head of) function passed as argument? Using Head[Plot] and adding an underscore like this MyPlotWrapper[Plot[fnsList, range, options__]] does not seem to work

POSTED BY: Ralph Schenn
Posted 5 hours ago

I assume you're trying to distinguish between Plot and Plot3D. One way is to simply overload the wrapper to have two separate definitions.

MyPlotWrapper[Plot[fns_List, range_, options___]] := ...
MyPlotWrapper[Plot3D[fns_List, range_, options___]] := ...

Another way would be to use a pattern for the head.

MyPlotWrapper[p_[fns_List, range_, options___]] :=
 Switch[
  p,
  Plot, "a 2d plot",
  Plot3D, "a 3d plot",
  _, "this is not a plot!"]
POSTED BY: Eric Rimbey
Posted 5 hours ago

Also, my example only handles a plot where the first argument is a list (because it made it easier to demonstrate).

And I should say, if you provide more information about your context we can probably come up with a better way. This approach feels a bit risky.

POSTED BY: Eric Rimbey
Posted 7 hours ago

There are many ways, but without knowing what you're trying to do, it's difficult to give complete and precise guidance. Here is just one example that will hopefully get you started.

SetAttributes[MyPlotWrapper, HoldFirst];
MyPlotWrapper[Plot[fns_List, range_, options___]] := 
 ToString[
  StringForm[
    "I will plot `` over `` with `` options", 
    Head /@ fns, Rest@range, Length[{options}]]]

Demonstration:

MyPlotWrapper[Plot[{Sin[x], Cos[x]}, {x, 0, Pi}, PlotLegends -> "Expressions"]]
(* "I will plot {Sin, Cos} over {0, Pi} with 1 options" *)
POSTED BY: Eric Rimbey
Posted 14 hours ago

Calling it like this would also be fine for me if this is easier to achieve

MyPlotWrapper[Plot, {Sin[x], {x,0,Pi}, PlotLegends->"Expressions"}]

POSTED BY: Ralph Schenn
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard