Suppose that we have a list of points. By plotting them we find two curves but the points are in a sequence of first fixing $x$ and then increasing $y$, next fixing $x+dx$ and then increasing $y$ and so on. In order words, the points of the two curves are mixing and scrambling, as seen from ListLinePlot.

testdata = (*copy & paste the data in .txt*);
{ListPlot[testdata, Frame -> True, PlotRange -> {{0, 4}, {0, 2.3}}, ImageSize -> 400],
ListLinePlot[testdata, Frame -> True, PlotRange -> {{0, 4}, {0, 2.3}}, ImageSize -> 400]}

enter image description here enter image description here

Such data is obtained from a big NSolve code, which seems to be impossible to change the order of data generating in the code. Generally, I need to separate them into two groups for the two curves and re-order them along the curves from a start point (indicated by a circle in the following figure), for example, see the figure.

enter image description here

How can I implement the procedure to separate and re-order them. Thank you in advance!

  • $\begingroup$ GoFile is kicking back an error at the moment. $\endgroup$ – MikeY Mar 1 '20 at 16:36
  • $\begingroup$ The file is missing. Could you re-upload so that this question is not without context? $\endgroup$ – Mr.Wizard Mar 2 '20 at 10:12
  • $\begingroup$ Related: (105988), (136181) $\endgroup$ – Mr.Wizard Mar 2 '20 at 10:12
dt = ToExpression[Import@FileNameJoin[{directory, "test.txt"}]]; 

where directory is the location of the input file.

Using FindShortestTour and splitting the resulting list based on the maximum distance between consecutive points in the tour seems to work for this input data:

tour = dt[[Rest[FindShortestTour[dt][[2]]]]];

maxd = Max@BlockMap[EuclideanDistance @@ # &, tour, 2, 1]


ListLinePlot[Split[tour, EuclideanDistance[##] < maxd &]]

enter image description here

  • $\begingroup$ impressive! Before your answer, I even tried FindShortestTour, but still have issues. What I learned from you is Rest and EuclideanDistance actually :) $\endgroup$ – user55777 Mar 2 '20 at 3:58

Looks like the two sets of data are separated by y value of 1.825. So may this is what you want?

testdata // GatherBy[#, (Last@# >= 1.825 &)] & // ListPlot

enter image description here

I missed the second part of your question. Try this

data // Select[Last@# < 1.825 &] // SortBy[Last] // ListLinePlot



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.