ListPlot join points by nearest neighbor rather than order Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) Announcing the arrival of Valued Associate #679: Cesar Manara Unicorn Meta Zoo #1: Why another podcast?FindCurvePath for lines (rather than points)How to specify DataRange in a ListPlot with an imported set of dataListPlot will not color markers in accordance with my color functionHow to deal with overlapping data points in ListPLotHow do I make ListPlot join the points in order?Show[List of plot] how to color them differently?Blank ListPlot with a tableListContourPlot not plotting all data pointsListLinePlot not plotting full dataGetting the error out of a prediction and a measurementMore resolution on ListContourPlot?

Why are the trig functions versine, haversine, exsecant, etc, rarely used in modern mathematics?

Significance of Cersei's obsession with elephants?

Dating a Former Employee

How could we fake a moon landing now?

Do wooden building fires get hotter than 600°C?

Withdrew £2800, but only £2000 shows as withdrawn on online banking; what are my obligations?

What does this Jacques Hadamard quote mean?

How to show element name in portuguese using elements package?

What do you call the main part of a joke?

Why didn't Eitri join the fight?

Extracting terms with certain heads in a function

Can a new player join a group only when a new campaign starts?

Is there a kind of relay only consumes power when switching?

Should I use a zero-interest credit card for a large one-time purchase?

Why aren't air breathing engines used as small first stages

What is the escape velocity of a neutron particle (not neutron star)

Find the length x such that the two distances in the triangle are the same

Can an alien society believe that their star system is the universe?

Can anything be seen from the center of the Boötes void? How dark would it be?

Delete nth line from bottom

8 Prisoners wearing hats

What is the meaning of the simile “quick as silk”?

Fantasy story; one type of magic grows in power with use, but the more powerful they are, they more they are drawn to travel to their source

Is there any way for the UK Prime Minister to make a motion directly dependent on Government confidence?



ListPlot join points by nearest neighbor rather than order



Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)
Announcing the arrival of Valued Associate #679: Cesar Manara
Unicorn Meta Zoo #1: Why another podcast?FindCurvePath for lines (rather than points)How to specify DataRange in a ListPlot with an imported set of dataListPlot will not color markers in accordance with my color functionHow to deal with overlapping data points in ListPLotHow do I make ListPlot join the points in order?Show[List of plot] how to color them differently?Blank ListPlot with a tableListContourPlot not plotting all data pointsListLinePlot not plotting full dataGetting the error out of a prediction and a measurementMore resolution on ListContourPlot?










9












$begingroup$


I have found some software that allows me to "data mine" the values from publication figures. I have a bunch of contours from papers that I've mined using this software, and am having some trouble plotting the points with the Joined command.



Unfortunately, the downloaded points are sorted by increasing x values, which makes the plotting of Gaussian-esque contours very difficult. I've searched around the forums and haven't found anyone mentioning this problem.



Here's an example on a very small, simpler distribution (note my other sets are much larger so brute force definitely won't work.)



data=62.0774, 0.598737, 62.2377, 0.619119, 62.4048, 
0.580509, 62.5466, 0.637818, 62.9276, 0.654518, 62.9668,
0.566973, 63.3095, 0.671261, 63.8137, 0.688518, 63.8913,
0.565805, 64.4067, 0.703821, 64.8157, 0.568541, 65.1005,
0.718671, 65.7401, 0.573603, 65.9282, 0.732056, 66.6646,
0.580678, 66.7973, 0.743456, 67.6058, 0.589303, 67.7571,
0.755602, 68.5512, 0.599853, 68.6815, 0.761419, 69.4,
0.614478, 69.6059, 0.76384, 70.1679, 0.631668, 70.5117,
0.759937, 70.5514, 0.759266, 70.7216, 0.649606, 71.3609,
0.666955, 71.3764, 0.751005, 71.7909, 0.736308, 71.8078,
0.687055, 71.947, 0.702022, 72.0491, 0.717738


Using ListPlot gives me this:



ListPlot[data]


points



While using ListLinePlot gives me this



ListLinePlot[data]


lines



because the points are ordered with increasing x-value.



So, is there any way to either join the points by nearest neighbor, or re-order the list such that the joined command will give me a neat line? This seems like a traveling-salesman type problem, which could quickly get slow as I increase the number of points too much.










share|improve this question











$endgroup$







  • 4




    $begingroup$
    Try FindShortestTour
    $endgroup$
    – C. E.
    2 days ago






  • 2




    $begingroup$
    Try something like ListLinePlot[data[[Last@FindShortestTour@data]]] but it is not perfect
    $endgroup$
    – J42161217
    2 days ago






  • 2




    $begingroup$
    Will your data always be in convex hulls?
    $endgroup$
    – MikeY
    2 days ago










  • $begingroup$
    @MikeY unfortunately not! They are the results of a Bayesian analysis and many have differing, strange, and non-analytical forms.
    $endgroup$
    – zack
    2 days ago










  • $begingroup$
    Related: (136181)
    $endgroup$
    – Mr.Wizard
    2 days ago















9












$begingroup$


I have found some software that allows me to "data mine" the values from publication figures. I have a bunch of contours from papers that I've mined using this software, and am having some trouble plotting the points with the Joined command.



Unfortunately, the downloaded points are sorted by increasing x values, which makes the plotting of Gaussian-esque contours very difficult. I've searched around the forums and haven't found anyone mentioning this problem.



Here's an example on a very small, simpler distribution (note my other sets are much larger so brute force definitely won't work.)



