Gnuplot循环绘制月度气象等高图报错:expecting discrete level
解决gnuplot循环绘制月等高图时的"expecting discrete level"错误
问题核心
在gnuplot 6.1中用do-loop批量绘制月度等高图时,动态计算的等高线级别未被正确解析为离散值列表,导致触发"expecting discrete level"错误;但单月单独运行时,级别计算是即时的,因此能正常执行。
解决方案
每次循环迭代中,先筛选当月数据并计算z值范围,再显式生成离散的等高线级别字符串,最后通过变量引用传递给set cntrparam命令,确保gnuplot能识别为合法的离散级别。
修正后的脚本
# 数据集格式:unix_timestamp x y z DATAFILE = "weather_data.txt" # 时间范围:2022年7月至2024年10月 start_year = 2022 start_month = 7 end_year = 2024 end_month = 10 # 遍历年份 do for [year=start_year:end_year] { # 确定当年的月份范围 m_start = (year == start_year) ? start_month : 1 m_end = (year == end_year) ? end_month : 12 # 遍历当月份 do for [month=m_start:m_end] { # 计算当月的时间戳边界 start_ts = strptime("%Y-%m-%d", sprintf("%d-%02d-01", year, month)) end_ts = strptime("%Y-%m-%d", sprintf("%d-%02d-01", year, month+1)) # 统计当月z值的最小/最大值 stats DATAFILE using ( ($1 >= start_ts && $1 < end_ts) ? $4 : NaN ) nooutput z_min = STATS_min z_max = STATS_max # 生成10级离散等高线级别字符串 level_count = 10 delta = (z_max - z_min)/(level_count - 1) levels = "" do for [i=0:level_count-1] { levels = levels.sprintf("%.2f,", z_min + i*delta) } levels = substr(levels, 1, strlen(levels)-1) # 移除末尾逗号 # 绘图参数设置 set terminal pngcairo size 800,600 set output sprintf("contour_%d%02d.png", year, month) set title sprintf("%d年%d月气象要素等高图", year, month) set xlabel "X" set ylabel "Y" set zlabel "Z" set contour base set cntrparam levels discrete @levels # 引用生成的离散级别 set view map # 绘制当月等高图 plot DATAFILE using ( ($1 >= start_ts && $1 < end_ts) ? $2 : NaN ) : \ ( ($1 >= start_ts && $1 < end_ts) ? $3 : NaN ) : \ ( ($1 >= start_ts && $1 < end_ts) ? $4 : NaN ) \ with lines title "Z Contour" } }
精简数据集示例(weather_data.txt)
1656633600 10 20 15.2 1656633600 10 30 16.8 1656720000 20 20 14.5 1688169600 15 25 22.3 1688256000 25 35 23.1 1727798400 30 40 28.7 1727884800 20 30 27.5
关键细节说明
- 用
stats命令在每次循环中单独计算当月z值范围,避免跨月份数据干扰计算结果 - 显式拼接等高线级别字符串并通过
@levels引用,确保gnuplot将其识别为离散级别列表,而非未解析的表达式 - 时间戳计算使用
strptime和sprintf保证月份边界的准确性,避免出现数据漏选或多选
内容的提问来源于stack exchange,提问作者ifffam
相关产品推荐
相关产品推荐

