0
$\begingroup$

In my problem, I am effectively plotting a parametric function that depends also on an outside parameter, e.g., the real/imaginary parts of

ff[tt_, param_] := (tt + I * param)^2 

I plot one parametric plot in tt for each of several values of param, i.e., if I let param vary in {1, 2, 3}, and tt vary in [-3, 4], I get

standard Parametric Plot with Multiple Plots

In addition, one of the more complicated functions I am using is hard to compute, so in that case, I use a medium-fine grid of tt and use ListPlot or Graphics primitives instead of ParametricPlot. I.e., I get something like this:

standard ListPlot with multiple plots

The main issue is that I want to give the reader some sense of the direction in which tt is increasing, but I cannot use color as that is already being used to distinguish the different values of param. I could just use text labels, but for my diagrams, that would tend to clutter the picture if they were typed with any frequency. Therefore, I would prefer to use another method.


Main Question

Short of adding text labels to the picture, how can I visually display the direction of increase in the parameter tt in a multiple-graph plot? I am interested in the answer for both ParametricPlot and a ListPlot or other discrete plot that mimics it.


I will put my attempted solutions thus far as answers. One works for both types of plots, but the other only works for a discrete plot.

**Note: I am using Mathematica 9.0.1, so the ParametricPlot/PlotLegends disagreement, as noted in ParametricPlot and PlotLegends don't seem to cooperate, applies.

$\endgroup$
1

2 Answers 2

1
$\begingroup$

A better solution for Discrete Plots

We can use Point instead of ListPlot, and then vary the size as t or tt varies.

We compute the sizes as follows:

unitize[t_, tMin_, tMax_] := (t - tMin)/(tMax - tMin)
sizeBase[u_, sizeMin_, sizeMax_] := sizeMin + (sizeMax - sizeMin)*u
sizer[{t_, tMin_, tMax_}, {sizeMin_, sizeMax_, dir_}] := 
Piecewise[{{sizeBase[unitize[t, tMin, tMax], sizeMin, sizeMax], dir == "incr"}, 
       {sizeBase[1 - unitize[t, tMin, tMax], sizeMin, sizeMax], dir == "decr"}}]

unitize just moves [tMin, tMax] to [0, 1], sizeBase moves that to the interval of sizes. sizer modifies sizeBase to let the user decide whether the circles should increase or decrease as the parameter tt increases. I pass all the size arguments to the user since they will depend on the size of the plot.

We now recall our function and get a list for a fixed param value. It should automatically find the biggest/smallest t value.