data=62.0774, 0.598737, 62.2377, 0.619119, 62.4048, 
0.580509, 62.5466, 0.637818, 62.9276, 0.654518, 62.9668,
0.566973, 63.3095, 0.671261, 63.8137, 0.688518, 63.8913,
0.565805, 64.4067, 0.703821, 64.8157, 0.568541, 65.1005,
0.718671, 65.7401, 0.573603, 65.9282, 0.732056, 66.6646,
0.580678, 66.7973, 0.743456, 67.6058, 0.589303, 67.7571,
0.755602, 68.5512, 0.599853, 68.6815, 0.761419, 69.4,
0.614478, 69.6059, 0.76384, 70.1679, 0.631668, 70.5117,
0.759937, 70.5514, 0.759266, 70.7216, 0.649606, 71.3609,
0.666955, 71.3764, 0.751005, 71.7909, 0.736308, 71.8078,
0.687055, 71.947, 0.702022, 72.0491, 0.717738


Using ListPlot gives me this:



ListPlot[data]


points



While using ListLinePlot gives me this



ListLinePlot[data]


lines



because the points are ordered with increasing x-value.



So, is there any way to either join the points by nearest neighbor, or re-order the list such that the joined command will give me a neat line? This seems like a traveling-salesman type problem, which could quickly get slow as I increase the number of points too much.










share|improve this question











$endgroup$







  • 4




    $begingroup$
    Try FindShortestTour
    $endgroup$
    – C. E.
    2 days ago






  • 2




    $begingroup$
    Try something like ListLinePlot[data[[Last@FindShortestTour@data]]] but it is not perfect
    $endgroup$
    – J42161217
    2 days ago






  • 2




    $begingroup$
    Will your data always be in convex hulls?
    $endgroup$
    – MikeY
    2 days ago










  • $begingroup$
    @MikeY unfortunately not! They are the results of a Bayesian analysis and many have differing, strange, and non-analytical forms.
    $endgroup$
    – zack
    2 days ago










  • $begingroup$
    Related: (136181)
    $endgroup$
    – Mr.Wizard
    2 days ago













9












9








9


2



$begingroup$


I have found some software that allows me to "data mine" the values from publication figures. I have a bunch of contours from papers that I've mined using this software, and am having some trouble plotting the points with the Joined command.



Unfortunately, the downloaded points are sorted by increasing x values, which makes the plotting of Gaussian-esque contours very difficult. I've searched around the forums and haven't found anyone mentioning this problem.



Here's an example on a very small, simpler distribution (note my other sets are much larger so brute force definitely won't work.)



data=62.0774, 0.598737, 62.2377, 0.619119, 62.4048, 
0.580509, 62.5466, 0.637818, 62.9276, 0.654518, 62.9668,
0.566973, 63.3095, 0.671261, 63.8137, 0.688518, 63.8913,
0.565805, 64.4067, 0.703821, 64.8157, 0.568541, 65.1005,
0.718671, 65.7401, 0.573603, 65.9282, 0.732056, 66.6646,
0.580678, 66.7973, 0.743456, 67.6058, 0.589303, 67.7571,
0.755602, 68.5512, 0.599853, 68.6815, 0.761419, 69.4,
0.614478, 69.6059, 0.76384, 70.1679, 0.631668, 70.5117,
0.759937, 70.5514, 0.759266, 70.7216, 0.649606, 71.3609,
0.666955, 71.3764, 0.751005, 71.7909, 0.736308, 71.8078,
0.687055, 71.947, 0.702022, 72.0491, 0.717738


Using ListPlot gives me this:



ListPlot[data]


points



While using ListLinePlot gives me this



ListLinePlot[data]


lines



because the points are ordered with increasing x-value.



So, is there any way to either join the points by nearest neighbor, or re-order the list such that the joined command will give me a neat line? This seems like a traveling-salesman type problem, which could quickly get slow as I increase the number of points too much.










share|improve this question











$endgroup$




I have found some software that allows me to "data mine" the values from publication figures. I have a bunch of contours from papers that I've mined using this software, and am having some trouble plotting the points with the Joined command.



Unfortunately, the downloaded points are sorted by increasing x values, which makes the plotting of Gaussian-esque contours very difficult. I've searched around the forums and haven't found anyone mentioning this problem.



Here's an example on a very small, simpler distribution (note my other sets are much larger so brute force definitely won't work.)



data=62.0774, 0.598737, 62.2377, 0.619119, 62.4048, 
0.580509, 62.5466, 0.637818, 62.9276, 0.654518, 62.9668,
0.566973, 63.3095, 0.671261, 63.8137, 0.688518, 63.8913,
0.565805, 64.4067, 0.703821, 64.8157, 0.568541, 65.1005,
0.718671, 65.7401, 0.573603, 65.9282, 0.732056, 66.6646,
0.580678, 66.7973, 0.743456, 67.6058, 0.589303, 67.7571,
0.755602, 68.5512, 0.599853, 68.6815, 0.761419, 69.4,
0.614478, 69.6059, 0.76384, 70.1679, 0.631668, 70.5117,
0.759937, 70.5514, 0.759266, 70.7216, 0.649606, 71.3609,
0.666955, 71.3764, 0.751005, 71.7909, 0.736308, 71.8078,
0.687055, 71.947, 0.702022, 72.0491, 0.717738


Using ListPlot gives me this:



ListPlot[data]


points



While using ListLinePlot gives me this



ListLinePlot[data]


lines



because the points are ordered with increasing x-value.



So, is there any way to either join the points by nearest neighbor, or re-order the list such that the joined command will give me a neat line? This seems like a traveling-salesman type problem, which could quickly get slow as I increase the number of points too much.







plotting order






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 2 days ago









Carl Woll

74.5k399194




74.5k399194










asked 2 days ago









zackzack

1036




