基于Gnuplot的变长数据多图绘制及RMSE可视化技术求助
Gnuplot 脚本实现多模型RMSE可视化方案
1. 批量生成带模型图形的独立RMSE图
假设转置后的Data file2格式为:每行对应一个模型,第一列是模型名,后续列是该模型在不同场景下的RMSE值;Data file1格式为每个模型的X/Y数据块以# 模型名开头分隔。
以下脚本会循环处理每个模型,生成以模型名命名的PNG文件,同时将对应模型的图形嵌入到RMSE柱状图的右上角:
# 设置全局样式 set terminal pngcairo enhanced font 'Arial,10' size 800,600 set style data histogram set style fill solid 0.7 border -1 set boxwidth 0.8 set ylabel "RMSE" set grid y # 读取Data file2的模型总数 stats "Data file2" using 1 nooutput model_count = STATS_records # 循环处理每个模型 do for [i=1:model_count] { # 提取当前模型名 model_name = system(sprintf("sed -n '%dp' 'Data file2' | awk '{print $1}'", i)) output_file = sprintf("%s_RMSE.png", model_name) set output output_file # 开启多图模式,组合RMSE柱状图和模型图形 set multiplot layout 2,2 rowsfirst margins 0.1,0.9,0.1,0.9 # 主图:RMSE柱状图 unset key set title sprintf("RMSE of %s", model_name) plot "Data file2" index i-1 using 2:xtic(1) histogram, \ '' index i-1 using 0:2:($2) with labels offset 0,1 font ',8' # 右上角嵌入模型图形 set origin 0.65,0.65 set size 0.3,0.3 unset title unset ylabel unset grid set key off # 从Data file1中筛选当前模型的X/Y数据 plot "<grep -A 1000 '# ".model_name."' Data file1 | grep -v '#'" using 1:2 with lines title model_name unset multiplot }
核心逻辑:
- 用
stats获取模型总数,通过循环遍历每个模型 - 调用
sed/awk提取模型名,生成对应输出文件名 - 利用
multiplot在同一张图中绘制主柱状图和右上角的模型小图 - 通过
grep从Data file1中筛选当前模型的X/Y数据
2. 柱子顶部显示RMSE数值
在柱状图的plot命令中添加with labels即可实现,核心代码片段:
plot "Data file2" using 2:xtic(1) histogram, \ '' using 0:2:($2) with labels offset 0,1 font ',8'
using 0:2:($2):0对应柱子的X轴位置,2是RMSE值(Y轴位置),第三个$2为要显示的数值offset 0,1:将标签向上偏移1个单位,避免与柱子重叠font ',8':设置标签字体大小
3. 支持行/列方向绘图
通过定义变量控制数据读取维度,实现行方向(按模型绘图)和列方向(按场景绘图)的切换:
# 选择绘图方向:row(按模型)或col(按场景) plot_direction = "row" # 可改为"col" set terminal pngcairo enhanced font 'Arial,10' size 1000,600 set style data histogram set style fill solid 0.7 border -1 set boxwidth 0.8 set ylabel "RMSE" set grid y set key outside if (plot_direction eq "row") { # 行方向:每个模型一行,绘制该模型所有场景的RMSE stats "Data file2" using 1 nooutput model_count = STATS_records set title "RMSE by Model (Row Direction)" plot for [i=1:model_count] "Data file2" index i-1 using 2:xtic(1) title sprintf("Model %d", i), \ for [i=1:model_count] '' index i-1 using 0:2:($2) with labels offset 0,1 font ',8' } else { # 列方向:每个场景一行,绘制所有模型在该场景下的RMSE stats "Data file2" using '*' nooutput scene_count = STATS_columns - 1 # 减去第一列的模型名 set title "RMSE by Scene (Column Direction)" plot for [j=2:scene_count+1] "Data file2" using j:xtic(1) title sprintf("Scene %d", j-1), \ for [j=2:scene_count+1] '' using 0:j:($j) with labels offset 0,1 font ',8' }
核心逻辑:
- 定义
plot_direction变量,切换row/col模式 - 行方向:循环遍历每个模型行,绘制该行的RMSE数据
- 列方向:通过
STATS_columns获取场景数量,循环遍历每个数据列,绘制所有模型在该场景下的RMSE
内容的提问来源于stack exchange,提问作者user86927
相关产品推荐
相关产品推荐

