使用 GNUplot 在热图中使用标签绘制等高线
Contour lines with labels in heatmap with GNUplot
在 之后,我现在有了一个带有自定义颜色条的热图。现在我需要用标签放置等高线。等高线我画好了,但是不知道怎么放。
这是我目前的剧情:
生成绘图的代码:
reset
#Function map values on desired ranges. The values set to 90,95,99 are for later labelling
step(x) = (x < 20.0 ? 0 : (x < 50.0 ? 10 : (x < 75.0 ? 20 : (x < 90.0 ? 80 : (x < 95.0 ? 90 : (x < 97.5 ? 95 : (x < 99.0 ? 97 : (x < 99.5 ? 99 : (x < 99.9 ? 100 : 101 )))))))))
# enable 3D data read from a scattered data set in file
#71,46,10 are the number of different values for each axis X,Y,Z in "HeatMap_Test.txt" data file
#If values of dgrid3d are not set accordingly, weird contour values will be generated
set dgrid3d 71,46,10
set contour base # enable contour drawing
set cntrlabel font ",7"
set view 0,0 # if you want to see the graph from above (2D plot)
unset surface # do not plot the surface, only the contour
set cntrparam levels discrete 90,95,99 #set contours only on values 90,95 and 99
set table "contours.dat" #Name of the output file to write the table
splot "HeatMap_Test.txt" u 2:1:(step()) with lines notitle
unset table #Write table to file
reset
#Map the Z values to desired ranges
step(x) = (x < 20.0 ? 0 : (x < 50.0 ? 1 : (x < 75.0 ? 2 : (x < 90.0 ? 3 : (x < 95.0 ? 4 : (x < 97.5 ? 5 : (x < 99.0 ? 6 : (x < 99.5 ? 7 : (x < 99.9 ? 8 : 9 )))))))))
set palette maxcolors 10
set palette defined (0 "#333399", 1 "#3333f7", 2 "#3373ff", 3 "#33c6ff", 4 "#5affd2", 5 "#9cff8f", 6 "#dfff4c", 7 "#ffc733", 8 "#ff7a33", 9 "#e53333")
set cbrange [-0.5:9.5]
set cbtics nomirror
set cbtics ( ">99.9" 9, ">99.5" 8, ">99.0" 7, ">97.5" 6, ">95.0" 5, ">90.0" 4, ">75.0" 3, ">50.0" 2, ">20.0" 1, ">10.0" 0 )
set xrange [-30:40]
set yrange [ 25:70]
set xtics 5
set ytics 5
#set title " %"
set grid front linetype -1
set grid xtics lt 0 lw 1 lc rgb "#000000"
set grid ytics lt 0 lw 1 lc rgb "#000000"
plot "HeatMap_Test.txt" u 2:1:(step()) notitle pt 5 ps 2 lc palette, "world_10m.txt" notitle with lines ls 1 lc -1, "contours.dat" u 1:2 w l lw 2 lc 0 notitle
这里是数据文件:HeatMap_Test.txt, world_10m.txt
该代码适用于 GNUplot 4.6 和 5(我在 Linux 下工作)
为了得到我想要的剧情,我还要做三件事:
1) 标注等高线(从内到外用99、95、90)
2) 使边界线适合绘图(图中热图越过边界)
3) 将标题(在本例中为单个“%”)放在颜色栏的顶部。一种肮脏的做法是设置一个普通的标题并放置空格(代码中有一个注释行可以做到这一点),但我认为必须有更好的方法。
我标记轮廓的想法如下图所示:
感谢您的帮助
让我们从数字开始 3: 颜色条的标题。
您想在颜色栏顶部设置 cblabel
。虽然我不认为这可以自动完成,但您可以像这样使用 offset x,y
:
set cblabel "%" norotate offset -6, 9
仍然是 hack,但我认为这比滥用标题要好。
现在编号2: 使边界线适合情节。
越过边界线的原因是(隐含的)命令plot with points pointsize 2
。仅绘制在边界上的点将重叠。我建议用这样的 splot pm3d
替换这些点:
set pm3d explicit
set view map
splot "HeatMap_Test_2.txt" u 2:1:(0):(step()) notitle w pm3d lc palette , \
"world_10m.txt" u 1:2:(0) notitle with lines ls 1 lc rgb "#ffffff" , \
"contours.dat" u 1:2:(0) w l lw 2 lc rgb "#000000" notitle
为了让这个 3D 绘图起作用,我做了以下操作:
- 添加一个虚拟 z 列,数字
(0)
- 格式化"HeadMap_test.txt"成块,即每次纬度扫描后插入一个空行
来自:
...
25.00 38.00 15.9
25.00 39.00 5.3
25.00 40.00 1.6
26.00 -30.00 0.0
26.00 -29.00 0.3
26.00 -28.00 0.7
...
至:
...
25.00 38.00 15.9
25.00 39.00 5.3
25.00 40.00 1.6
26.00 -30.00 0.0
26.00 -29.00 0.3
26.00 -28.00 0.7
...
- 而且我不得不稍微调整第一步函数来找到轮廓,我已经稍微降低了步长值 90、95 和 99
像这样:
step(x) = (x < 20.0 ? 0 : \
(x < 50.0 ? 10 : \
(x < 75.0 ? 20 : \
(x < 90.0 ? 80 : \
(x < 95.0 ? 89.999 : \
(x < 97.5 ? 94.999 : \
(x < 99.0 ? 97 : \
(x < 99.5 ? 98.999 : \
(x < 99.9 ? 100 : 101 )))))))))
现在,有了 pngcairo 终端和 Gnuplot 4.6,我们应该已经到达这里了:
和编号1: 标记等高线
我没试过,但也许this post可以帮到你。
终于明白了,多亏了@maij, using the link他的回答。
对于问题编号 3,我使用了带有以下参数的 @maij 行:
set cblabel "%" norotate offset -8, 12
问题编号 2,绘制热图时,我不得不从
plot "HeatMap_Test.txt" u 2:1:(step()) notitle pt 5 ps 2 lc palette
到
plot "HeatMap_Test.txt" u 2:1:(step()) with image
最后,问题号 1,为了将标签放在轮廓线中,我不得不使用与以前相同的 link 中提供的外部 awk 脚本.我将脚本命名为draw_contourlines_label.sh,脚本内容为:
#!/bin/bash
awk -v d= -v w= -v os= 'function abs(x) { return (x>=0?x:-x) }
{
if([=13=]~/# Contour/) nr=0
if(nr==int(os+w/2) && d==0) {a[i]=; b[i]=; c[i]=;}
if(nr==int(os+w/2)-1 && d==0) {i++; x = ; y = ;}
if(nr==int(os+w/2)+1 && d==0) r[i]= 180.0*atan2(y-, x-)/3.14
if(abs(nr-os-w/2)>w/2 && d==1) print [=13=]
nr++
}
END { if(d==0) {
for(j=1;j<=i;j++)
printf "set label %d \"%g\" at %g, %g centre front rotate by %d\n", j, c[j], a[j], b[j], r[j]
}
}' ""
此脚本具有以下参数:
#1 -> 包含 GNUplot 生成的轮廓数据的文件
#2 -> 旗帜。如果它是“0”,则打印 GNUplot 的脚本以在图中添加标签。如果它是'1',取出等高线的点,这样等高线图的线就不会越过标签
#3 -> 格式化标签的空格数
#4 -> 偏移以移动标签的空白(因此它们不居中)
我使用 wxt 终端的结果是:
结果是:
生成绘图的代码是:
reset
#Function map values on desired ranges. The values set to 90,95,99 are for later labelling
step90(x) = (x < 20.0 ? 0 : (x < 50.0 ? 10 : (x < 75.0 ? 20 : (x < 90.0 ? 80 : (x < 95.0 ? 90 : (x < 97.5 ? 95 : (x < 99.0 ? 97 : (x < 99.5 ? 99 : (x < 99.9 ? 100 : 101 )))))))))
# enable 3D data read from a scattered data set in file
#71,46,10 are the number of different values for each axis X,Y,Z in "HeatMap_Test.txt" data file
#If values of dgrid3d are not set accordingly, weird contour values will be generated
set dgrid3d 71,46,10
set contour base # enable contour drawing
set view 0,0 # if you want to see the graph from above (2D plot)
unset surface # do not plot the surface, only the contour
set cntrparam levels discrete 90,95,99 #set contours only on values 90,95 and 99
set table "contours.dat" #Name of the output file to write the table
splot "HeatMap_Test.txt" u 2:1:(step90()) notitle
unset table #Write table to file
reset
#Map the Z values to desired ranges
step(x) = (x < 20.0 ? 0 : (x < 50.0 ? 1 : (x < 75.0 ? 2 : (x < 90.0 ? 3 : (x < 95.0 ? 4 : (x < 97.5 ? 5 : (x < 99.0 ? 6 : (x < 99.5 ? 7 : (x < 99.9 ? 8 : 9 )))))))))
set palette maxcolors 10
set palette defined (0 "#333399", 1 "#3333f7", 2 "#3373ff", 3 "#33c6ff", 4 "#5affd2", 5 "#9cff8f", 6 "#dfff4c", 7 "#ffc733", 8 "#ff7a33", 9 "#e53333")
set cbrange [-0.5:9.5]
set cbtics nomirror
set cbtics ( ">99.9" 9, ">99.5" 8, ">99.0" 7, ">97.5" 6, ">95.0" 5, ">90.0" 4, ">75.0" 3, ">50.0" 2, ">20.0" 1, ">10.0" 0 )
set cblabel "%" norotate offset -8, 12
set xrange [-30:40]
set yrange [ 25:70]
set xtics 5
set ytics 5
set grid front linetype -1
set grid xtics lt 0 lw 1 lc rgb "#000000"
set grid ytics lt 0 lw 1 lc rgb "#000000"
load "<./draw_contourlines_label.sh contours.dat 0 4 0"
plot "HeatMap_Test.txt" u 2:1:(step()) with image, "world_10m.txt" notitle with lines ls 1 lc -1, "<./draw_contourlines_label.sh contours.dat 1 3 0" u 1:2 w l lw 2 lc 0 notitle
注意: 如果文件 "contours.dat" 是使用 GNUplot 4.6.4 计算的,标签不会以相同的方式出现。计算文件后,4.6+ 版本显示相同的图。
我们也可以使用 @maij 方法使用 splot 函数。为此,我们首先需要按照他所说的那样更改阶跃函数,否则会产生奇怪的线条。我将函数重命名为step3D,但正是@maij在上面发布的:
step(x) = (x < 20.0 ? 0 : \
(x < 50.0 ? 10 : \
(x < 75.0 ? 20 : \
(x < 90.0 ? 80 : \
(x < 95.0 ? 89.999 : \
(x < 97.5 ? 94.999 : \
(x < 99.0 ? 97 : \
(x < 99.5 ? 98.999 : \
(x < 99.9 ? 100 : 101 )))))))))
有了splot,还需要将输入文件格式化成块。我用这个简单的 awk 脚本做了,它可以直接放在 splot 命令中:
awk 'NF>=1 && !~/#/ && !=prev {print \"\"} {prev=;print}' HeatMap_Test.txt
在 GNUplot 5+ 中,当绘制 colobar 百分比时出现 half-cutted,并且 x 和 y 标签过于分离,因此我不得不使用以下命令手动调整它们以适应屏幕:
set rmargin at screen 0.8
set lmargin at screen 0.08
set tmargin at screen 0.95
set xtics offset 0, screen 0.036
set ytics offset screen 0.008, 0
等高线是用相同的命令绘制的,所以得到的结果是相似的(只是等高线由于范围的原因有点变化):
生成绘图的代码是:
reset
#Function map values on desired ranges. The values set to 90,95,99 are for later labelling
step3D(x) = (x < 20.0 ? 0 : (x < 50.0 ? 10 : (x < 75.0 ? 20 : (x < 90.0 ? 80 : (x < 95.0 ? 89.999 : (x < 97.5 ? 94.999 : (x < 99.0 ? 97 : (x < 99.5 ? 98.999 : (x < 99.9 ? 100 : 101 )))))))))
# enable 3D data read from a scattered data set in file
#71,46,10 are the number of different values for each axis X,Y,Z in "HeatMap_Test.txt" data file
#If values of dgrid3d are not set accordingly, weird contour values will be generated
set dgrid3d 71,46,10
set contour base # enable contour drawing
set view 0,0 # if you want to see the graph from above (2D plot)
unset surface # do not plot the surface, only the contour
set cntrparam levels discrete 90,95,99 #set contours only on values 90,95 and 99
set table "contours.dat" #Name of the output file to write the table
splot "HeatMap_Test.txt" u 2:1:(step3D()) notitle
unset table #Write table to file
reset
#Map the Z values to desired ranges
step(x) = (x < 20.0 ? 0 : (x < 50.0 ? 1 : (x < 75.0 ? 2 : (x < 90.0 ? 3 : (x < 95.0 ? 4 : (x < 97.5 ? 5 : (x < 99.0 ? 6 : (x < 99.5 ? 7 : (x < 99.9 ? 8 : 9 )))))))))
set palette maxcolors 10
set palette defined (0 "#333399", 1 "#3333f7", 2 "#3373ff", 3 "#33c6ff", 4 "#5affd2", 5 "#9cff8f", 6 "#dfff4c", 7 "#ffc733", 8 "#ff7a33", 9 "#e53333")
set cbrange [-0.5:9.5]
set cbtics nomirror
set cbtics ( ">99.9" 9, ">99.5" 8, ">99.0" 7, ">97.5" 6, ">95.0" 5, ">90.0" 4, ">75.0" 3, ">50.0" 2, ">20.0" 1, ">10.0" 0 )
set cblabel "%" norotate offset -8, 11.5
set xrange [-30:40]
set yrange [ 25:70]
set xtics 5
set ytics 5
set grid front linetype -1
set grid xtics lt 0 lw 1 lc rgb "#000000"
set grid ytics lt 0 lw 1 lc rgb "#000000"
set rmargin at screen 0.8
set lmargin at screen 0.08
set tmargin at screen 0.95
set xtics offset 0, screen 0.036
set ytics offset screen 0.008, 0
set pm3d explicit
set view map
load "<./draw_contourlines_label.sh contours.dat 0 4 0"
splot "< awk 'NF>=1 && !~/#/ && !=prev {print \"\"} {prev=;print}' HeatMap_Test.txt" u 2:1:(0):(step()) notitle w pm3d lc palette ,"world_10m.txt" u 1:2:(0) notitle with lines ls 1 lc rgb "#ffffff", "<./draw_contourlines_label.sh contours.dat 1 3 0" u 1:2:(0) w l lw 2 lc rgb "#000000" notitle
注意: 如果您是 Windows 用户,您也可以使用 Cygwin 的 GNUPlot 版本
绘制此图
在
这是我目前的剧情:
生成绘图的代码:
reset
#Function map values on desired ranges. The values set to 90,95,99 are for later labelling
step(x) = (x < 20.0 ? 0 : (x < 50.0 ? 10 : (x < 75.0 ? 20 : (x < 90.0 ? 80 : (x < 95.0 ? 90 : (x < 97.5 ? 95 : (x < 99.0 ? 97 : (x < 99.5 ? 99 : (x < 99.9 ? 100 : 101 )))))))))
# enable 3D data read from a scattered data set in file
#71,46,10 are the number of different values for each axis X,Y,Z in "HeatMap_Test.txt" data file
#If values of dgrid3d are not set accordingly, weird contour values will be generated
set dgrid3d 71,46,10
set contour base # enable contour drawing
set cntrlabel font ",7"
set view 0,0 # if you want to see the graph from above (2D plot)
unset surface # do not plot the surface, only the contour
set cntrparam levels discrete 90,95,99 #set contours only on values 90,95 and 99
set table "contours.dat" #Name of the output file to write the table
splot "HeatMap_Test.txt" u 2:1:(step()) with lines notitle
unset table #Write table to file
reset
#Map the Z values to desired ranges
step(x) = (x < 20.0 ? 0 : (x < 50.0 ? 1 : (x < 75.0 ? 2 : (x < 90.0 ? 3 : (x < 95.0 ? 4 : (x < 97.5 ? 5 : (x < 99.0 ? 6 : (x < 99.5 ? 7 : (x < 99.9 ? 8 : 9 )))))))))
set palette maxcolors 10
set palette defined (0 "#333399", 1 "#3333f7", 2 "#3373ff", 3 "#33c6ff", 4 "#5affd2", 5 "#9cff8f", 6 "#dfff4c", 7 "#ffc733", 8 "#ff7a33", 9 "#e53333")
set cbrange [-0.5:9.5]
set cbtics nomirror
set cbtics ( ">99.9" 9, ">99.5" 8, ">99.0" 7, ">97.5" 6, ">95.0" 5, ">90.0" 4, ">75.0" 3, ">50.0" 2, ">20.0" 1, ">10.0" 0 )
set xrange [-30:40]
set yrange [ 25:70]
set xtics 5
set ytics 5
#set title " %"
set grid front linetype -1
set grid xtics lt 0 lw 1 lc rgb "#000000"
set grid ytics lt 0 lw 1 lc rgb "#000000"
plot "HeatMap_Test.txt" u 2:1:(step()) notitle pt 5 ps 2 lc palette, "world_10m.txt" notitle with lines ls 1 lc -1, "contours.dat" u 1:2 w l lw 2 lc 0 notitle
这里是数据文件:HeatMap_Test.txt, world_10m.txt
该代码适用于 GNUplot 4.6 和 5(我在 Linux 下工作)
为了得到我想要的剧情,我还要做三件事:
1) 标注等高线(从内到外用99、95、90)
2) 使边界线适合绘图(图中热图越过边界)
3) 将标题(在本例中为单个“%”)放在颜色栏的顶部。一种肮脏的做法是设置一个普通的标题并放置空格(代码中有一个注释行可以做到这一点),但我认为必须有更好的方法。
我标记轮廓的想法如下图所示:
感谢您的帮助
让我们从数字开始 3: 颜色条的标题。
您想在颜色栏顶部设置 cblabel
。虽然我不认为这可以自动完成,但您可以像这样使用 offset x,y
:
set cblabel "%" norotate offset -6, 9
仍然是 hack,但我认为这比滥用标题要好。
现在编号2: 使边界线适合情节。
越过边界线的原因是(隐含的)命令plot with points pointsize 2
。仅绘制在边界上的点将重叠。我建议用这样的 splot pm3d
替换这些点:
set pm3d explicit
set view map
splot "HeatMap_Test_2.txt" u 2:1:(0):(step()) notitle w pm3d lc palette , \
"world_10m.txt" u 1:2:(0) notitle with lines ls 1 lc rgb "#ffffff" , \
"contours.dat" u 1:2:(0) w l lw 2 lc rgb "#000000" notitle
为了让这个 3D 绘图起作用,我做了以下操作:
- 添加一个虚拟 z 列,数字
(0)
- 格式化"HeadMap_test.txt"成块,即每次纬度扫描后插入一个空行
来自:
...
25.00 38.00 15.9
25.00 39.00 5.3
25.00 40.00 1.6
26.00 -30.00 0.0
26.00 -29.00 0.3
26.00 -28.00 0.7
...
至:
...
25.00 38.00 15.9
25.00 39.00 5.3
25.00 40.00 1.6
26.00 -30.00 0.0
26.00 -29.00 0.3
26.00 -28.00 0.7
...
- 而且我不得不稍微调整第一步函数来找到轮廓,我已经稍微降低了步长值 90、95 和 99
像这样:
step(x) = (x < 20.0 ? 0 : \
(x < 50.0 ? 10 : \
(x < 75.0 ? 20 : \
(x < 90.0 ? 80 : \
(x < 95.0 ? 89.999 : \
(x < 97.5 ? 94.999 : \
(x < 99.0 ? 97 : \
(x < 99.5 ? 98.999 : \
(x < 99.9 ? 100 : 101 )))))))))
现在,有了 pngcairo 终端和 Gnuplot 4.6,我们应该已经到达这里了:
和编号1: 标记等高线
我没试过,但也许this post可以帮到你。
终于明白了,多亏了@maij, using the link他的回答。
对于问题编号 3,我使用了带有以下参数的 @maij 行:
set cblabel "%" norotate offset -8, 12
问题编号 2,绘制热图时,我不得不从
plot "HeatMap_Test.txt" u 2:1:(step()) notitle pt 5 ps 2 lc palette
到
plot "HeatMap_Test.txt" u 2:1:(step()) with image
最后,问题号 1,为了将标签放在轮廓线中,我不得不使用与以前相同的 link 中提供的外部 awk 脚本.我将脚本命名为draw_contourlines_label.sh,脚本内容为:
#!/bin/bash
awk -v d= -v w= -v os= 'function abs(x) { return (x>=0?x:-x) }
{
if([=13=]~/# Contour/) nr=0
if(nr==int(os+w/2) && d==0) {a[i]=; b[i]=; c[i]=;}
if(nr==int(os+w/2)-1 && d==0) {i++; x = ; y = ;}
if(nr==int(os+w/2)+1 && d==0) r[i]= 180.0*atan2(y-, x-)/3.14
if(abs(nr-os-w/2)>w/2 && d==1) print [=13=]
nr++
}
END { if(d==0) {
for(j=1;j<=i;j++)
printf "set label %d \"%g\" at %g, %g centre front rotate by %d\n", j, c[j], a[j], b[j], r[j]
}
}' ""
此脚本具有以下参数:
#1 -> 包含 GNUplot 生成的轮廓数据的文件
#2 -> 旗帜。如果它是“0”,则打印 GNUplot 的脚本以在图中添加标签。如果它是'1',取出等高线的点,这样等高线图的线就不会越过标签
#3 -> 格式化标签的空格数
#4 -> 偏移以移动标签的空白(因此它们不居中)
我使用 wxt 终端的结果是:
结果是:
生成绘图的代码是:
reset
#Function map values on desired ranges. The values set to 90,95,99 are for later labelling
step90(x) = (x < 20.0 ? 0 : (x < 50.0 ? 10 : (x < 75.0 ? 20 : (x < 90.0 ? 80 : (x < 95.0 ? 90 : (x < 97.5 ? 95 : (x < 99.0 ? 97 : (x < 99.5 ? 99 : (x < 99.9 ? 100 : 101 )))))))))
# enable 3D data read from a scattered data set in file
#71,46,10 are the number of different values for each axis X,Y,Z in "HeatMap_Test.txt" data file
#If values of dgrid3d are not set accordingly, weird contour values will be generated
set dgrid3d 71,46,10
set contour base # enable contour drawing
set view 0,0 # if you want to see the graph from above (2D plot)
unset surface # do not plot the surface, only the contour
set cntrparam levels discrete 90,95,99 #set contours only on values 90,95 and 99
set table "contours.dat" #Name of the output file to write the table
splot "HeatMap_Test.txt" u 2:1:(step90()) notitle
unset table #Write table to file
reset
#Map the Z values to desired ranges
step(x) = (x < 20.0 ? 0 : (x < 50.0 ? 1 : (x < 75.0 ? 2 : (x < 90.0 ? 3 : (x < 95.0 ? 4 : (x < 97.5 ? 5 : (x < 99.0 ? 6 : (x < 99.5 ? 7 : (x < 99.9 ? 8 : 9 )))))))))
set palette maxcolors 10
set palette defined (0 "#333399", 1 "#3333f7", 2 "#3373ff", 3 "#33c6ff", 4 "#5affd2", 5 "#9cff8f", 6 "#dfff4c", 7 "#ffc733", 8 "#ff7a33", 9 "#e53333")
set cbrange [-0.5:9.5]
set cbtics nomirror
set cbtics ( ">99.9" 9, ">99.5" 8, ">99.0" 7, ">97.5" 6, ">95.0" 5, ">90.0" 4, ">75.0" 3, ">50.0" 2, ">20.0" 1, ">10.0" 0 )
set cblabel "%" norotate offset -8, 12
set xrange [-30:40]
set yrange [ 25:70]
set xtics 5
set ytics 5
set grid front linetype -1
set grid xtics lt 0 lw 1 lc rgb "#000000"
set grid ytics lt 0 lw 1 lc rgb "#000000"
load "<./draw_contourlines_label.sh contours.dat 0 4 0"
plot "HeatMap_Test.txt" u 2:1:(step()) with image, "world_10m.txt" notitle with lines ls 1 lc -1, "<./draw_contourlines_label.sh contours.dat 1 3 0" u 1:2 w l lw 2 lc 0 notitle
注意: 如果文件 "contours.dat" 是使用 GNUplot 4.6.4 计算的,标签不会以相同的方式出现。计算文件后,4.6+ 版本显示相同的图。
我们也可以使用 @maij 方法使用 splot 函数。为此,我们首先需要按照他所说的那样更改阶跃函数,否则会产生奇怪的线条。我将函数重命名为step3D,但正是@maij在上面发布的:
step(x) = (x < 20.0 ? 0 : \
(x < 50.0 ? 10 : \
(x < 75.0 ? 20 : \
(x < 90.0 ? 80 : \
(x < 95.0 ? 89.999 : \
(x < 97.5 ? 94.999 : \
(x < 99.0 ? 97 : \
(x < 99.5 ? 98.999 : \
(x < 99.9 ? 100 : 101 )))))))))
有了splot,还需要将输入文件格式化成块。我用这个简单的 awk 脚本做了,它可以直接放在 splot 命令中:
awk 'NF>=1 && !~/#/ && !=prev {print \"\"} {prev=;print}' HeatMap_Test.txt
在 GNUplot 5+ 中,当绘制 colobar 百分比时出现 half-cutted,并且 x 和 y 标签过于分离,因此我不得不使用以下命令手动调整它们以适应屏幕:
set rmargin at screen 0.8
set lmargin at screen 0.08
set tmargin at screen 0.95
set xtics offset 0, screen 0.036
set ytics offset screen 0.008, 0
等高线是用相同的命令绘制的,所以得到的结果是相似的(只是等高线由于范围的原因有点变化):
生成绘图的代码是:
reset
#Function map values on desired ranges. The values set to 90,95,99 are for later labelling
step3D(x) = (x < 20.0 ? 0 : (x < 50.0 ? 10 : (x < 75.0 ? 20 : (x < 90.0 ? 80 : (x < 95.0 ? 89.999 : (x < 97.5 ? 94.999 : (x < 99.0 ? 97 : (x < 99.5 ? 98.999 : (x < 99.9 ? 100 : 101 )))))))))
# enable 3D data read from a scattered data set in file
#71,46,10 are the number of different values for each axis X,Y,Z in "HeatMap_Test.txt" data file
#If values of dgrid3d are not set accordingly, weird contour values will be generated
set dgrid3d 71,46,10
set contour base # enable contour drawing
set view 0,0 # if you want to see the graph from above (2D plot)
unset surface # do not plot the surface, only the contour
set cntrparam levels discrete 90,95,99 #set contours only on values 90,95 and 99
set table "contours.dat" #Name of the output file to write the table
splot "HeatMap_Test.txt" u 2:1:(step3D()) notitle
unset table #Write table to file
reset
#Map the Z values to desired ranges
step(x) = (x < 20.0 ? 0 : (x < 50.0 ? 1 : (x < 75.0 ? 2 : (x < 90.0 ? 3 : (x < 95.0 ? 4 : (x < 97.5 ? 5 : (x < 99.0 ? 6 : (x < 99.5 ? 7 : (x < 99.9 ? 8 : 9 )))))))))
set palette maxcolors 10
set palette defined (0 "#333399", 1 "#3333f7", 2 "#3373ff", 3 "#33c6ff", 4 "#5affd2", 5 "#9cff8f", 6 "#dfff4c", 7 "#ffc733", 8 "#ff7a33", 9 "#e53333")
set cbrange [-0.5:9.5]
set cbtics nomirror
set cbtics ( ">99.9" 9, ">99.5" 8, ">99.0" 7, ">97.5" 6, ">95.0" 5, ">90.0" 4, ">75.0" 3, ">50.0" 2, ">20.0" 1, ">10.0" 0 )
set cblabel "%" norotate offset -8, 11.5
set xrange [-30:40]
set yrange [ 25:70]
set xtics 5
set ytics 5
set grid front linetype -1
set grid xtics lt 0 lw 1 lc rgb "#000000"
set grid ytics lt 0 lw 1 lc rgb "#000000"
set rmargin at screen 0.8
set lmargin at screen 0.08
set tmargin at screen 0.95
set xtics offset 0, screen 0.036
set ytics offset screen 0.008, 0
set pm3d explicit
set view map
load "<./draw_contourlines_label.sh contours.dat 0 4 0"
splot "< awk 'NF>=1 && !~/#/ && !=prev {print \"\"} {prev=;print}' HeatMap_Test.txt" u 2:1:(0):(step()) notitle w pm3d lc palette ,"world_10m.txt" u 1:2:(0) notitle with lines ls 1 lc rgb "#ffffff", "<./draw_contourlines_label.sh contours.dat 1 3 0" u 1:2:(0) w l lw 2 lc rgb "#000000" notitle
注意: 如果您是 Windows 用户,您也可以使用 Cygwin 的 GNUPlot 版本
绘制此图