This is probably a very stupid question, but I've been fighting with it for quite awhile now.

So suppose you have a module:

Test[g_] := Module[{r = g, r2},
r2 = g + 2;
Return[{g, r2}];

That module returns two values such that you can plot them (I've tried it with and without the {} around the function):

Plot[{Test[g]}, {g, 0, 100}, PlotStyle -> {Red, Blue}]

I need to have them colored. I realize I can do this:

Plot[{Test[g][[1]], Test[g][[2]]}, {g, 0, 100}, PlotStyle -> {Red, Blue}]

However, Test is just an example to ask this question, my real module takes a half an hour to plot (it is doing a bunch of maximizations, etc). So, doing the last option would double that time. (and I want to make a bunch of plots).

So, does anyone know how to color the lines when in the first form such that I'm not running the module twice?

  • $\begingroup$ The problem is that due to the adaptive plotting capability of Plot[], the sampling points used for plotting the first component do not at all need to be the same as the points for the second component, most especially if one component varies more than the other. $\endgroup$ – J. M.'s discontentment Jun 17 '13 at 14:58
  • $\begingroup$ Try Plot[Evaluate@Test[g], {g, 0, 100}, PlotStyle -> {Red, Blue}]! This is a know issue with Plot. $\endgroup$ – PlatoManiac Jun 17 '13 at 15:05
  • $\begingroup$ Here's an example that might illustrate the problem for everybody else: ponder on the output of Plot[Re[WeierstrassInvariants[{1 + I u, 1 - I u}]], {u, 1, 2}, Mesh -> All]. $\endgroup$ – J. M.'s discontentment Jun 17 '13 at 15:31
  • $\begingroup$ As a point of note, Return is not necessary here. Instead, simply use {g, r2}, and as the last expression in the CompoundExpression, it is the value "returned." More correctly, the CompoundExpression has that value, hence it is the Module's value, too. $\endgroup$ – rcollyer Jun 17 '13 at 17:05


Plot[Evaluate@Test[g], {g, 0, 100}, PlotStyle -> {Red, Blue}]

This is a known issue with Plot. It happens because of the HoldAll attribute of Plot. You can check it

ClearAttributes[Plot, HoldAll]
Plot[Test[g], {g, 0, 100}, PlotStyle -> {Red, Blue}]

However in practice we use Evaluate in place of messing with the attributes as it can result into unpredictable side effects.

Smapling Issue:

Following the adaptive meshing issue raised in the comment one should understand Plot by default may sample more often for some of the components that will result into computation of the other components as well in this case (particularly for the problem suggested by the OP). To see this try the following oscillating example

Test[g_] := Module[{r2},
 r2 = g^2 Sin[1/(g - 2)];
 {r2, g}];
{pic, data} = 
Reap[Plot[Evaluate@Test[g], {g, 1, 4}, Mesh -> All, 
     MeshStyle -> Directive[PointSize[0.01], Opacity[.45], Black], 
     PlotStyle -> {Red, {Blue, Thick}}, Frame -> True, Axes -> None, 
     EvaluationMonitor :> Sow[{g, #} & /@ Test[g]]]]; 

enter image description here

At first it seems less sample points were used for the linear component. But looking at the true sampling points using EvaluationMonitor one gets to see how adaptive meshing of Plot controls the evaluation of the function Test.

ListPlot[Transpose@First@data, PlotStyle -> {Red, Blue},Frame -> True, Axes -> None]

enter image description here


| improve this answer | |
  • 1
    $\begingroup$ The OP mentions "...it is doing a bunch of maximizations, etc...", which leads me to suspect that what we have is a numerical function that happens to return two outputs. $\endgroup$ – J. M.'s discontentment Jun 17 '13 at 15:27
  • $\begingroup$ @0x4A4D I got your point very well. I also updated the answer a bit to show this issue. $\endgroup$ – PlatoManiac Jun 17 '13 at 16:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.