Just trying to get used to gnuplot. I searched a few pages on this site looking for the answer, read the documentation (4.6), and still haven't found the answer. say I have a data file like this:
0.0 0
1.0 25
2.0 55
3.0 110
4.0 456
5.0 554
6.0 345
and I want to label all the data points on the plot. How do I do this? I tried this suggestion plot 'exp.dat' u 1:2 w labels point offset character 0,character 1 tc rgb "blue" but it didn't work. It gave me a Not enough columns for this style response. I'm sure it's something I'm doing but I'm not sure what. Any help would be appreciated. Thanks.
I think you are missing strings for labels. You can do
flabel(y)=sprintf("y=%.2f", y)
plot '-' u 1:2:(flabel($2)) w labels point offset character 0,character 1 tc rgb "blue"
0.0 0
1.0 25
2.0 55
3.0 110
4.0 456
5.0 554
6.0 345
Related
I'm trying to plot the following data file
#x y s err
1 1 0.1 0.2
2 2 0.2 0.2
3 3 0.3 0.2
4 4 0.4 0.2
5 5 0.5 0.2
6 6 0.6 0.2
7 7 0.7 0.2
8 8 0.8 0.2
9 9 0.9 0.2
10 10 1.0 0.2
where the points have a variable size given by column 3 and the errors are given in column 4. I can get
plot "test" u 1:2:3 pt 7 ps variable
plot "test" u 1:2:4 w yerrorbars pt 7
to work independently, giving me this:
But when I try to combine them
plot "test" u 1:2:4:3 w yerrorbars pt 7 ps variable
I get something very strange:
yerrorbars seems to be using column 4 as the y column and column 3 as the yerror column. Even stranger, I get the same output if I try u 1:2:3:4. Is there something wrong with how I'm doing this? I can manually draw the errorbars as vectors, but I'd prefer to use the built-in errorbars style if possible.
gnuplot> help yerrorbars
The `yerrorbars` (or `errorbars`) style is only relevant to 2D data plots.
`yerrorbars` is like `points`, except that a vertical error bar is also drawn.
At each point (x,y), a line is drawn from (x,y-ydelta) to (x,y+ydelta) or
from (x,ylow) to (x,yhigh), depending on how many data columns are provided.
The appearance of the tic mark at the ends of the bar is controlled by
`set errorbars`.
2 columns: [implicit x] y ydelta
3 columns: x y ydelta
4 columns: x y ylow yhigh
An additional input column (4th or 5th) may be used to provide information
such as variable point color.
So in order to provide more than 3 columns and still use a single value for the ydelta, you should be able to do
plot "test" u 1:2:($2-$4):($2+$4):3 w yerrorbars pt 7 ps variable
However, as you point out this doesn't actually work as documented.
Work-around
An alternative is to make two passes; first plot the errorbar lines and suppress the points, second plot the point with the desired properties :
unset key
plot "test" u 1:2:3 with yerrorbars pt 0, \
"" u 1:2:4 with points pt 7 ps variable
I want to plot points with individual labels and colors in Gnuplot.
I have a data file a.dat:
###label x y z
1 244.8 18 6.1
2 248.0 10.4 7
3 294.4 6.3 13.7
4 248.0 7.5 8.92
5 240.0 3.69 6.61
6 240.48 3.69 8.92
7 256 5.7 15.8
8 256 7 10.6
9 256 4.1 8.2
10 256 5.1 12.3
The following commands work.
splot 'a.dat' using 2:3:4:1 with labels
set palette model RGB defined (0 'black',1 'blue', 2 'green', 3 'red')
splot 'a.dat' using 2:3:4:($1==3?1:$1==6?2:$1==9?3:0) with points palette
But how can I mix them?
Assuming I understood your question correctly, do you really need a palette if you just want to set only a few specific colors to a few specific points?
You are using two plotting styles with points and with labels you can combine them in one plot command.
Code:
### variable color points
reset session
$Data <<EOD
###label x y z
1 244.8 18 6.1
2 248.0 10.4 7
3 294.4 6.3 13.7
4 248.0 7.5 8.92
5 240.0 3.69 6.61
6 240.48 3.69 8.92
7 256 5.7 15.8
8 256 7 10.6
9 256 4.1 8.2
10 256 5.1 12.3
EOD
myColor(col) = column(col)==3 ? 0x0000ff : \
column(col)==6 ? 0x00ff00 : \
column(col)==9 ? 0xff0000 : 0
set key noautotitle
splot $Data u 2:3:4:(myColor(1)) w p pt 7 lc rgb var, \
'' u 2:3:4:1 w labels offset 0.0,0.7,0.7
### end of code
Result:
Addition: (colored labels)
If you want to have colored labels then change the plot command as follows:
splot $Data u 2:3:4:1:(myColor(1)) w labels tc rgb var
Well, you have to decide:
using only labels it might be difficult to locate the exact position of your data point
using a point and a label without offset it might be diffcult to read the number
Result: (colored label without point)
I have this iris data ...
5.1 3.5 1.4 0.2 Iris-setosa
4.9 3 1.4 0.2 Iris-setosa
7 3.2 4.7 1.4 Iris-versicolor
6.4 3.2 4.5 1.5 Iris-versicolor
7.1 3 5.9 2.1 Iris-virginica
6.3 2.9 5.6 1.8 Iris-virginica
.
.
.
and I got graph using gnuplot (plot 'c:\iris.data')
But I want points with color group by 5th column (iris-setosa, iris-versicolor, iris-virginica)
For example . . .
iris-setosa = color red, iris-versicolor= color green, iris-virginica = color blue
How can I get color graph?
Please answer . . . .
Replace your colours with numerical indices, e.g., like this:
5.1 3.5 1.4 0.2 0
4.9 3 1.4 0.2 0
7 3.2 4.7 1.4 1
6.4 3.2 4.5 1.5 1
7.1 3 5.9 2.1 2
6.3 2.9 5.6 1.8 2
A simple search-and-replace script should be able to do this for you.
Then you can use Gnuplot’s linecolor palette, e.g. as follows:
plot "iris.data" u 1:2:5 w p lc palette
To adjust the colours used like this:
set palette defined (0 "red", 1 "green", 2 "blue")
Note that while I chose to use the exact indices here, the palette definition is relative and I might as well have used:
set palette defined (-11 "red", -2 "green", 7 "blue")
If you want to keep the string values in your data file, you can construct some kind of lookup-table with gnuplot, using the few string functions which gnuplot provides (see also Different coloured bars in gnuplot bar chart? for a similar use case):
IrisColors = 'Iris-setosa Iris-versicolor Iris-virginica'
index(s) = words(substr(IrisColors, 0, strstrt(IrisColors, s)-1)) + 1
set style fill solid noborder
set linetype 1 lc rgb 'red'
set linetype 2 lc rgb 'green'
set linetype 3 lc rgb 'blue'
plot 'iris.data' using 1:2:(index(strcol(5))) linecolor variable
Note, that the string comparison is case-sensitive, and that you cannot use strings with white spaces as single keys.
In case you don't want to modify your original data (as required in Wrzlprmft's answer) or if you are using the palette already for some other purpose in the graph or if you need more than 255 colors (rarely), you can use the following.
Here, Christoph's lookup function is slightly modified because it would return index 4 if a colorname from the file is not in the list and it would give wrong results in the specially constructed case e.g. index("Test1") with the list "Test100 Test10 Test1".
You are basically looking for a mapping function for your own color names.
This reminds me also to this question.
You could also use the sum function to construct your lookup-table. And from gnuplot>=5.2.0 you could additionally use arrays.
In case you want a legend entry for each color you need to plot it in a loop and filter the data for each color accordingly.
Script:
### color according to colorname from file
reset session
$Data <<EOD
5.1 3.5 1.4 0.2 Iris-setosa
4.9 3 1.4 0.2 Iris-setosa
7 3.2 4.7 1.4 Iris-versicolor
6.4 3.2 4.5 1.5 Iris-versicolor
7.1 3 5.9 2.1 Iris-virginica
6.3 2.9 5.6 1.8 Iris-virginica
EOD
myColors = 'Iris-setosa Iris-versicolor Iris-virginica'
myColorsRGB = '0xff0000 0x00ff00 0x0000ff'
index(s) = words(substr(myColors, 0, strstrt(myColors.' ', s.' ')))
myColor(col) = (_i=index(strcol(col)), _i ? int(word(myColorsRGB,_i)) : 0xcccccc)
set key out Left reverse noautotitle
set multiplot layout 2,1
plot $Data u 1:2:(myColor(5)) w p pt 7 ps 2 lc rgb var
myFilter(colD,colF,i) = strcol(colF) eq word(myColors,i) ? column(colD) : NaN
plot for [i=1:words(myColors)] $Data u 1:(myFilter(2,5,i)):(myColor(5)) \
w p pt 7 ps 2 lc rgb var ti word(myColors,i)
unset multiplot
### end of script
Result:
A quick question about a gnuplot.
I have two graphs, ploted from file, like this:
plot "t2" using 1:75 with linespoints title "crop 20",\
"t2" using 1:11 with linespoints title "crop 30"
Now I want to identify points on both graphs if they have identical height e.g Y coordinate.
It could be a different colour, or a perfect solution would be to draw a line between them.
Any ideas?
Thanks a lot.
EDIT
Thanks for the reply Sunhwan Jo, method suggested works fine, as long as similar values appear in the same order. See the image
Two graphs share several more points in the same height, but its not picked up due to length difference.
You may use external program to filter out data points that have same data in two different column (here I've examined if 75th and 11th column has same entry).
plot "t2" using 1:75 with linespoints title "crop 20",\
"t2" using 1:11 with linespoints title "crop 30",\
"< awk '{if ($75==$11) print $0}' t2" us 1:11 with lines points title "crop 20/30"
EDIT:
Okay, above will not work if you would like to show the data points that have same data in different rows. AWK script will be more elaborated. I have tried as below, hope this helps.
Here's test data.
0 0.0 0.0
1 0.3 0.6
2 1.6 1.6
3 0.3 1.5
4 0.6 3.6
5 0.3 4.3
6 0.3 0.7
7 5.5 5.5
8 6.6 6.6
9 5.2 5.2
10 8.3 8.3
11 2.7 5.0
12 2.8 8.3
13 3.3 2.8
14 7.9 3.9
15 9.9 7.9
16 15.3 15.3
17 14.7 14.7
18 3.8 18.1
19 18.1 12.1
And the gnuplot command (note some obvious difference in column designation):
plot 'test.dat' us 1:2 w lp title "1", \
'test.dat" us 1:3 w lp title "2", \
"< awk '{ind[NR]=$1; arr1[NR]=$2; arr2[NR]=$3} END{for (i=1; i<=NR; i++) {for (j=1; j<=NR; j++) {if (arr1[i]==arr2[j]) print ind[i], arr1[i]}}}' test.dat' test.dat" us 1:2 w lp title '1==2'
Resulting plot:
The previous answer using a awk script to preprocess the data is a good method. Here I give a method using only gnuplot. There is a ternary operator--"?:". Uisng this operator you can pick the points with same value out. For example, "plot 'data.dat' u 1:($11==$75?$11:1/0) w p lc rgb'blue'" will plot only the points with $11==$75. I have written the details in my blog. If any question, visit http://gnuplot-surprising.blogspot.com/2011/09/manipulate-data-using-ternary-operator.html.
I have a data set that uses the x-scale:
0.1 0.4 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
But I need the tics to line up evenly, not have 0.1 and 0.4 scrunched up into the corner. I currently use,
set xtics 1
set xtics add (0.1)(0.4)
But that spaces 0.1 and 0.4 respective to the rest of the scale. I've attached a link to a tinypic I uploaded of my dummy data set with my current problem.
http://tinypic.com/r/2zfolxf/7
Current State
As far as I know, you can do the following in gnuplot with tics (at least what is relevant to your question):
You can specify the start, increment and end of the tics displayed.
This would make sense to you, if you wish to simply set the tics after the value of 2 like
set xtics 2, 1
The other thing you can do, is add explicit tic labels to certain values like
set xtics add ("0.1" 0, "0.4" 1)
This would introduce the labels 0.1, and 0.4 to the x scale where the actual values are 0 and 1
However you cannot modify the actual plotting of the graph. If in you data it states
0.1 100
0.4 150
1 200
2 300
then gunplot will plot it correspondingly.
Possible workaround
A workaround could look like this:
Plot the normal graph from 2 upwards.
Do some hackery stuff to the first two values with this:
plot "Data.dat" every 1::2 w l, "" every 1::1::2 using ($1<magic>):($2)
magic specifies some algebraic operation you want to do with the first column.
Everything is allowed and if your values are constant you can specify a polynomial that goes through the points 0, 1 and 2 with the inputs 0.1, 0.4 and 1 like this polynomial:
y = -1.85*x^2 + 4.26*x - 1.4
Example
Suppose you have this data file:
0.1 0.41
0.4 0.03
1 0.97
2 0.74
3 0.05
4 0.15
5 0.11
6 0.60
7 0.76
8 0.25
Then you can "rearrange" the first two entries to the x-positions -1 and 0 like this:
plot "Data.dat" every 1::2 w l, \
"" every 1::0::2 using (-1.85*$1**2 + 4.26*$1 - 1.4):($2) w l
With some tic-labeling and line style settings it should look exactly like what you are after.
I hope I understood what you are after and that you can make some use of my suggestions.
Cherio
Woltan