如何在gnuplot中遍历所有数据集及列并完整绘制所有曲线?
解决Gnuplot遍历多数据集多列绘图的问题
你有一个以空行分隔多数据集的数据文件,每个数据集列数不固定,首行是对应列的标题。使用Gnuplot 5.4 patchlevel 2时,直接用for [i=1:*]循环列或指定超过实际列数的范围,会导致部分曲线(比如示例中的c列)消失。
问题原因
Gnuplot默认的for [i=1:*]循环范围是基于文件第一个数据集的列数生成的,后续数据集列数少于该值时,循环到超出列数的i会被跳过;同时全局循环列会让不同数据集的同序号列共用同一个表头标题,导致曲线混淆或被覆盖。
解决方案
需要同时遍历每个数据集和对应数据集内的列,通过stats命令获取每个数据集的列数,再逐一绘制每一列并使用对应表头作为标题。
完整脚本示例
# 统计文件中的数据集总数(空行分隔的块数) stats 'gp.dat' nooutput total_blocks = STATS_blocks # 初始化绘图命令字符串 plot_command = "" # 遍历每个数据集 do for [block_idx=1:total_blocks] { # 仅统计当前数据集的列数 stats 'gp.dat' every :::block_idx::block_idx nooutput cols_in_block = STATS_columns # 遍历当前数据集的每一列 do for [col_idx=1:cols_in_block] { # 获取当前列的表头文字(取数据集第一行的对应列) set print $COL_HEADER print 'gp.dat' every ::0::0 :::block_idx::block_idx using col_idx set print header_text = $COL_HEADER[1] # 拼接绘图指令:指定数据集、列,用表头做图例 plot_command = plot_command . sprintf( \ "'gp.dat' every :::%d::%d using 0:%d title '%s' with lines, ", \ block_idx, block_idx, col_idx, header_text \ ) } } # 移除末尾多余的逗号和空格,执行绘图 plot_command = substr(plot_command, 1, strlen(plot_command)-2) eval(plot_command)
关键步骤解释
stats 'gp.dat' nooutput:静默统计文件,STATS_blocks返回数据集的总数量。every :::block_idx::block_idx:指定只处理第block_idx个数据集(Gnuplot中数据集从1开始计数)。set print $COL_HEADER:临时将当前数据集第一行的目标列内容写入变量,用作曲线标题。- 最后通过
eval()执行拼接好的完整绘图命令,确保每一列都被单独绘制,且标题与表头对应。
简化替代写法
如果不需要单独控制每个数据集的样式,也可以用嵌套循环直接绘制(需确保每个数据集首行是有效表头):
stats 'gp.dat' nooutput plot for [b=0:STATS_blocks-1] for [c=1:*] 'gp.dat' index b using 0:c title columnhead(c) with lines
内容的提问来源于stack exchange,提问作者Apocalypse Mystic
相关产品推荐
相关产品推荐

