# How to separate and re-order a list of points?

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


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.

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

• GoFile is kicking back an error at the moment. Commented Mar 1, 2020 at 16:36
• The file is missing. Could you re-upload so that this question is not without context? Commented Mar 2, 2020 at 10:12
• Related: (105988), (136181) Commented Mar 2, 2020 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]


3.31441

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


• impressive! Before your answer, I even tried FindShortestTour, but still have issues. What I learned from you is Rest and EuclideanDistance actually :) Commented Mar 2, 2020 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


I missed the second part of your question. Try this

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