Parts[z_] := {Re[z], Im[z]}
ff[tt_, param_] := (tt + I * param)^2 ;
pointListAlt[ttList_,  {param_, col_}, {sizeMin_, sizeMax_, dir_}] := 
 Table[{PointSize[sizer[{ttList[[j]], Sort[ttList][[1]], Sort[ttList[[Length[ttList]]]}, 
 {sizeMin, sizeMax, dir}]], col, Point[Parts[ff[ttList[[j]], param]]]}, {j, 1, Length[ttList]}]

Now all we need to do is the final plotting wrapper, including labels.

paramLabel[paramList_List] := 
  Table[Row[{"param = ", paramList[[j]]}], {j, 1, Length[paramList]}]
SeveralListPlotsVarySize[tFullList_, paramList_, {sizeMin_, sizeMax_, dir_}] := 
Legended[Graphics[
Table[pointListAlt[tFullList, {paramList[[j]], ColorData[1][j]}, {sizeMin, sizeMax, 
  dir}],
  {j, 1, Length[paramList]}], Axes -> True], 
{Placed[ PointLegend[(ColorData[1][#]) & /@ #, 
   paramLabel[paramList][[#]]] & @ Range @ Length[paramList],  Right]}]

We set the list of t values as in my other answer:

 (*Construct the t list*)
 tSmall = -3; tLarge = 4 ; dt = 1/10; numTs = Floor[(tLarge - tSmall)/dt] + 1; 
 dt = (tLarge - tSmall)/(numTs - 1);
 tList = Table[tSmall + (j - 1)* dt, {j, 1, numTs}];

Then plugging in

SeveralListPlotsVarySize[tList, {1, 2, 3}, {0.01, 0.05, "incr"}]

yields

parametric plot with increasing point size

and plugging in

SeveralListPlotsVarySize[tList, {1, 2, 3}, {0.01, 0.05, "decr"}]

yields

parametric plot with decreasing point size

That looks reasonably good.

$\endgroup$
0
$\begingroup$

A simple, not so good solution.

We use special colors (the primary colors work well) to distinguish the start and endpoints.

ParametricPlot version

Again, thanks to the answers to ParametricPlot and PlotLegends don't seem to cooperate and How to simulate Placed in workaround for PlotLegends ParametricPlot bug? for pointing me in the right fixes for 9.0.1.

Parts[z_] := {Re[z], Im[z]};
ff[tt_, param_] := (tt + I * param)^2 ;
(*Need an implicit wrapper for the workaround; 
need an explicit wrapper to evaluate the endpoints*)
ffImplicit[paramList_List] := Transpose[Parts[ff[t, paramList]]]
ffExplicit[tt_, paramList_List] := Transpose[Parts[ff[tt, paramList]]]
(*Commands to plot a t-value with all corresponding parameter values*)
pointListU[tHere_,  paramList_List, size_, colorOption_] := 
 Table[{{PointSize[size], colorOption, Point@#}} &@
   ffExplicit[tHere,  paramList][[j]], {j, 1, Length[paramList]}]
pointCollectU[tList_List,  paramList_List, size_, 
  colorOptionList_List] := 
 Table[pointListUnlabeled[tList[[j]],  paramList, size, 
   colorOptionList[[j]]], {j, 1, Length[tList]}]
(*Construct Labels*)
tLabel[ttList_] := 
Table[Row[{"t = ", ttList[[j]]}], {j, 1, Length[ttList]}];
paramLabel[paramList_List] := 
 Table[Row[{"param = ", paramList[[j]]}], {j, 1, Length[paramList]}]
(*Plotting Command*)
SeveralPlotsWithEndpointsD[tList_List, paramList_List , 
  pointColorList_List, legendLoc_] := 
 With[{localFuncList = ffImplicit[ paramList], 
   localLabels = paramLabel[paramList]}, 
  With[{n = Length@localFuncList, m = Length[tList]}, 
   Legended[
    ParametricPlot[localFuncList, {t, tList[[1]], tList[[m]]}, 
     ImageSize -> Large, PlotRangePadding -> {3, 2}, 
     Epilog -> {pointCollectU[tList,  paramList, .01, 
        pointColorList]}], {Placed[
      LineLegend[(ColorData[1][#]) & /@ #, localLabels[[#]]] & @ 
       Range @ n, {Right, Bottom}], 
     Placed[PointLegend[pointColorList, tLabel[tList]], legendLoc]}]]]

Evaluating with

SeveralPlotsWithEndpointsD[{-3, 4}, {1, 2, 3}, {Black, Red}, {Right, 
Bottom}]

gives

Above with brightly covered endpoints, parametric case

O.K., it does the job, but it doesn't look great.

ListPlot version

Start by taking everything from the previous version above (*PlottingCommand*), though you can omit the wrappers ffImplicit and ffExplicit.

 (*Primary Plotting Command*)
SeveralListPlotsB[tFullList_, tShortList_, paramList_, 
  shortColorList_] := 
 Legended[ListPlot[
    Table[Parts[ff[t, p]], {p, paramList}, {t, tFullList}], 
   Epilog -> {pointCollectU[tShortList, ParamList, 0.03, 
       shortColorList]}], {Placed[
   PointLegend[(ColorData[1][#]) & /@ #, 
     paramLabel[paramList][[#]]] & @ Range @ Length[paramList], 
    Right], Placed[PointLegend[shortColorList, tLabel[tShortList]], 
    Right]}]

Evaluating with

(*Construct the t list*)
tSmall = -3; tLarge = 4 ; dt = 1/10; numTs = 
 Floor[(tLarge - tSmall)/dt] + 1; 
dt = (tLarge - tSmall)/(numTs - 1);
tList = Table[tSmall + (j - 1)* dt, {j, 1, numTs}];
SeveralListPlotsB[tList, {-3, 4}, {1, 2, 3}, {Black, Red}]

which yields

ListPlot with extra Graphics Points

Again, it's OK. It avoids putting text in on top of other text, but that's its only advantage.

$\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.