I have a huge data file with three columns " X Y data" about 60000 rows without any space between them. The values are in the raster pattern. For example in a square of 1cm side the data file will look like
0.0 0.0 7.8
0.2 0.0 5.2
0.4 0.0 6.7
0.6 0.0 7.5
0.8 0.0 7.8
1.0 0.0 5.6
1.0 0.2 6.2
0.8 0.2 4.5
0.6 0.2 4.8
.
.
.
.
.
.
.
1.0 1.0 8.9
I want to plot a heat map for this. I tried using http://gnuplot.sourceforge.net/demo/heatmaps.html
Gnuplot heatmap XYZ
but I was not able to do it. Does anyone have a clue how to proceed with it? Any help will be appreciated.
The link doesn't work...
Your data sample doesn't look like "raster pattern". For me raster pattern (1 x 0.2) means:
0.0 0.0 data
0.0 0.2 data
0.0 0.4 data
0.0 0.6 data
0.0 0.8 data
0.0 1.0 data
0.2 0.0 data
0.2 0.2 data
0.2 0.4 data
0.2 0.6 data
0.2 0.8 data
0.2 1.0 data
...
If you have this data form with each line separated by empty line, see above, you can plot them by
set view map
unset surface
set pm3d at b
set size ration -1 #not necessary
unset key #not necessary
splot "data.dat" u 1:2:3 with pm3d
For creating the datafile you can use some sorting programs like sort and then add empty line every lines.
I'm using this procedure upto 1e6 points without much problems. For testing I can recommend you to use keyword every.
Related
I am making a gnuplot animation of a satellite going around a planet. My task is to display it's XY trajectory and associated values of velocity and energy versus time. I know how to plot the path, but I've been having problems displaying velocity etc.
the code below does the following:
satellite track and time steps -- column 3:4;
satellite position -- column 3:4;
planet position -- column 6:7.
do for [n=0:int(STATS_records)] {
plot "sat.dat" u 3:4 every ::0::n w lp ls 2 t sprintf("steps=%i", n), \
"sat.dat" u 3:4 every ::n::n w lp ls 4 notitle, \
"sat.dat" u 6:7 every ::0::n w lp ls 3 notitle , \
}
How do I display the associated velocity values for each sprintf ? The velocity values are in column 5. Thank you everyone in advance.
It seems that you want to put everything in the "key" (legend), but another option is to use labels, which can be easily placed arbitrarily. There are labels you can place one at a time (with set label) and with labels for plotting with actual labels. Don't get them confused.
Your main issue seems to be how to pull out the velocity value from column 5. My first instinct (which is quite hacky) is to use some external program, like awk:
v = system(sprintf("awk 'NR==%d{print $5}' '%s'", n+1, infile))
set label 1 sprintf("v=%.3f", v+0) at screen 0.2,0.9
This is also an example of a label (named 1). The screen keyword means screen-relative rather than graph-relative. Putting this inside your for loop will reassign label 1 every iteration, so it overwrites the label from the previous iteration. Not using this 1 will just plop another label on top of the last one, so it would get messy.
Using an external command line like this isn't very portable. (I don't think it would work on Windows.) I saw this question that shows how to pull a value from a specific row and column of a file. The problem I had with using this is that stats implicitly filters according to whatever xrange is set. When making animations like this, I've noticed that the camera can jump around too much from autoranging, so it's nice to have tight control over the plotting range. Defining an xrange at the top of the file interfered with a subsequent stats command to read a velocity value.
You can, however, specify a range for stats (before the file name, such as stats [*:*] infile). But I had issues using this in combination with a predefined xrange based for position. I found that it did work if I specify the desired plotting range on the plot line instead of a set xrange. Here is another (full script) version using only gnuplot:
set terminal pngcairo
infile = 'anim.dat'
stats infile using 3:4 name 'data' nooutput
set key font 'Courier'
do for [n=0:data_records-1] {
set output sprintf('frame-%03d.png', n)
stats [*:*] infile every ::n::n using 5 name 'velocity' nooutput
plot [data_min_x:1.1*data_max_x][data_min_y:1.1*data_max_y] \
infile u 3:4 every ::0::n w linespoints ls 2 t \
sprintf("steps =%6d\nvelocity =%6.3f", n, velocity_min), \
'' u 3:4 every ::n::n w points pt 7 ps 3 notitle
}
Notice that you could easily change this to a set label if you want. Another option is to plot
'' u (x):(y):5 every ::n::n w labels
to place a label at graph position (x,y).
I don't have your data, but I made my own file with what I hope is a similar format to yours:
anim.dat
0 0.0 0.0 0.0 1.11803398875 0.625
1 0.05 0.05 0.02375 1.09658560997 0.625
2 0.1 0.1 0.045 1.07703296143 0.625
3 0.15 0.15 0.06375 1.05948100502 0.625
4 0.2 0.2 0.08 1.04403065089 0.625
5 0.25 0.25 0.09375 1.0307764064 0.625
6 0.3 0.3 0.105 1.01980390272 0.625
7 0.35 0.35 0.11375 1.01118742081 0.625
8 0.4 0.4 0.12 1.00498756211 0.625
9 0.45 0.45 0.12375 1.00124921973 0.625
10 0.5 0.5 0.125 1.0 0.625
11 0.55 0.55 0.12375 1.00124921973 0.625
12 0.6 0.6 0.12 1.00498756211 0.625
13 0.65 0.65 0.11375 1.01118742081 0.625
14 0.7 0.7 0.105 1.01980390272 0.625
15 0.75 0.75 0.09375 1.0307764064 0.625
16 0.8 0.8 0.08 1.04403065089 0.625
17 0.85 0.85 0.06375 1.05948100502 0.625
18 0.9 0.9 0.045 1.07703296143 0.625
19 0.95 0.95 0.02375 1.09658560997 0.625
I am trying to set line colors in gnuplot. I have a file with several datablocks in the usual format, separated by two empty lines. Is there a way I can set the color of each line in the plot to different colors. My graph looks like this right now
and my file like:
1 0.1 0.5
1 0.2 0.6
1 0.3 0.7
1 0.4 0.8
2 0.1 0.7
2 0.2 0.8
2 0.3 0.9
2 0.4 0.95
3 0.1 0.6
3 0.2 0.7
3 0.3 0.8
3 0.4 0.9
You can plot the lines block by block like this:
filename = "filename.dat" # need the same file several times
stats filename # get number of blocks
show variables # check STATS_blocks
plot for [b=0:STATS_blocks-1] filename u 2:3 index b title ''.(b+1) w lp ps 1
See help stats which counts the blocks in your file, help for which loops over all available blocks, and help index which selects one specific block.
When I separate the data blocks in your example file by two lines as you have written, I get this result:
If you want some control over the color, you might want to read help linecolor variable.
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:
I have a data file with schema as "object parameter output1 output2 ...... outputk". For eg.
A 0.1 0.2 0.43 0.81 0.60
A 0.2 0.1 0.42 0.83 0.62
A 0.3 0.5 0.48 0.84 0.65
B 0.1 0.1 0.42 0.83 0.62
B 0.2 0.1 0.82 0.93 0.61
B 0.3 0.5 0.48 0.34 0.15
...
I want to create multiple plots, each plot corresponding to an object, with x axis being the parameter and series being the outputs. Currently, I've written a python script which dumps the rows for each object in different files and then calls gnuplot. Is there a more elegant way to plot it?
You are looking for this:
plot 'data.txt' using (strcol(1) eq "A" ? $2 : 1/0):4 with line
which results to:
If you would like to create plots for every object use:
do for [object in "A B"] {
reset
set title sprintf("Object %s",object)
plot 'data.txt' using (strcol(1) eq object ? $2 : 1/0):4 notitle with line
pause -1
}
Just press Enter for next plot.
Of course you can export these plots in files, too.
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