I want to plot results in gnuplot that all lie on a circle. For each value I have the corresponding x-y coordinates and a corresponding ID number (so 4 columns in total), but in an unsorted order. The rows are to be sorted in such a way that the direction of rotation is from -x => -y => x => y and end again at -x. So the center of the circle is at 0. How to implement this with "sort" (or alternatively with "awk"?) command (using Linux)?
At Theozh's suggestion, I will formulate my problem a little more precisely. Imagine the dial of a clock with small dots as minute symbols. The position of the minute points can be determined by polar coordinates or by Cartesian coordinates. My file contains the Cartesian coordinates with an associated value (result). The file contains 60 lines with x - y coordinates and the result in the third column. Depending on the quadrant, the signs of x and y change, of course. Unfortunately, the lines are NOT sorted in such a way that they correspond to the sense of circulation. So the line for the point "minute 30" is not in line 30, but e.g. in line 17. The task is to sort the lines by the coordinates so that they appear in the order from 1 to 60. In the diagram, the x-axis would then simply be defined from 1 to 60 and the y-axis would then contain the results (from the 3rd column)
My unsorted file (coordinates for a unit circle, result values simplified for a better overview)
And this is what I want to have (8 rows (every 45°) sorted counterclockwise):
CodePudding user response:
The angle can be calculated directly from the x/y coordinates using the atan2() function.
You do not say exactly what it is that you want to plot. If it is simply the points themselves (one point per line in the file), then this can be done easily inside gnuplot. I show the output from gnuplot 5.5. In earlier versions, and depending on exactly what you want to plot, it might require additional commands to sort the data in a separate step and then plot the sorted data. If you clarify what exactly is supposed to go into the plot, I will modify the example accordingly.
Example using 100 points with random x and y coordinates:
set print $RANDOM
do for [i=1:100] { print rand(0)-0.5, rand(0)-0.5 }
unset print
set xrange [-1:1]
set yrange [-1:1]
set angle degrees
set cbrange [-180:180]; set cblabel "Angle"
set style data linespoints
plot $RANDOM using 1:2:(atan2($2,$1)):(atan2($2,$1)) smooth zsort lc palette
Updated answer
Revised to show a plot of the sample data as given
$DATA << EOD
X Y Result
-0.707 -0.707 222
-0.707 0.707 888
0.707 -0.707 444
-1 0 111
1 0 555
0.707 0.707 666
0 1 777
0 -1 333
EOD
set datafile columnheader # allow for the line of labels
unset key
# atan2() returns a number between -pi and pi; convert this to 0 -> 1
# You could make it run from 0->60 if you know in advance
# there will be 60 evenly spaced points
xcoord(a) = (a pi) / (2 * pi)
plot $DATA using (xcoord(atan2($2,$1))):3:(atan2($2,$1)) smooth zsort with points
And actually, if you don't care what order the points are drawn in, only where they end up, the command is even simpler because there is no need to sort!
plot $DATA using (xcoord(atan2($2,$1))):3 with points