如何用gnuplot绘制含方括号数据列的CSV文件
处理CSV数据并绘制gnuplot可视化的方案
第一步:数据预处理(拆分向量列)
gnuplot对嵌套在方括号里的多值列支持有限,先把数据转换成每行对应一个样本点的格式,用awk脚本最方便:
#!/usr/bin/awk -F ',' BEGIN { FS = ","; OFS = ","; } { # 提取基础字段 datetime = $1; dev_id = $2; # 去除volt列的方括号,分割成数组 gsub(/\[|\]/, "", $3); n = split($3, volt_arr, " "); # 去除temp列的方括号,分割成数组 gsub(/\[|\]/, "", $4); split($4, temp_arr, " "); # 循环输出每个样本点 for(i=1; i<=n; i++){ print datetime, dev_id, i-1, volt_arr[i], temp_arr[i]; } }
把上面的脚本保存为preprocess.awk,然后执行:
awk -f preprocess.awk input.csv > processed.csv
处理后的数据每行格式为:日期时间,设备ID,样本索引(0-415),volt值,temp值,原20万行会扩展为20万×416行,这种结构化数据更适配gnuplot的绘图逻辑。
第二步:绘制堆叠栅栏图
这里的堆叠栅栏图以时间为X轴,每个设备对应一组,每组内按样本索引堆叠显示数值(以volt为例),用gnuplot的boxes样式实现:
set datafile separator "," set terminal pngcairo size 1200,800 set output "stacked_fence.png" # 配置时间格式(根据你的CSV日期格式调整,示例为"%Y-%m-%d %H:%M:%S") set xdata time set timefmt "%Y-%m-%d %H:%M:%S" set format x "%H:%M" # 按需调整显示格式 # 给不同设备设置时间轴偏移量,实现分组 dev_offsets = {"1":0, "4":1, "5":2, "6":3, "7":4, "10":5} group_width = 0.8 sample_width = group_width / 416 # 绘制volt值的堆叠栅栏图,替换为:5可绘制temp值 plot for [dev in dev_offsets] \ "processed.csv" using (timecolumn(1) + dev_offsets[dev]*3600):4:(sample_width) \ every ::0::0 using (strcol(2) eq dev ? $3 : NaN) \ with boxes fill solid 0.7 title "Dev " . dev, \ for [dev in dev_offsets] \ "processed.csv" using (timecolumn(1) + dev_offsets[dev]*3600):(0) \ every ::0::0 using (strcol(2) eq dev ? 1 : NaN) \ with labels offset 0,-1.5 textcolor rgb "black" title ""
通过时间轴偏移量区分不同设备组,每个样本点对应一个窄盒子,堆叠后形成栅栏效果。
第三步:绘制曲面图
曲面图以时间为X轴、样本索引为Y轴、数值为Z轴,用gnuplot的pm3d样式实现:
set datafile separator "," set terminal pngcairo size 1200,800 set output "volt_surface.png" set xdata time set timefmt "%Y-%m-%d %H:%M:%S" set format x "%H:%M" set ylabel "Sample Index" set zlabel "Voltage" set pm3d at b set view 60,30 # 调整视角 # 绘制设备1的volt曲面,替换dev值可切换其他设备,替换为:5可绘制temp值 plot "processed.csv" using 1:3:4 every ::0::0 using (strcol(2) eq "1" ? $1 : NaN) \ with pm3d title "Device 1 Voltage Surface"
如果要同时展示所有设备的曲面,用multiplot分屏绘制:
set multiplot layout 2,3 title "Device Voltage Surfaces" set xdata time set timefmt "%Y-%m-%d %H:%M:%S" set format x "%H:%M" set ylabel "Sample Index" set zlabel "Voltage" set pm3d at b dev_list = ["1", "4", "5", "6", "7", "10"] do for [i=1:6] { dev = dev_list[i] set title "Dev " . dev plot "processed.csv" using 1:3:4 every ::0::0 using (strcol(2) eq dev ? $1 : NaN) with pm3d notitle } unset multiplot
内容的提问来源于stack exchange,提问作者Sina Atabak
相关产品推荐
相关产品推荐

