1
$\begingroup$

Mathematica graphics

I was experimenting with passing arguments via a hash table to a module. Found a very strange result. When I pass a function to be plotted inside the module, it comes out empty.

Yet all argument passed look correct when printing them.

This seems like a scope problem? But I am passing everything to the module?

I just can't exactly know what is going on. A small example will show the problem.

The caller does this

ClearAll[x,y];
ode["f"]    =  Cos[x] (*function to plot*)
ode["xmin"] = -Pi;
ode["xmax"] = Pi;
ode["x"]    = x; (*symbol*)
makePlot[ode]

And the module just reads the input from the hash table and calls plot.

makePlot[ode_]:=Module[{p,f,x,xmin,xmax},
f     = ode["f"];
xmin  = ode["xmin"];
xmax  = ode["xmax"];
x     = ode["x"];

(*print to verify*)
Print[InputForm[f]];
Print[InputForm[xmin]];
Print[InputForm[xmax]];
Print[InputForm[x]];

p = Plot[f,{x,xmin,xmax}];
Print[p] (*this prints only the frame and with no actual graphics*)
]

Here is screen shot of the print on console

Mathematica graphics

This problem only affects the plot commands. All other computation using this passing method work fine. I've been using this method for few days with no problems. It is only graphics come out empty.

I tried adding Evaluate to the plot, but that had no effect.

This works OK, if all is done on global level

ClearAll[x, y];

ode["f"] = Cos[x];
ode["xmin"] = -Pi;
ode["xmax"] = Pi;
ode["x"] = x;

f    = ode["f"];
xmin = ode["xmin"];
xmax = ode["xmax"];
x    = ode["x"];

p = Plot[f, {x, xmin, xmax}]

Mathematica graphics

The question is, why it does not work inside a module? And what does one need to make it work inside a module?

$\endgroup$
7
  • 1
    $\begingroup$ use p = Plot[f, Evaluate@{x, xmin, xmax}] in place of p = Plot[f, {x, xmin, xmax}]? $\endgroup$
    – kglr
    Jul 17, 2018 at 8:12
  • $\begingroup$ @kglr I tried Evaluate@f but did not try Evaluate@{x, xmin, xmax}. Adding the second one made it work! thanks. Even though I do not understand why, but it works :) $\endgroup$
    – Nasser
    Jul 17, 2018 at 8:15
  • $\begingroup$ .. or p = With[{x1 = x, xmin1 = xmin, xmax1 = xmax}, Plot[f, {x1, xmin1, xmax1}]] $\endgroup$
    – kglr
    Jul 17, 2018 at 8:15
  • $\begingroup$ it is the old HoldAll thing. $\endgroup$
    – kglr
    Jul 17, 2018 at 8:16
  • 2
    $\begingroup$ It doesn't work inside of the module, because the Module produces an x variable with a different name (like x$2412). The function f still depends on the global x but the plot iterator goes over this localized version of x. So you're basically plotting something like Plot[Cos[x], {x$2412, -1, 1}]. This is why you need to make sure x$2412 evaluates to x first. $\endgroup$ Jul 17, 2018 at 12:03

1 Answer 1

3
$\begingroup$

Wrapping the iterator in Plot with Evaluate, i.e. using

p = Plot[f, Evaluate@{x, xmin, xmax}]

instead of p = Plot[f, {x, xmin, xmax}] fixes the problem:

makePlot[ode]

enter image description here

$\endgroup$

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.