# Options for a function I define that can be passed to functions I call in the definition

I know, this is very close to Functions with Options and/or Function with custom Options and modified Options for built-in Symbols, but I don't get it.

My function looks like this one:

myPlot[data1_, data2_, opts : OptionsPattern[]] :=
Module[{Rescaled, dataRescaled},
Rescaled[x_, commonZero_: False] :=
If[commonZero,
(* for an common zero line *)
x - 5,
(* normal *)
x
];
dataRescaled = Rescaled[data2];
ListLinePlot[{data1, dataRescaled},
FilterRules[{opts}, Options[ListLinePlot]],
PlotLegends -> {"should not", "be the legend"}]
]


And this is how I want to call it:

myPlot[
Sin[Range[51, 100, .1]],
Cos[Range[51, 100, .1]] + 5,
PlotLegends -> Automatic
]


But how can I add an option "CommonZero->True"?

EDIT:

I edited my function this way

myPlot[data1_, data2_,
opts : OptionsPattern[{ListLinePlot, Rescaled}]] :=
Module[{Rescaled, dataRescaled},
Options[Rescaled] = {CommonZero -> False};
Rescaled[x_, OptionsPattern[]] :=
If[OptionValue[CommonZero],
(* for an common zero line *)
x - 5,
(* normal *)
x
];
dataRescaled =
Rescaled[data2, CommonZero -> OptionValue[CommonZero]];

ListLinePlot[{data1, dataRescaled},
FilterRules[{opts}, Options[ListLinePlot]],
PlotLegends -> {"should not", "be the legend"}]
]


But I doubt this is the right or a nice way to do.

• Options[myPlot] = Sort[Append[Options[Plot], "CommonZero" -> True]] and use OptionValue[] and FilterRules[] as necessary. – J. M. is in limbo Jul 30 '15 at 11:35
• @Guesswhoitis. Is the edited solution what you meant? – Phab Jul 30 '15 at 12:01
• If you'll pardon me for being frank, your implementation looks a bit more fragile (unless this is a toy example and your actual routine has good reasons for having a function definition within a function definition). Maybe separate out Rescaled, and set up an option default list the way I did in my previous comment. – J. M. is in limbo Jul 30 '15 at 12:05
• I gave this answer to illustrate a different issue, but it is a pretty good example of handling options in a function definition. – m_goldberg Jul 31 '15 at 2:38
• @Guesswhoitis. I don't mind you being frank, on contrary. As I would call myself still a beginner in Mathematica, I'm thankful for every suggestion for improvement. But yes, it's just a toy function :-) But I was not aware one should not define functions in functions (if they should be 'private'). So I guess building a own package would be a good way?! Or is there another way to have private functions? – Phab Jul 31 '15 at 7:28

If we can pull the function Rescaled outside of myPlot, as Guess who it is suggests, then it can be done in a fairly straightforward way. (If Rescaled is to depend on the arguments to myPlot, perhaps Rescaled can be written so that any needed parameters can be passed to it through the function call instead coded in its definition. Then the following method could be used.)

ClearAll[Rescaled, myPlot];
Options[Rescaled] = {"CommonZero" -> False};
Rescaled[x_, OptionsPattern[]] :=
If[TrueQ@OptionValue["CommonZero"],  (*for an common zero line*)
x - 5,                              (*normal*)
x];
myPlot[data1_, data2_, opts : OptionsPattern[{ListLinePlot, Rescaled}]] :=
Module[{dataRescaled},
dataRescaled = Rescaled[data2, FilterRules[{opts}, Options[Rescaled]]];
ListLinePlot[{data1, dataRescaled},
FilterRules[{opts}, Options[ListLinePlot]],
PlotLegends -> {"should not", "be the legend"}]
]

myPlot[Sin[Range[51, 100, .1]], Cos[Range[51, 100, .1]] + 5,
PlotLegends -> Automatic, "CommonZero" -> True]


• My idea with the neasted function was to have a kind of a 'private' function because I dont want to have a lot userdefined functions around. – Phab Jul 31 '15 at 7:31
• @Phab (1) The way Mathematica does that for its own functions is usually through Contexts. Use fooRescaled instead of just Rescaled, where foo is a name you choose. (2) Otherwise you can move the Rescaled defs (both Options and Rescaled) inside the module (without change) and add Options[myPlot] = Join[Options[ListLinePlot], {"CommonZero" -> False}]; before the definition of myPlot. (3) If it's truly a lot of functions, consider Packages. – Michael E2 Jul 31 '15 at 10:17

If I follow this, the central issue is how to have the main function accept a list of options that need to be separately dispersed to different functions internally.

After messing around a good bit, I've given up on even using OptionsPattern for the main input

myf[a_, opts : OptionsPattern[commonZero -> 42]] :=
Print[Row[{"myf option is ", OptionValue[commonZero]}]]
f[fn_, opts_List: {}] := (
myf[0, Evaluate[
Cases[ opts , x_Rule /; MemberQ[{commonZero}, First@x]]]];
Plot[fn, {x, 0, 1},
Evaluate[
Cases[ opts ,
x_Rule /; MemberQ[First /@ Options[Plot], First@x]]]])

f[x]
f[Sqrt[x] + 1/2, {PlotRange -> {1/2, 3/2}, commonZero -> 1}]


This obviously needs work to make robust (A single option must be in {}` for one thing ).