5
$\begingroup$

How can I modify ListPlot so that I can plot joined data, but exclude joining up adjacent data points that differ by a certain threshold.

E.g. I want to modify the code

ListPlot[Table[Tan[x], {x, -Pi, Pi, 0.01}], Joined -> True]

so that I don't see the vertical lines at the discontinuities (figure below). I understand this is often taken care of automatically in Plot and can be adapted to one's needs, but I'm not sure how to implement this with ListPlot.

enter image description here

Edit

The answer provided by @corey979 works for this simple example, but isn't suitable for my particular application (I don't want to get bogged down in the details unless necessary). I have an idea that will work for a general discontinuity but not sure how to implement it. Say instead I have the plot given by

f[x_] := If[x < 0, 0, 1]
t1 = Table[f[x], {x, -1, 1, 0.01}];
ListPlot[t1, Joined -> True, DataRange -> {-1, 1}]

how can I get rid of this discontinuity by telling ListPlot to not join the two points either side of 0?

enter image description here

$\endgroup$
6
$\begingroup$

As shown in this thread, with

t = Table[Tan[x], {x, -Pi, Pi, 0.01}];
plot = ListPlot[t, Joined -> True]

can do either

DeleteCases[plot, Line[_?(Length[#] < 4 &)], Infinity]

enter image description here

or

ListPlot[t /. x_ /; Abs@x > 6 -> None, Joined -> True]

enter image description here


EDIT

Regarding the edit in the OP:

f[x_] := If[x < 0, 0, 1]
t1 = Table[f[x], {x, -1, 1, 0.01}];
plot = ListPlot[t1, Joined -> True]

enter image description here

plot /. Line[a_] :> Line /@ Split[a, Abs[#1[[2]] - #2[[2]]] < 0.1 &]

enter image description here

As Chip Hurst proposed in a comment (thanks!), instead of the number 0.1 an automatically selected threshold might be used:

threshold = 
 Quantile[Join @@ 
   Cases[plot, Line[a_] :> Abs[Differences[a[[All, 2]]]], Infinity], 
  0.999]
$\endgroup$
  • $\begingroup$ Thank you. Unfortunately they don't seem to work for my application. I will update my question. $\endgroup$ – Tom Nov 15 '16 at 14:47
  • $\begingroup$ You could always histogram all the height differences to determine a threshold. That would help generalize this code to work for an arbitrary plot. $\endgroup$ – Chip Hurst Nov 15 '16 at 15:49
  • $\begingroup$ @ChipHurst How? Cases[plot, Line[a_] -> a, Infinity][[1, All, 2]] // Differences // Histogram[#, PlotRange -> All] & on the plot of Tan[x] doesn't look enlightening. $\endgroup$ – corey979 Nov 15 '16 at 15:59
  • 3
    $\begingroup$ I was thinking of something like threshold = Quantile[Join @@ Cases[plot, Line[a_] :> Abs[Differences[a[[All, 2]]]], Infinity], 0.999]. $\endgroup$ – Chip Hurst Nov 15 '16 at 16:03
  • $\begingroup$ @ChipHurst Indeed. Allow me to incorporate it into the answer :) $\endgroup$ – corey979 Nov 15 '16 at 16:09
2
$\begingroup$

You can actually split the data then plot. ( For this to work the list needs to be in the {x,f[x]} form. )

f[x_] := If[x < 0, 0, 1]
ListPlot[Split[
  Table[{x, f[x]}, {x, -1, 1, 0.01}],
  Abs[#1[[2]] - #2[[2]]] < .5 &],
  Joined -> True,PlotStyle -> Blue]

enter image description here

of course if the data is already just a list of f[x] you can do like this:

data = Table[Tan[x], {x, -Pi, Pi, 0.01}];
ListPlot[Split[Transpose[{Subdivide[-Pi, Pi, Length@data - 1], data}],
  ( Abs[#1[[2]] - #2[[2]]] < .1 || #1[[2]] #2[[2]] >= 0) &], 
 Joined -> True, PlotStyle -> Blue]

for this one I added a condition to only split if there is a sign change and a large derivative

$\endgroup$

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.