# Slope-demarcated PlotStyle implementation (II)

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}]


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.

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};

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


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};

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


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.

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],