1
$\begingroup$

I would like to apply a custom PlotStyle (colors and dashing) to a plot of a bunch of expressions, which are in a nested list. I can do this fine when using Plot, but with ParametricPlot I have to manually flatten the list of expressions. Why do they behave differently?

I'm using Mathematica 10.2.

Here is an example: I want to plot two expressions, each under two substitution rules, and use the default colors for them. I also want to show a gray dashed 45° line. (In this example, ParametricPlot doesn't actually improve on Plot, but in my real application it does.)

expnList = {-.2 + x^n, 1 - x*n};
substList = {{n -> .1}, {n -> .2}};
myPlotStyle = PadRight[{Directive[Dashed, Gray]}, 5, Automatic];

Here's a Plot that works just fine:

Plot[Evaluate @ Prepend[x][expnList /. substList], {x, 0, 1}, PlotStyle -> myPlotStyle]

Plot with right colors

(I chose to use Evaluate@ rather than Evaluated->True as suggested here, since for some reason that fails with ParametricPlot.)

But when I try to make a ParametricPlot just like it, Mathematica thinks it's plotting just 2 lines plus the pre-pended 45° one, and so only uses 2+1 colors:

expnPairList = Map[{x, #} &, expnList]
ParametricPlot[
 Evaluate @ Prepend[{x, x}][expnPairList /. substList], {x, 0, 1}, 
 PlotStyle -> myPlotStyle]

ParametricPlot with wrong colors

I can fix this by flattening my expnPairList into a list of length-2 lists using Partition and Flatten.

ParametricPlot[
 Evaluate @
  Prepend[{x, x}][
   Partition[#, 2] &@Flatten@(expnPairList /. substList)],
   {x, 0, 1}, PlotStyle -> myPlotStyle]

ParametricPlot with right colors

What I don't understand is: Why is this flattening necessary? I thought that using Evaluate would allow Mathematica to figure out how many lines it will need to plot, so it could assign styles appropriately.

And, is there a better way to make the colors behave correctly, without having to flatten things in this way?

$\endgroup$
  • 1
    $\begingroup$ The issue is not Evaluate but the ways that the two functions handle lists of lists. To see this, execute Prepend[x][expnList /. substList] outside Plot and copy the result into Plot (without Evaluate), and do the similar thing for ParametricPlot. You will see that the behavior is unchanged from what you describe in your question. As I understand it, Plot is a special case of ParametricPlot. Perhaps it flattens lists of functions before passing them to ParametricPlot. It is impossible to know for certain without knowing the internal behavior of these two functions. $\endgroup$ – bbgodfrey Jan 11 '16 at 12:26
  • $\begingroup$ I don't think nested lists are a documented syntax for Plot or ParametricPlot, so I'm not sure that you can consider one behaviour correct or the other incorrect. They are different functions and they handle unsupported inputs differently. IMO flattening the lists is the correct approach. $\endgroup$ – Simon Woods Jan 11 '16 at 21:03
1
$\begingroup$

I would propose a simpler approach

expnList = {-.2 + x^n, 1 - x*n};
myPlotStyle = PadRight[{Directive[Dashed, Gray]}, 5, Automatic];

plo = Flatten@{x, Table[expnList, {n, {.1, .2}}]}

enter image description here

Row[{
  Plot[
   plo, {x, 0, 1},
   ImageSize -> 400,
   PlotLabel -> "Plot",
   PlotStyle -> myPlotStyle],
  ParametricPlot[
   Evaluate@Thread[List[x, plo]], {x, 0, 1},
   ImageSize -> 400,
   PlotLabel -> "ParametricPlot",
   PlotStyle -> myPlotStyle,
   AspectRatio -> 1/GoldenRatio]
  }]

enter image description here

$\endgroup$
  • $\begingroup$ eldo, your code is certainly cleaner. Is there an advantage to using Table instead of /. (ReplaceAll) to do the substitutions for n? $\endgroup$ – Seth Jan 13 '16 at 3:35
  • $\begingroup$ Not really - Table is much faster for large lists (which isn't the case here). Follow your personal preference :) $\endgroup$ – eldo Jan 13 '16 at 13:16

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.