gnuplot矩阵或调色板使用一行 [英] gnuplot matrix or palette using one line
问题描述
..大家好.
我想绘制矩阵颜色图(热图), 但是我想使用一行打印的数据绘制热图. 我尝试过,
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
因此gnuplot显示警告图像至少需要2维数据
So gnuplot display warning image need at least 2dimension data
我的数据集是这样的
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 "")
.
.
.
.
在上述数据中,一行中有4个值. 在一行中使用4值,我想制作2X2颜色矩阵 而且我想每0.3秒钟更改一条线以制作变色视频. 我可以制作视频,但问题是,如何使用一行中的数据制作矩阵.
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.
我不想转换为x:y:z数据以绘制图像. 我的数据有点长且繁琐,我担心它会降低速度. 我需要绘制实时热图. 随着价值的变化,颜色也会实时变化
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
我也尝试过调色板,
p for[i=5:15] 'line' u (i%2):(i/2%10):i+1 w p pt 5 ps 23.5 palette
但是,x轴和y轴之间有空白(白色).
However, there is empty spaces(white color) between xaxis and yaxis.
所以,看起来不太好.
如何使用一行打印的数据绘制热图?
How can I plot heat map using datas printed in one line?
实际上,如果我可以在不将数据保存到文件中的情况下绘制实时热图, 会好起来的. (在C代码中,打开gnuplot并将值传递给gnuplot)
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)
提前谢谢
推荐答案
基本上,有几种方法可以实现所需的目标.首先,我展示了三种将静态数据处理为动画gif的可能性:
Basically there are several ways to achieve what you want. First I show three possibilities to process the static data into an animated gif:
-
使用外部工具(在此为
awk
)一次处理数据文件.
Use an external tool (here
awk
) to process the data file once.
(变式1:使用awk
这样的外部工具实时处理数据)
(Variant of 1: Use an external tool like awk
to process the data on the fly)
仅使用gnuplot
Use gnuplot only
变量1:预处理数据
我认为适合您的数据格式是
Variant 1: preprocessing the data
I think an appropriate data format for you is
N1T1 N2T1
N3T1 N4T1
N1T2 N2T2
N3T2 N4T2
...
请注意数据集之间的两条换行符.这样,您就可以使用index
关键字来选择不同的数据集.
Note the two newlines between the data sets. With this you can use the index
keyword to select different data sets.
要将数据预处理到此文件中,请从gnuplot调用
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]
现在,要绘制数据,您最终可以使用matrix
并使用index
依次选择所有时间步长:
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:
您可以同时使用awk
选择时间步长和重新格式化数据.为简单起见,在这里我手动设置一个固定的颜色范围:
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
变体3:仅gnuplot
这仅使用gnuplot且不依赖任何外部工具,但更麻烦,因为它需要对using
语句有所了解.问题是,您具有一维数据(只有一条线),但是想将其绘制为二维,因此需要特殊的数据格式才能正常工作.
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.
要伪造2D输入,我让gnuplot分两行读取.在处理第一行时,gnuplot会记住第3列和第4列的值,并在第1列和第2列的第二行中使用这些值.第2行的数据将被丢弃.这具有一个小的缺点,即除非插入虚拟的最后一行,否则无法绘制最后的时间步长.同样,对于4列,最大和最小颜色值的估计也有些冗长:
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.
进行实时绘图的一种可能性是有一个循环,在其中绘制数据文件的最后一行.但是,如果您的程序一次不写完整的行,那么在竞争情况下这是不安全的:
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
}
要中断,只需按Ctrl+C
.
这篇关于gnuplot矩阵或调色板使用一行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!