Reputation: 25843
For sorting a file by column, Linux users have the utility sort
.
Windows users have to install, e.g. CoreUtils
from GnuWin to get the same (or similar) functionality.
So, the minimal code for sorting the file first by column1 and then by column2, and then plotting the file would be something like this:
plot '<sort -k 1,2 "myFile.dat"' u 1:2
Now, however, I have a datablock $Data
:
$Data <<EOD
1 6
4 8
3 7
2 5
1 4
2 3
EOD
The commands I tried so far which all end up in error messages:
plot '<sort -k 1,2' $Data u 1:2
#--> Bad data on line 1 of file <sort -k 1,2
plot '<sort -k 1,2 $Data' u 1:2
plot '<sort -k 1,2 <$Data' u 1:2
#--> warning: Skipping data file with no valid points
#--> x range is invalid
plot '<sort -k 1,2 '<$Data u 1:2
#--> Column number or datablock line expected
I don't want to write the datablock to a file first and read it again from file. I currently don't see how I would redirect the content of $Data
to the standard input of sort
. Is there any solution for Windows as well as for Linux?
Update:
When using @Ethan's suggested code, I get the following result. Mind the lines 2 5
and 2 3
which I expected (and Ethan has it) the other way round.
# Curve 0 of 1, 6 points
# Curve title: "$Data_1 using 1:2:1"
# x y type
1 4 i
1 6 i
2 5 i
2 3 i
3 7 i
4 8 i
Any idea why this is? I'm running gnuplot 5.4.1 on Win10.
Upvotes: 3
Views: 426
Reputation: 15118
The syntax for sending $Data to stdin of the sort utility is set print "| sort"; print $Data
. But that won't do what you want. Instead let's perform the double sort inside gnuplot.
$Data <<EOD
1 6
4 8
3 7
2 5
1 4
2 3
EOD
set table $Data_1
plot $Data using 1:2:2 smooth zsort with points
set table $Data_2
plot $Data_1 using 1:2:1 smooth zsort with points
unset table
print $Data_2
# Curve 0 of 1, 6 points
# Curve title: "$Data_1 using 1:2:1"
# x y type
1 4 i
1 6 i
2 3 i
2 5 i
3 7 i
4 8 i
Upvotes: 1
Reputation: 15118
I am going to back up and suggest that you reconsider your initial restriction against using a temporary file. The most straightforward solution is this:
set print "| sort -k 1,2 > sorted.dat"
print $Data
unset print
plot 'sorted.dat'
If you explain why you don't want to use a temp file, maybe there is an answer to that question independent of the sorting issue. If the concern is the name of the temp file, then perhaps something like this:
tempfile = system("mktemp")
set print "| sort -k 1,2 > ".tempfile
print $Data
unset print
plot tempfile with points
Upvotes: 1
Reputation: 25843
It wouldn't be gnuplot if there wasn't a workaround. Well, a bit cumbersome but it seems to work.
Apparently, smooth zsort
sorts each subblock separately. Hence, after the first sort you "simply" need to split your data into sub-blocks whenever the value in the first column changes.
Code: (edit: with graphical representation it's easier to illustrate the undesired behaviour of zsort
(under Windows only))
### sorting datablock, "bug": Windows zsort does not preserve order
reset session
# create some random test data
set print $Data
do for [i=1:100] {
print sprintf("%g %g", int(rand(0)*10), int(rand(0)*10))
}
set print
# order not preserving (only under Windows)
set table $Data1
plot $Data u 1:2:2 smooth zsort
set table $Data2
plot $Data1 u 1:2:1 smooth zsort
unset table
# order preserving (even under Windows, but cumbersome)
set table $Data3
plot $Data u 1:2:1 smooth zsort
unset table
set print $Data4
do for [i=1:|$Data3|] {
print $Data3[i]
if (i<|$Data3|) { if (word($Data3[i],1) ne word($Data3[i+1],1)) { print "" } }
}
set print
set table $Data5
plot $Data4 u 1:2:2 smooth zsort
set table $Data6
plot $Data5 u 1:2 w table
unset table
set key out
set rmargin 20
set multiplot layout 3,1
plot $Data w lp pt 7 lc "black" ti "Random"
plot $Data2 w lp pt 7 lc "red" ti "zsort"
plot $Data6 w lp pt 7 lc "web-green" ti "Workaround"
unset multiplot
### end of code
Result:
Upvotes: 1