Message Boards Message Boards

0
|
361 Views
|
6 Replies
|
0 Total Likes
View groups...
Share
Share this post:

Custom defaults for *some* options, passing through others

Good afternoon! Suppose I want to write a function that calls another, specifying by default certain options in that call, but I also want the user to be able to override those options and also specify any other options available for the called function. I illustrate with a toy example function that does a ListPlot, but with the option Frame->True.The following partly works, in that it sets the Frame option to one that is different from the ListPlot default, and yet can be overridden

Clear[mySpecialPlot]
Options[mySpecialPlot] = {Frame -> True};

mySpecialPlot[data_, opts : OptionsPattern[]] := Module[{},
  ListPlot[data, Frame -> OptionValue[Frame]]
  ]

mySpecialPlot[{1, 2, 3, 4, 5}]
mySpecialPlot[{1, 2, 3, 4, 5}, Frame -> False]

However, what it does not do is allow the user of mySpecialPlot to pass through other ListPlot options. So instead, I tried this:

Clear[mySpecialPlot]
Options[mySpecialPlot] = {Frame -> True};

mySpecialPlot[data_, opts : OptionsPattern[]] := Module[{},
  ListPlot[data, FilterRules[{opts}, Options[ListPlot]]]
  ]

mySpecialPlot[{1, 2, 3, 4, 5}, Background -> GrayLevel[0.95]]
mySpecialPlot[{1, 2, 3, 4, 5}, Frame -> True, 
 Background -> GrayLevel[0.95]]

This does do the pass-though but it does not respect the Options[] command setting the new default. I have to specify it explicitly

So each code does one of the things I want: how can I combine them?

POSTED BY: Gareth Russell
6 Replies

I'd probably do it this way, because I would want Options@mySpecialPlot to be explicit and complete:

ClearAll[mySpecialPlot]
Options[mySpecialPlot] = Options@ListPlot;
SetOptions[mySpecialPlot, Frame -> True];

mySpecialPlot[data_, opts : OptionsPattern[]] := 
 Module[{}, ListPlot[data, opts, Options@mySpecialPlot]];
POSTED BY: Michael Rogers
Posted 23 days ago

You could try something like this:

mySpecialPlot[data_, opts : OptionsPattern[]] := 
  ListPlot[data, Normal@Merge[{Options[mySpecialPlot], {opts}}, Last]]
POSTED BY: Eric Rimbey

Well that does work! Many thanks. Out of interest, do you (or does anyone) know if this is how it is done in the built-in functions that have extensive option pass-though (mainly graphics plotting)?

POSTED BY: Gareth Russell
Posted 23 days ago

What makes you think that built-in functions have extensive pass-through behavior?

POSTED BY: Eric Rimbey

Well, I'm think of higher level plotting functions that say things like "ListPlot has the same options as Graphics, with the following additions and changes:" I assume that ListPlot calls Graphics and therefore must doing something similar to what I was looking for: it has its own set of default Options for some Graphics options, which it must pass to the Graphics call, but must let those be overridden by anyone's specified options in the ListPlot call.

Or am I understanding it all wrong?

POSTED BY: Gareth Russell

Have you seen FilterRules[]? For instance,

Graphics[g, FilterRules[options, Options[Graphics]]]

passes only options for Graphics. Here's an example:

ndsolvePlot // ClearAll;
ndsolvePlot // Options = 
  DeleteDuplicatesBy[Join[Options@NDSolve, Options@ListLinePlot], First];
ndsolvePlot[sys_, y_, dom : {_, _, _}, opts : OptionsPattern[]] := 
 With[
  {sols = NDSolveValue[sys, y, dom, 
     FilterRules[Flatten@{opts}, Options@NDSolve]]},
  ListLinePlot[sols, 
    FilterRules[Flatten@{opts}, Options@ListLinePlot]] /;
   MatchQ[sols, _InterpolatingFunction | {__InterpolatingFunction}]
  ];

ndsolvePlot[{y''[x] - x  y[x]^4 + y[x]^7 == 0, y[0] == 1, 
  y'[0] == -1}, y, {x, 0, 10}, Method -> "ExplicitRungeKutta", 
 Frame -> True]

ndsolvePlot[{y''[x] - x  y[x]^4 + y[x]^7 == 0, y[0] == 1, 
  y'[0] == -1}, y, {x, 0, 10}, Frame -> True, PlotRange -> All]

If you want the default settings for options for the custom function ndsolvePlot[] to be different than the defaults for the components, NDSolve[] or ListLinePlot[], then the FilterRules[] calls should look like this:

FilterRules[Flatten@{opts, Options@ndsolvePlot}, Options@NDSolve]
FilterRules[Flatten@{opts, Options@ndsolvePlot}, Options@ListLinePlot]

Note I did not handle conflicting option values above. For instance the default InterpolationOrder option values are different. The one for ListLinePlot[] is InterpolationOrder -> None and does not work in NDSolve[]. And the default for NDSolve[], InterpolationOrder -> Automatic does something different than None in ListLinePlot[]. In an actual application, one might have to fiddle with the values to get the desired behavior. For instance, one could hard-code the respective defaults like this:

FilterRules[Flatten@{opts,
 InterpolationOrder -> Automatic, Options@ndsolvePlot}, Options@NDSolve]
FilterRules[Flatten@{opts, 
 InterpolationOrder -> None, Options@ndsolvePlot}, Options@ListLinePlot]
POSTED BY: Michael Rogers
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract