..Hi all.
I want to plot matrix color map (heat map),
However I want plot heat map using data printed in one line.
I tried,
p for[i=5:15] 'line' u (i%2):(i/2%10):i+1 w image
So gnuplot display warning image need at least 2dimension data
My dataset is like this
0.1(node 1 value at time step 1) 0.1(node 2 "") 0.3(node 3 "") 0.2(node 4 "")
0.5(node 1 value at time step 2) 1.2(node 2 "") 0.7(node 3 "") 0.2(node 4 "")
0.8(node 1 value at time step 3) 2.2(node 2 "") 0.1(node 3 "") 0.1(node 4 "")
0.1(node 1 value at time step 4) 1.2(node 2 "") 1.1(node 3 "") 0.4(node 4 "")
0.4(node 1 value at time step 5) 1.1(node 2 "") 0.7(node 3 "") 0.6(node 4 "")
0.3(node 1 value at time step 6) 0.4(node 2 "") 0.2(node 3 "") 0.3(node 4 "")
0.2(node 1 value at time step 7) 0.3(node 2 "") 0.7(node 3 "") 0.2(node 4 "")
.
.
.
.
In above data there is 4 value in the one line.
Using 4 value in the one line, I want to make 2X2 color matrix
And every 0.3 second I want to change line to make color changing video.
I can make video but problem is, How can I make matrix using datas in one line.
And I don't want to convert in to x:y:z data to plot image.
My datas are little bit long and heavy I am worrying it could decrease speed.
I need to plot real-time heat-map.
As value changes color also changes in real-time
I also tried palette,
p for[i=5:15] 'line' u (i%2):(i/2%10):i+1 w p pt 5 ps 23.5 palette
However, there is empty spaces(white color) between xaxis and yaxis.
So, it doesn't look nice.
How can I plot heat map using datas printed in one line?
Actually, if I can plot real-time heat-map without saving data in the file,
it will be better. ( In the C code open gnuplot and pass the values to the gnuplot)
Thank you in advance
Basically there are several ways to achieve what you want. First I show three possibilities to process the static data into an animated gif:
Use an external tool (here awk
) to process the data file once.
(Variant of 1: Use an external tool like awk
to process the data on the fly)
Use gnuplot only
Variant 1: preprocessing the data
I think an appropriate data format for you is
N1T1 N2T1
N3T1 N4T1
N1T2 N2T2
N3T2 N4T2
...
Note the two newlines between the data sets. With this you can use the index
keyword to select different data sets.
To preprocess your data into this file, call from gnuplot
system('if [ ! -e dataconv ]; then awk ''{ print $1 " " $2 "\n" $3 " " $4 "\n\n"}'' data > dataconv; fi')
If you want to have a fixed color range for all frames, you can either use fixed values (if you know the ranges), or extract them from the data file:
stats 'dataconv' using 1:2
timesteps = int(STATS_records/2)
cbmin = (STATS_min_x > STATS_min_y ? STATS_min_y : STATS_min_x)
cbmax = (STATS_max_x > STATS_max_y ? STATS_max_x : STATS_max_y)
set cbrange[cbmin:cbmax]
Now, to plot the data, you can finally use matrix
and sequentially select all time steps with index
:
set terminal gif animate delay 30
set output 'animate.gif'
unset key
set xrange[-0.5:1.5]
set yrange[-0.5:1.5]
set xtics 1
set ytics 1
do for [i=0:(timesteps-1)] {
set title sprintf('time step % 3d', i+1)
plot 'dataconv' matrix index i with image
}
unset output
Here, I show only the result of the first time step:
Variant 2: processing the data on the fly
You can use awk
both to select the time step and reformat the data. For simplicity, here I manually set a fixed color range:
reset
set cbrange[0:3]
set terminal gif animate delay 30
set output 'animate2.gif'
unset key
set xrange[-0.5:1.5]
set yrange[-0.5:1.5]
set xtics 1
set ytics 1
timesteps = int(system('wc -l data | cut -d " " -f1'))
do for [i=0:timesteps] {
set title sprintf('time step % 3d', i)
plot '< awk ''{ if (FNR == '.i.') {print $1 " " $2 "\n" $3 " " $4}}'' data' matrix with image
}
unset output
Variant 3: gnuplot only
This uses only gnuplot and relies on no external tools, but is a more tedious because it requires some fiddling with the using
statement. The problem is, that you have 1D data (only one line), but want to plot it as 2D, which requires special data format to work properly.
To fake the 2D input, I let gnuplot read in two lines. While it processes the first line, gnuplot remembers the values of column 3 and 4 and uses these in the second line in columns 1 and 2. The data of line 2 is discarded. This has the small disadvantage, that the last time step cannot be plotted unless a dummy last line is inserted. Also estimation of the maximum and minimum color value is a bit more verbose for 4 columns:
stats 'data' using 1:2 prefix 'A_'
stats 'data' using 3:4 prefix 'B_'
timesteps = int(A_records)
max(x, y) = x > y ? x : y
min(x, y) = x > y ? y : x
cbmin = min(min(A_min_x, A_min_y), min(B_min_x, B_min_y))
cbmax = max(max(A_max_x, A_max_y), max(B_max_x, B_max_y))
set cbrange[cbmin:cbmax]
Again, you can skip most of this part if you know the possible color range.
set terminal gif animate delay 30
set output 'animate3.gif'
unset key
A0 = 0
A1 = 0
set xrange[0.5:2.5]
set yrange[0.5:2.5]
set xtics 1
set ytics 1
do for [i=0:(timesteps-2)] {
set title sprintf('time step % 3d', i)
plot 'data' matrix every :::i::(i+1) \
using (A0 = ($1 == 2 && $2 == i) ? $3 : A0, \
A1 = ($1 == 3 && $2 == i) ? $3 : A1, $1+1):\
($2-i+1):\
($2 == i ? $3 : ($1 == 0 ? A0 : ($1 == 1 ? A1 : $3))) \
with image
}
unset output
I hope there is one way which fits your needs.
Real time plotting
One possibility for sort of real time plotting is to have an loop in which the last line of the data file is plotted. This however is not safe against race conditions, if your program doesn't write complete lines at a time:
set cbrange[0:3]
unset key
set xrange[-0.5:1.5]
set yrange[-0.5:1.5]
set xtics 1
set ytics 1
while (1) {
set title "time ".strftime('%T', time(0))
plot '< tail -1 data | awk ''{print $1 " " $2 "\n" $3 " " $4}'' ' matrix with image
pause 0.1
}
To interrupt, just press Ctrl+C
.