1
$\begingroup$

I just experience the following problem (this is a MWE just to illustrate). First DateListPlot

v = RandomInteger[{1, 10}, 5];
t = Range[5]
ts = TimeSeries[v, {t}]

and

ClearAll[showTS];
showTS[ts_, options_: OptionsPattern[]] := Module[{},
  DateListPlot[ts, FilterRules[options, Options[DateListPlot]]]
  ]

then

showTS[ts, {ImageSize -> Small}]

works fine. But

ClearAll[showSomething];
showSomething[f_, options_: OptionsPattern[]] := Module[{},
  Plot[f[x], {x, 0, 10}, FilterRules[options, Options[Plot]]]
  ]

and

showSomething[x^2, {ImageSize -> Medium}]

gives an error message:

"Plot: Options expected (instead of 
FilterRules[{ImageSize->Medium},Options[Plot]]) beyond position 2...."

I do not understand why? It is nearly the same code.

$\endgroup$

1 Answer 1

1
$\begingroup$

Let's compare the attributes of Plot and DateListPlot:

Attributes[Plot]
Attributes[DateListPlot]

returns

{HoldAll, Protected, ReadProtected}
{Protected, ReadProtected}

Unlike DateListPlot, Plot holds its arguments from evaluation. Here is a solution that solves your problem:

ClearAll[showSomething];
showSomething[f_, options_: OptionsPattern[]] := 
 Module[{}, 
  Plot[f[x], {x, 0, 10}, 
   Evaluate@FilterRules[options, Options[Plot]]]]

(note I've added Evaluate). And here is a proper way to call your code - you need an pure function, not a formula:

showSomething[#^2 &, {ImageSize -> Medium}]

enter image description here

$\endgroup$
3
  • $\begingroup$ If you insist on typing formula as a parameter to showSomething, as opposed to a pure function, you would need to do more trickery with evaluation. $\endgroup$
    – Victor K.
    Mar 22, 2020 at 17:15
  • $\begingroup$ The main point is to force an evaluation with Evaluate[] of something that needs to be evaluated (e.g. FilterRules[]) inside a function with a HoldAll attribute. Thus: showSomething[f_, range_, opts : OptionsPattern[]] := Plot[f, range, Evaluate @ FilterRules[{opts}, Options[Plot]]] (note the arguments inside FilterRules[]!) and then you can do {showSomething[Sin[x], {x, 0, 2 π}, Frame -> True, PlotStyle -> Red], showSomething[Sin[x], x ∈ Interval[{0, 2 π}], Frame -> True, PlotStyle -> Red]}. $\endgroup$ Mar 23, 2020 at 5:03
  • $\begingroup$ @VictorK.: I should have seen this from the error message (but sometimes one does not see the obvious) - thank you for the fast answer. $\endgroup$
    – mgamer
    Mar 23, 2020 at 6:46

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.