1036







  • 4




    $begingroup$
    Try FindShortestTour
    $endgroup$
    – C. E.
    2 days ago






  • 2




    $begingroup$
    Try something like ListLinePlot[data[[Last@FindShortestTour@data]]] but it is not perfect
    $endgroup$
    – J42161217
    2 days ago






  • 2




    $begingroup$
    Will your data always be in convex hulls?
    $endgroup$
    – MikeY
    2 days ago










  • $begingroup$
    @MikeY unfortunately not! They are the results of a Bayesian analysis and many have differing, strange, and non-analytical forms.
    $endgroup$
    – zack
    2 days ago










  • $begingroup$
    Related: (136181)
    $endgroup$
    – Mr.Wizard
    2 days ago












  • 4




    $begingroup$
    Try FindShortestTour
    $endgroup$
    – C. E.
    2 days ago






  • 2




    $begingroup$
    Try something like ListLinePlot[data[[Last@FindShortestTour@data]]] but it is not perfect
    $endgroup$
    – J42161217
    2 days ago






  • 2




    $begingroup$
    Will your data always be in convex hulls?
    $endgroup$
    – MikeY
    2 days ago










  • $begingroup$
    @MikeY unfortunately not! They are the results of a Bayesian analysis and many have differing, strange, and non-analytical forms.
    $endgroup$
    – zack
    2 days ago










  • $begingroup$
    Related: (136181)
    $endgroup$
    – Mr.Wizard
    2 days ago







4




4




$begingroup$
Try FindShortestTour
$endgroup$
– C. E.
2 days ago




$begingroup$
Try FindShortestTour
$endgroup$
– C. E.
2 days ago




2




2




$begingroup$
Try something like ListLinePlot[data[[Last@FindShortestTour@data]]] but it is not perfect
$endgroup$
– J42161217
2 days ago




$begingroup$
Try something like ListLinePlot[data[[Last@FindShortestTour@data]]] but it is not perfect
$endgroup$
– J42161217
2 days ago




2




2




$begingroup$
Will your data always be in convex hulls?
$endgroup$
– MikeY
2 days ago




$begingroup$
Will your data always be in convex hulls?
$endgroup$
– MikeY
2 days ago












$begingroup$
@MikeY unfortunately not! They are the results of a Bayesian analysis and many have differing, strange, and non-analytical forms.
$endgroup$
– zack
2 days ago




$begingroup$
@MikeY unfortunately not! They are the results of a Bayesian analysis and many have differing, strange, and non-analytical forms.
$endgroup$
– zack
2 days ago












$begingroup$
Related: (136181)
$endgroup$
– Mr.Wizard
2 days ago




$begingroup$
Related: (136181)
$endgroup$
– Mr.Wizard
2 days ago










4 Answers
4






active

oldest

votes


















11












$begingroup$

You can use FindCurvePath to reorder your data. However, FindCurvePath expects the scale of the two coordinates to be close, so you need to rescale first:



