3
$\begingroup$
A = Table[{x, 2 + Sinc[x], 2 + Sinc[0.9 x], 2 + Sinc[0.8 x]}, {x, 0, 
     10.0, 0.1}] // N;
ListLinePlot[A[[All, {1, #}]] & /@ {2, 3, 4}, PlotStyle -> {Red, Blue, Black}, PlotRange -> {1.6, 3.2}]

enter image description here

In the above graph, I want to show the curves with slope-dependent PlotStyles (solid, dashed and dotted).

Specifically, the regions a---b1, a---b2 and a---b3 with solid lines(Thick), then b1---c1, b2---c2 and b3---c3 with Dashed lines and beyond c1, c2 and c3 with Dotted lines.

I have asked a similar question with a beautiful answer. However, this question is different as here, instead of functions, we have a data table.

$\endgroup$

3 Answers 3

4
$\begingroup$

You can still use the same method if you define interpolating functions like:

dat = Table[{x, 2 + Sinc[x], 2 + Sinc[0.9 x], 2 + Sinc[0.8 x]}, {x, 0,
     10.0, 0.1}];
funcs = Interpolation[Transpose[{dat[[All, 1]], #}]] & /@ 
  Transpose[dat[[All, 2 ;;]]]

Now you may use your old code with some minor changes. Note that you will get some warning messages about interpolating functions used outside of their domain.

g[f_] := 
  FindRoot[D[f[x], x], {x, #}] & /@ Range[0, 10, 2] // Values // 
    Chop // Flatten;

flatAt = 
  g /@ funcs // Map[Chop] // Map[Round[#, 0.0001] &] // Map[Union] // 
    Map[Select[# >= 0 &]] // Map[Take[#, 3] &];
styles = {Red, Darker@Green, Blue};

Show@MapThread[
  Plot[#1[x], {x, 0, 10}, PlotRange -> {0, 3.2}, Mesh -> {#2}, 
    MeshShading -> {Dotted, Automatic, Dashed}, PlotStyle -> #3, 
    ImageSize -> 400] &, {funcs, flatAt, styles}]

enter image description here

$\endgroup$
3
$\begingroup$

Using Differences and SplitBy:

A = Table[{x, 2 + Sinc[x], 2 + Sinc[0.9 x], 2 + Sinc[0.8 x]}, {x, 0, 
     10.5, 0.1}] // N;
tA = Transpose@A;

If we take the Differences of a list and notice where the Sign changes, it can give a good indication of the slope going to zero. However, Sign returns {-1, 0, 1} as outputs, so for flat portions, once has to choose a transition resulting in a slight bias for very low frequency signals. Interpolation method, being continuous, (shown by @Daniel Huber) will not have this limitation.

The list of points can be SplitBy the criteria Positive before TakeList extracts appropriate chunks of each list to plot.

g[k_List] := SplitBy[Differences[k], Positive] // Map[Length];

p1 = TakeList[{tA[[1]], tA[[2]]} // Transpose, g[tA[[2]]]];
p2 = TakeList[{tA[[1]], tA[[3]]} // Transpose, g[tA[[3]]]];
p3 = TakeList[{tA[[1]], tA[[4]]} // Transpose, g[tA[[4]]]];
cols = {Red, Darker@Green, Blue};

Show@MapThread[
  ListLinePlot[ #1
    , PlotStyle -> {
      {#2, Thick}
      , {#2, Dashed}
      , {#2, Dotted}
      }
    , PlotRange -> {1.6, 3.2}
    , ImageSize -> 400
    ] &,
  {{p1, p2, p3}, cols}
  ]

enter image description here

If there are more zero-slope points or even a different number of such points per signal then the uniformity of length expected of the MapThread arguments will break down.

$\endgroup$
3
$\begingroup$
data = A[[All, {1,#}]] & /@ {2,3,4};

styles = {Red, Blue, Black};

A function to identify peaks and troughs:

pt = Riffle @@ Sort[FindPeaks[#][[All, 1]]& /@ {#, -#}] & /@ Rest[Transpose@A]

Use pt to construct settings for the option Mesh:

meshspecs = MapThread[#[[#2, 1]] &] @ {data, pt /@ Rest[Transpose @ A]};

options = {MeshStyle -> Opacity[0], 
   MeshShading -> {Dashing[{}], Dashed, DotDashed}, 
   PlotRange -> {1.6, 3.2}, ImageSize -> Large};

Show[
 MapThread[ListLinePlot[#, Mesh -> {#2}, PlotStyle -> #3, options] &]@
  {data, Rest /@ meshspecs, styles}, 
 GridLines -> {Join @@ MapThread[Thread@{##} &]@{meshspecs, styles}, None}]

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.