new = FindCurvePath[data . 1, 0, 0, 100]
ListLinePlot[data[[#]]& /@ new]



2, 1, 3, 6, 9, 11, 13, 15, 17, 19, 21, 23, 26, 27, 30, 31, 32, 29,
28, 25, 24, 22, 20, 18, 16, 14, 12, 10, 8, 7, 5, 4, 2




enter image description here



Update



Roman suggested automating the scaling of the data. Here is one possibility for rescaling the data:



rescale = RescalingTransform[CoordinateBounds[data]] @ data;


Then, using FindCurvePath on the rescaled data:



new = FindCurvePath @ rescale



2, 1, 3, 6, 9, 11, 13, 15, 17, 19, 21, 23, 26, 27, 30, 31, 32, 29, 28, 25,
24, 22, 20, 18, 16, 14, 12, 10, 8, 7, 5, 4, 2




produces the same result.






share|improve this answer











$endgroup$








  • 1




    $begingroup$
    Why not just the closely related ListCurvePathPlot?
    $endgroup$
    – Roman
    2 days ago






  • 1




    $begingroup$
    @Roman Did you try using ListCurvePathPlot? Because the data has such a small variation in the y coordinate, ListCurvePathPlot doesn't work well. That's why I scaled the data and used FindCurvePath to reorder the data, and then plotted the reordered data.
    $endgroup$
    – Carl Woll
    2 days ago






  • 1




    $begingroup$
    Ah yes, brilliant! Maybe even easier for automation would be a hands-free rescaling by the covariance matrix of the data, something like path = First[FindCurvePath[data.(Transpose[#[[2]]]/Sqrt[#[[1]]] &@ Eigensystem[Covariance[data]])]], which tries to map the given data onto a unit circle before applying FindCurvePath. What do you think?
    $endgroup$
    – Roman
    2 days ago







  • 1




    $begingroup$
    @Roman Adding automatic rescaling is a good idea. I added a simple version based on RescalingTransform. You can add an answer using Eigensystem/Covariance if you want.
    $endgroup$
    – Carl Woll
    2 days ago










  • $begingroup$
    Thank you very much for your multiple solutions @CarlWoll! These worked perfectly for all my datasets other than the ones with kinks, those of which I can manually edit.
    $endgroup$
    – zack
    2 days ago


















11












$begingroup$

Since your data can form a star convex polygon, we can sort by the angle with respect to a certain point:



center = Mean[data];
ListLinePlot[ArrayPad[SortBy[data, ArcTan @@ (# - center) &], 0, 1, "Periodic"]]


enter image description here






share|improve this answer











$endgroup$




















    7












    $begingroup$

    By scaling the data into the covariance ellipsoid, we can achieve hands-free auto-scaling before calculating a FindCurvePath along @CarlWoll 's solution:



    path = First@FindCurvePath[
    data.Transpose[#[[2]]/Sqrt[#[[1]]]&@Eigensystem[Covariance[data]]]]



    2, 1, 3, 6, 9, 11, 13, 15, 17, 19, 21, 23, 26, 27, 30, 31, 32, 29, 28, 25, 24, 22, 20, 18, 16, 14, 12, 10, 8, 7, 5, 4, 2




    ListPlot[data[[path]]]


    enter image description here



    Alternatively, if the data points are meant to describe a closed loop, the path can be found with



    path = Last@FindShortestTour[
    data.Transpose[#[[2]]/Sqrt[#[[1]]]&@Eigensystem[Covariance[data]]]]



    1, 2, 4, 5, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 25, 28, 29, 32, 31, 30, 27, 26, 23, 21, 19, 17, 15, 13, 11, 9, 6, 3, 1




    The transformed data that are fed into FindCurvePath or FindShortestTour have a unit covariance matrix, which makes it easier to find a good path:



    Sdata = data.Transpose[#[[2]]/Sqrt[#[[1]]]&@Eigensystem[Covariance[data]]];
    Chop@Covariance[Sdata]



    1., 0, 0, 1.




    We can see that these scaled points nearly lie on a circle:



    ListPlot[Sdata, AspectRatio -> Automatic]


    enter image description here






    share|improve this answer











    $endgroup$








    • 1




      $begingroup$
      You're missing the plot command for your first image and the command shown for it should be with the second image.
      $endgroup$
      – Bob Hanlon
      2 days ago






    • 1




      $begingroup$
      Thanks @BobHanlon , for some reason the formatting got scrambled when I added the second image.
      $endgroup$
      – Roman
      2 days ago










    • $begingroup$
      Thank you for this solution @Roman! It also works excellently.
      $endgroup$
      – zack
      2 days ago


















    2












    $begingroup$

    Sorta lame, but rescaling and Nearest can be used to get triples, with Line to connect the triples (each has a point and its two closest neighbors which in this case will do what you want).



    data2 = Map[1, 100*# &, data];
    nf = Nearest[data2];
    triples0 = Map[RotateRight, nf[data2, 3]];
    triples = Map[Line, Map[1, 1/100*# &, triples0, 2]];

    Show[ListPlot[data, ColorFunction -> (Black &)],
    Graphics[Green, triples]]


    enter image description here






    share|improve this answer









    $endgroup$













      Your Answer








      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "387"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f195229%2flistplot-join-points-by-nearest-neighbor-rather-than-order%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      11












      $begingroup$

      You can use FindCurvePath to reorder your data. However, FindCurvePath expects the scale of the two coordinates to be close, so you need to rescale first:



      new = FindCurvePath[data . 1, 0, 0, 100]
      ListLinePlot[data[[#]]& /@ new]



      2, 1, 3, 6, 9, 11, 13, 15, 17, 19, 21, 23, 26, 27, 30, 31, 32, 29,
      28, 25, 24, 22, 20, 18, 16, 14, 12, 10, 8, 7, 5, 4, 2




      enter image description here



      Update



      Roman suggested automating the scaling of the data. Here is one possibility for rescaling the data:



      rescale = RescalingTransform[CoordinateBounds[data]] @ data;


      Then, using FindCurvePath on the rescaled data:



      new = FindCurvePath @ rescale



      2, 1, 3, 6, 9, 11, 13, 15, 17, 19, 21, 23, 26, 27, 30, 31, 32, 29, 28, 25,
      24, 22, 20, 18, 16, 14, 12, 10, 8, 7, 5, 4, 2




      produces the same result.






      share|improve this answer











      $endgroup$








      • 1




        $begingroup$
        Why not just the closely related ListCurvePathPlot?
        $endgroup$
        – Roman
        2 days ago






      • 1




        $begingroup$
        @Roman Did you try using ListCurvePathPlot? Because the data has such a small variation in the y coordinate, ListCurvePathPlot doesn't work well. That's why I scaled the data and used FindCurvePath to reorder the data, and then plotted the reordered data.
        $endgroup$
        – Carl Woll
        2 days ago






      • 1




        $begingroup$
        Ah yes, brilliant! Maybe even easier for automation would be a hands-free rescaling by the covariance matrix of the data, something like path = First[FindCurvePath[data.(Transpose[#[[2]]]/Sqrt[#[[1]]] &@ Eigensystem[Covariance[data]])]], which tries to map the given data onto a unit circle before applying FindCurvePath. What do you think?
        $endgroup$
        – Roman
        2 days ago







      • 1




        $begingroup$
        @Roman Adding automatic rescaling is a good idea. I added a simple version based on RescalingTransform. You can add an answer using Eigensystem/Covariance if you want.
        $endgroup$
        – Carl Woll
        2 days ago










      • $begingroup$
        Thank you very much for your multiple solutions @CarlWoll! These worked perfectly for all my datasets other than the ones with kinks, those of which I can manually edit.
        $endgroup$
        – zack
        2 days ago















      11












      $begingroup$

      You can use FindCurvePath to reorder your data. However, FindCurvePath expects the scale of the two coordinates to be close, so you need to rescale first:



      new = FindCurvePath[data . 1, 0, 0, 100]
      ListLinePlot[data[[#]]& /@ new]



      2, 1, 3, 6, 9, 11, 13, 15, 17, 19, 21, 23, 26, 27, 30, 31, 32, 29,
      28, 25, 24, 22, 20, 18, 16, 14, 12, 10, 8, 7, 5, 4, 2




      enter image description here



      Update



      Roman suggested automating the scaling of the data. Here is one possibility for rescaling the data:



      rescale = RescalingTransform[CoordinateBounds[data]] @ data;


      Then, using FindCurvePath on the rescaled data:



      new = FindCurvePath @ rescale



      2, 1, 3, 6, 9, 11, 13, 15, 17, 19, 21, 23, 26, 27, 30, 31, 32, 29, 28, 25,
      24, 22, 20, 18, 16, 14, 12, 10, 8, 7, 5, 4, 2




      produces the same result.






      share|improve this answer











      $endgroup$








      • 1




        $begingroup$
        Why not just the closely related ListCurvePathPlot?
        $endgroup$
        – Roman
        2 days ago






      • 1




        $begingroup$
        @Roman Did you try using ListCurvePathPlot? Because the data has such a small variation in the y coordinate, ListCurvePathPlot doesn't work well. That's why I scaled the data and used FindCurvePath to reorder the data, and then plotted the reordered data.
        $endgroup$
        – Carl Woll
        2 days ago






      • 1




        $begingroup$
        Ah yes, brilliant! Maybe even easier for automation would be a hands-free rescaling by the covariance matrix of the data, something like path = First[FindCurvePath[data.(Transpose[#[[2]]]/Sqrt[#[[1]]] &@ Eigensystem[Covariance[data]])]], which tries to map the given data onto a unit circle before applying FindCurvePath. What do you think?
        $endgroup$
        – Roman
        2 days ago







      • 1




        $begingroup$
        @Roman Adding automatic rescaling is a good idea. I added a simple version based on RescalingTransform. You can add an answer using Eigensystem/Covariance if you want.
        $endgroup$
        – Carl Woll
        2 days ago










      • $begingroup$
        Thank you very much for your multiple solutions @CarlWoll! These worked perfectly for all my datasets other than the ones with kinks, those of which I can manually edit.
        $endgroup$
        – zack
        2 days ago













      11












      11








      11





      $begingroup$

      You can use FindCurvePath to reorder your data. However, FindCurvePath expects the scale of the two coordinates to be close, so you need to rescale first:



      new = FindCurvePath[data . 1, 0, 0, 100]
      ListLinePlot[data[[#]]& /@ new]



      2, 1, 3, 6, 9, 11, 13, 15, 17, 19, 21, 23, 26, 27, 30, 31, 32, 29,
      28, 25, 24, 22, 20, 18, 16, 14, 12, 10, 8, 7, 5, 4, 2




      enter image description here



      Update



      Roman suggested automating the scaling of the data. Here is one possibility for rescaling the data:



      rescale = RescalingTransform[CoordinateBounds[data]] @ data;


      Then, using FindCurvePath on the rescaled data:



      new = FindCurvePath @ rescale



      2, 1, 3, 6, 9, 11, 13, 15, 17, 19, 21, 23, 26, 27, 30, 31, 32, 29, 28, 25,
      24, 22, 20, 18, 16, 14, 12, 10, 8, 7, 5, 4, 2




      produces the same result.






      share|improve this answer











      $endgroup$



      You can use FindCurvePath to reorder your data. However, FindCurvePath expects the scale of the two coordinates to be close, so you need to rescale first:



      new = FindCurvePath[data . 1, 0, 0, 100]
      ListLinePlot[data[[#]]& /@ new]



      2, 1, 3, 6, 9, 11, 13, 15, 17, 19, 21, 23, 26, 27, 30, 31, 32, 29,
      28, 25, 24, 22, 20, 18, 16, 14, 12, 10, 8, 7, 5, 4, 2




      enter image description here



      Update



      Roman suggested automating the scaling of the data. Here is one possibility for rescaling the data:



      rescale = RescalingTransform[CoordinateBounds[data]] @ data;


      Then, using FindCurvePath on the rescaled data:



      new = FindCurvePath @ rescale



      2, 1, 3, 6, 9, 11, 13, 15, 17, 19, 21, 23, 26, 27, 30, 31, 32, 29, 28, 25,
      24, 22, 20, 18, 16, 14, 12, 10, 8, 7, 5, 4, 2




      produces the same result.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited 2 days ago

























      answered 2 days ago









      Carl WollCarl Woll

      74.5k399194




      74.5k399194







      • 1




        $begingroup$
        Why not just the closely related ListCurvePathPlot?
        $endgroup$
        – Roman
        2 days ago






      • 1




        $begingroup$
        @Roman Did you try using ListCurvePathPlot? Because the data has such a small variation in the y coordinate, ListCurvePathPlot doesn't work well. That's why I scaled the data and used FindCurvePath to reorder the data, and then plotted the reordered data.
        $endgroup$
        – Carl Woll
        2 days ago






      • 1




        $begingroup$
        Ah yes, brilliant! Maybe even easier for automation would be a hands-free rescaling by the covariance matrix of the data, something like path = First[FindCurvePath[data.(Transpose[#[[2]]]/Sqrt[#[[1]]] &@ Eigensystem[Covariance[data]])]], which tries to map the given data onto a unit circle before applying FindCurvePath. What do you think?
        $endgroup$
        – Roman
        2 days ago







      • 1




        $begingroup$
        @Roman Adding automatic rescaling is a good idea. I added a simple version based on RescalingTransform. You can add an answer using Eigensystem/Covariance if you want.
        $endgroup$
        – Carl Woll
        2 days ago










      • $begingroup$
        Thank you very much for your multiple solutions @CarlWoll! These worked perfectly for all my datasets other than the ones with kinks, those of which I can manually edit.
        $endgroup$
        – zack
        2 days ago












      • 1




        $begingroup$
        Why not just the closely related ListCurvePathPlot?
        $endgroup$
        – Roman
        2 days ago






      • 1




        $begingroup$
        @Roman Did you try using ListCurvePathPlot? Because the data has such a small variation in the y coordinate, ListCurvePathPlot doesn't work well. That's why I scaled the data and used FindCurvePath to reorder the data, and then plotted the reordered data.
        $endgroup$
        – Carl Woll
        2 days ago






      • 1




        $begingroup$
        Ah yes, brilliant! Maybe even easier for automation would be a hands-free rescaling by the covariance matrix of the data, something like path = First[FindCurvePath[data.(Transpose[#[[2]]]/Sqrt[#[[1]]] &@ Eigensystem[Covariance[data]])]], which tries to map the given data onto a unit circle before applying FindCurvePath. What do you think?
        $endgroup$
        – Roman
        2 days ago







      • 1




        $begingroup$
        @Roman Adding automatic rescaling is a good idea. I added a simple version based on RescalingTransform. You can add an answer using Eigensystem/Covariance if you want.
        $endgroup$
        – Carl Woll
        2 days ago










      • $begingroup$
        Thank you very much for your multiple solutions @CarlWoll! These worked perfectly for all my datasets other than the ones with kinks, those of which I can manually edit.
        $endgroup$
        – zack
        2 days ago







      1




      1




      $begingroup$
      Why not just the closely related ListCurvePathPlot?
      $endgroup$
      – Roman
      2 days ago




      $begingroup$
      Why not just the closely related ListCurvePathPlot?
      $endgroup$
      – Roman
      2 days ago




      1




      1




      $begingroup$
      @Roman Did you try using ListCurvePathPlot? Because the data has such a small variation in the y coordinate, ListCurvePathPlot doesn't work well. That's why I scaled the data and used FindCurvePath to reorder the data, and then plotted the reordered data.
      $endgroup$
      – Carl Woll
      2 days ago




      $begingroup$
      @Roman Did you try using ListCurvePathPlot? Because the data has such a small variation in the y coordinate, ListCurvePathPlot doesn't work well. That's why I scaled the data and used FindCurvePath to reorder the data, and then plotted the reordered data.
      $endgroup$
      – Carl Woll
      2 days ago




      1




      1




      $begingroup$
      Ah yes, brilliant! Maybe even easier for automation would be a hands-free rescaling by the covariance matrix of the data, something like path = First[FindCurvePath[data.(Transpose[#[[2]]]/Sqrt[#[[1]]] &@ Eigensystem[Covariance[data]])]], which tries to map the given data onto a unit circle before applying FindCurvePath. What do you think?
      $endgroup$
      – Roman
      2 days ago





      $begingroup$
      Ah yes, brilliant! Maybe even easier for automation would be a hands-free rescaling by the covariance matrix of the data, something like path = First[FindCurvePath[data.(Transpose[#[[2]]]/Sqrt[#[[1]]] &@ Eigensystem[Covariance[data]])]], which tries to map the given data onto a unit circle before applying FindCurvePath. What do you think?
      $endgroup$
      – Roman
      2 days ago





      1




      1




      $begingroup$
      @Roman Adding automatic rescaling is a good idea. I added a simple version based on RescalingTransform. You can add an answer using Eigensystem/Covariance if you want.
      $endgroup$
      – Carl Woll
      2 days ago




      $begingroup$
      @Roman Adding automatic rescaling is a good idea. I added a simple version based on RescalingTransform. You can add an answer using Eigensystem/Covariance if you want.
      $endgroup$
      – Carl Woll
      2 days ago












      $begingroup$
      Thank you very much for your multiple solutions @CarlWoll! These worked perfectly for all my datasets other than the ones with kinks, those of which I can manually edit.
      $endgroup$
      – zack
      2 days ago




      $begingroup$
      Thank you very much for your multiple solutions @CarlWoll! These worked perfectly for all my datasets other than the ones with kinks, those of which I can manually edit.
      $endgroup$
      – zack
      2 days ago











      11












      $begingroup$

      Since your data can form a star convex polygon, we can sort by the angle with respect to a certain point:



      center = Mean[data];
      ListLinePlot[ArrayPad[SortBy[data, ArcTan @@ (# - center) &], 0, 1, "Periodic"]]


      enter image description here






      share|improve this answer











      $endgroup$

















        11












        $begingroup$

        Since your data can form a star convex polygon, we can sort by the angle with respect to a certain point:



        center = Mean[data];
        ListLinePlot[ArrayPad[SortBy[data, ArcTan @@ (# - center) &], 0, 1, "Periodic"]]


        enter image description here






        share|improve this answer











        $endgroup$















          11












          11








          11





          $begingroup$

          Since your data can form a star convex polygon, we can sort by the angle with respect to a certain point:



          center = Mean[data];
          ListLinePlot[ArrayPad[SortBy[data, ArcTan @@ (# - center) &], 0, 1, "Periodic"]]


          enter image description here






          share|improve this answer











          $endgroup$



          Since your data can form a star convex polygon, we can sort by the angle with respect to a certain point:



          center = Mean[data];
          ListLinePlot[ArrayPad[SortBy[data, ArcTan @@ (# - center) &], 0, 1, "Periodic"]]


          enter image description here







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 2 days ago









          Bob Hanlon

          61.7k33598




          61.7k33598










          answered 2 days ago









          Chip HurstChip Hurst

          23.5k15995




          23.5k15995





















              7












              $begingroup$

              By scaling the data into the covariance ellipsoid, we can achieve hands-free auto-scaling before calculating a FindCurvePath along @CarlWoll 's solution:



              path = First@FindCurvePath[
              data.Transpose[#[[2]]/Sqrt[#[[1]]]&@Eigensystem[Covariance[data]]]]



              2, 1, 3, 6, 9, 11, 13, 15, 17, 19, 21, 23, 26, 27, 30, 31, 32, 29, 28, 25, 24, 22, 20, 18, 16, 14, 12, 10, 8, 7, 5, 4, 2




              ListPlot[data[[path]]]


              enter image description here



              Alternatively, if the data points are meant to describe a closed loop, the path can be found with



              path = Last@FindShortestTour[
              data.Transpose[#[[2]]/Sqrt[#[[1]]]&@Eigensystem[Covariance[data]]]]



              1, 2, 4, 5, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 25, 28, 29, 32, 31, 30, 27, 26, 23, 21, 19, 17, 15, 13, 11, 9, 6, 3, 1




              The transformed data that are fed into FindCurvePath or FindShortestTour have a unit covariance matrix, which makes it easier to find a good path:



              Sdata = data.Transpose[#[[2]]/Sqrt[#[[1]]]&@Eigensystem[Covariance[data]]];
              Chop@Covariance[Sdata]



              1., 0, 0, 1.




              We can see that these scaled points nearly lie on a circle:



              ListPlot[Sdata, AspectRatio -> Automatic]


              enter image description here






              share|improve this answer











              $endgroup$








              • 1




                $begingroup$
                You're missing the plot command for your first image and the command shown for it should be with the second image.
                $endgroup$
                – Bob Hanlon
                2 days ago






              • 1




                $begingroup$
                Thanks @BobHanlon , for some reason the formatting got scrambled when I added the second image.
                $endgroup$
                – Roman
                2 days ago










              • $begingroup$
                Thank you for this solution @Roman! It also works excellently.
                $endgroup$
                – zack
                2 days ago















              7












              $begingroup$

              By scaling the data into the covariance ellipsoid, we can achieve hands-free auto-scaling before calculating a FindCurvePath along @CarlWoll 's solution:



              path = First@FindCurvePath[
              data.Transpose[#[[2]]/Sqrt[#[[1]]]&@Eigensystem[Covariance[data]]]]



              2, 1, 3, 6, 9, 11, 13, 15, 17, 19, 21, 23, 26, 27, 30, 31, 32, 29, 28, 25, 24, 22, 20, 18, 16, 14, 12, 10, 8, 7, 5, 4, 2




              ListPlot[data[[path]]]


              enter image description here



              Alternatively, if the data points are meant to describe a closed loop, the path can be found with



              path = Last@FindShortestTour[
              data.Transpose[#[[2]]/Sqrt[#[[1]]]&@Eigensystem[Covariance[data]]]]



              1, 2, 4, 5, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 25, 28, 29, 32, 31, 30, 27, 26, 23, 21, 19, 17, 15, 13, 11, 9, 6, 3, 1




              The transformed data that are fed into FindCurvePath or FindShortestTour have a unit covariance matrix, which makes it easier to find a good path:



              Sdata = data.Transpose[#[[2]]/Sqrt[#[[1]]]&@Eigensystem[Covariance[data]]];
              Chop@Covariance[Sdata]



              1., 0, 0, 1.




              We can see that these scaled points nearly lie on a circle:



              ListPlot[Sdata, AspectRatio -> Automatic]


              enter image description here






              share|improve this answer











              $endgroup$








              • 1




                $begingroup$
                You're missing the plot command for your first image and the command shown for it should be with the second image.
                $endgroup$
                – Bob Hanlon
                2 days ago






              • 1




                $begingroup$
                Thanks @BobHanlon , for some reason the formatting got scrambled when I added the second image.
                $endgroup$
                – Roman
                2 days ago










              • $begingroup$
                Thank you for this solution @Roman! It also works excellently.
                $endgroup$
                – zack
                2 days ago













              7












              7








              7





              $begingroup$

              By scaling the data into the covariance ellipsoid, we can achieve hands-free auto-scaling before calculating a FindCurvePath along @CarlWoll 's solution:



              path = First@FindCurvePath[
              data.Transpose[#[[2]]/Sqrt[#[[1]]]&@Eigensystem[Covariance[data]]]]



              2, 1, 3, 6, 9, 11, 13, 15, 17, 19, 21, 23, 26, 27, 30, 31, 32, 29, 28, 25, 24, 22, 20, 18, 16, 14, 12, 10, 8, 7, 5, 4, 2




              ListPlot[data[[path]]]


              enter image description here



              Alternatively, if the data points are meant to describe a closed loop, the path can be found with



              path = Last@FindShortestTour[
              data.Transpose[#[[2]]/Sqrt[#[[1]]]&@Eigensystem[Covariance[data]]]]



              1, 2, 4, 5, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 25, 28, 29, 32, 31, 30, 27, 26, 23, 21, 19, 17, 15, 13, 11, 9, 6, 3, 1




              The transformed data that are fed into FindCurvePath or FindShortestTour have a unit covariance matrix, which makes it easier to find a good path:



              Sdata = data.Transpose[#[[2]]/Sqrt[#[[1]]]&@Eigensystem[Covariance[data]]];
              Chop@Covariance[Sdata]



              1., 0, 0, 1.




              We can see that these scaled points nearly lie on a circle:



              ListPlot[Sdata, AspectRatio -> Automatic]


              enter image description here






              share|improve this answer











              $endgroup$



              By scaling the data into the covariance ellipsoid, we can achieve hands-free auto-scaling before calculating a FindCurvePath along @CarlWoll 's solution:



              path = First@FindCurvePath[
              data.Transpose[#[[2]]/Sqrt[#[[1]]]&@Eigensystem[Covariance[data]]]]



              2, 1, 3, 6, 9, 11, 13, 15, 17, 19, 21, 23, 26, 27, 30, 31, 32, 29, 28, 25, 24, 22, 20, 18, 16, 14, 12, 10, 8, 7, 5, 4, 2




              ListPlot[data[[path]]]


              enter image description here



              Alternatively, if the data points are meant to describe a closed loop, the path can be found with



              path = Last@FindShortestTour[
              data.Transpose[#[[2]]/Sqrt[#[[1]]]&@Eigensystem[Covariance[data]]]]



              1, 2, 4, 5, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 25, 28, 29, 32, 31, 30, 27, 26, 23, 21, 19, 17, 15, 13, 11, 9, 6, 3, 1




              The transformed data that are fed into FindCurvePath or FindShortestTour have a unit covariance matrix, which makes it easier to find a good path:



              Sdata = data.Transpose[#[[2]]/Sqrt[#[[1]]]&@Eigensystem[Covariance[data]]];
              Chop@Covariance[Sdata]



              1., 0, 0, 1.




              We can see that these scaled points nearly lie on a circle:



              ListPlot[Sdata, AspectRatio -> Automatic]


              enter image description here







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited 2 days ago

























              answered 2 days ago









              RomanRoman

              5,56111131




              5,56111131







              • 1




                $begingroup$
                You're missing the plot command for your first image and the command shown for it should be with the second image.
                $endgroup$
                – Bob Hanlon
                2 days ago






              • 1




                $begingroup$
                Thanks @BobHanlon , for some reason the formatting got scrambled when I added the second image.
                $endgroup$
                – Roman
                2 days ago










              • $begingroup$
                Thank you for this solution @Roman! It also works excellently.
                $endgroup$
                – zack
                2 days ago












              • 1




                $begingroup$
                You're missing the plot command for your first image and the command shown for it should be with the second image.
                $endgroup$
                – Bob Hanlon
                2 days ago






              • 1




                $begingroup$
                Thanks @BobHanlon , for some reason the formatting got scrambled when I added the second image.
                $endgroup$
                – Roman
                2 days ago










              • $begingroup$
                Thank you for this solution @Roman! It also works excellently.
                $endgroup$
                – zack
                2 days ago







              1




              1




              $begingroup$
              You're missing the plot command for your first image and the command shown for it should be with the second image.
              $endgroup$
              – Bob Hanlon
              2 days ago




              $begingroup$
              You're missing the plot command for your first image and the command shown for it should be with the second image.
              $endgroup$
              – Bob Hanlon
              2 days ago




              1




              1




              $begingroup$
              Thanks @BobHanlon , for some reason the formatting got scrambled when I added the second image.
              $endgroup$
              – Roman
              2 days ago




              $begingroup$
              Thanks @BobHanlon , for some reason the formatting got scrambled when I added the second image.
              $endgroup$
              – Roman
              2 days ago












              $begingroup$
              Thank you for this solution @Roman! It also works excellently.
              $endgroup$
              – zack
              2 days ago




              $begingroup$
              Thank you for this solution @Roman! It also works excellently.
              $endgroup$
              – zack
              2 days ago











              2












              $begingroup$

              Sorta lame, but rescaling and Nearest can be used to get triples, with Line to connect the triples (each has a point and its two closest neighbors which in this case will do what you want).



              data2 = Map[1, 100*# &, data];
              nf = Nearest[data2];
              triples0 = Map[RotateRight, nf[data2, 3]];
              triples = Map[Line, Map[1, 1/100*# &, triples0, 2]];

              Show[ListPlot[data, ColorFunction -> (Black &)],
              Graphics[Green, triples]]


              enter image description here






              share|improve this answer









              $endgroup$

















                2












                $begingroup$

                Sorta lame, but rescaling and Nearest can be used to get triples, with Line to connect the triples (each has a point and its two closest neighbors which in this case will do what you want).



                data2 = Map[1, 100*# &, data];
                nf = Nearest[data2];
                triples0 = Map[RotateRight, nf[data2, 3]];
                triples = Map[Line, Map[1, 1/100*# &, triples0, 2]];

                Show[ListPlot[data, ColorFunction -> (Black &)],
                Graphics[Green, triples]]


                enter image description here






                share|improve this answer









                $endgroup$















                  2












                  2








                  2





                  $begingroup$

                  Sorta lame, but rescaling and Nearest can be used to get triples, with Line to connect the triples (each has a point and its two closest neighbors which in this case will do what you want).



                  data2 = Map[1, 100*# &, data];
                  nf = Nearest[data2];
                  triples0 = Map[RotateRight, nf[data2, 3]];
                  triples = Map[Line, Map[1, 1/100*# &, triples0, 2]];

                  Show[ListPlot[data, ColorFunction -> (Black &)],
                  Graphics[Green, triples]]


                  enter image description here






                  share|improve this answer









                  $endgroup$



                  Sorta lame, but rescaling and Nearest can be used to get triples, with Line to connect the triples (each has a point and its two closest neighbors which in this case will do what you want).



                  data2 = Map[1, 100*# &, data];
                  nf = Nearest[data2];
                  triples0 = Map[RotateRight, nf[data2, 3]];
                  triples = Map[Line, Map[1, 1/100*# &, triples0, 2]];

                  Show[ListPlot[data, ColorFunction -> (Black &)],
                  Graphics[Green, triples]]


                  enter image description here







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 2 days ago









                  Daniel LichtblauDaniel Lichtblau

                  47.6k277165




                  47.6k277165



























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Mathematica Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      Use MathJax to format equations. MathJax reference.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f195229%2flistplot-join-points-by-nearest-neighbor-rather-than-order%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Grendel Contents Story Scholarship Depictions Notes References Navigation menu10.1093/notesj/gjn112Berserkeree

                      Area configuration aggregation error after install Porto themeMagento 2.1 CE Installed but front/backend not loading/workingCSS not loading on page within Magento 2 pageCannot install module in Magento 2no commands defined in the “setup” namespace. in Magento2Magento 2: Static files are present but shows 404Why do i have to always run the commands to clean cache in Magento 2.1.8?Failure reason: 'Unable to unserialize value.'Error 500 after magento migrationIn production mode the site does not loadMagento 2 : Error 500 after installing

                      Middle Expansion Olielle Resaix Definition: Uttering songs of triumph shouting with joy triumphant exulting Sejunction Journal 붙다 달 고급 품목 외출 The stretch trades the screeching tin. Definition: The act of speaking with a drawl a drawl Cough Sand Definition: An uproar a quarrel a noisy outbreak Shake Iron Publicize Horse House Baby 사과 Resaix Flaggy Jelly Temporary Unequaled Puppet A drop in the bucket Shrew 성격 회원 성질 미팅 The burn frames the tacky quality. Materialistic The smoke reduces the way. Yammoe Nondescript Cheek 얼굴 배 약하다 날리다 타다 The illegal country shows the iron. Help Rule Drearien Smoke Teaching Meaty Wasp Abraham Lincoln Jaws 진심 수리하다 Size Cork Idea Convert Think Lark John Lennon 거울 청소 군 추천하다 아이스크림