如何在gnuplot中实现条件可选绘图且避免警告
Gnuplot动态控制绘图数据集数量(无警告版)
问题场景
你在循环绘制多图时,需要根据条件决定是否包含某个数据集——比如第1、3幅图要画背景、前景A、前景B,第2幅只画背景和前景A。用/dev/null占位虽然能实现效果,但会弹出烦人的“无有效数据点”警告,又不想手动拆循环(循环前代码太多,重复写太麻烦),也不想屏蔽所有错误输出。
解决方案:动态拼接plot命令字符串
Gnuplot支持把命令写成字符串,再用eval()执行,这样就能根据条件动态增减绘图项,完全避开无效文件的加载。修改后的代码如下:
set multiplot layout 3, 1 array names[3] = ["foo", "bar", "baz"] do for [i=1:3] { background = names[i]."-bg.txt" foregroundA = names[i]."-fg.txt" # 先构建必选的两个绘图项命令 plot_cmd = sprintf('plot "%s" using 1:2:3 with image palette, "%s" using 1:2 with lines', background, foregroundA) # 只有非第2幅图时,才追加前景B的绘图项 if (i != 2) { foregroundB = "< ./stuff" plot_cmd = plot_cmd . sprintf(', "%s" using 1:2 with points', foregroundB) } # 执行最终拼接好的plot命令 eval(plot_cmd) } unset multiplot
方案优势
- 根本不会在不需要的时候加载任何无效文件,自然不会触发警告
- 循环结构完全保留,循环前的代码只写一次,避免冗余
- 逻辑清晰,条件判断直接控制绘图项的有无,比占位符更直观
备选方案:用空的inline数据集
如果不想用字符串拼接,也可以提前定义一个空的inline数据集,当不需要前景B时指向它——这个方法同样不会产生警告,示例如下:
# 提前定义空的inline数据集 $EMPTY << EOD EOD set multiplot layout 3, 1 array names[3] = ["foo", "bar", "baz"] do for [i=1:3] { background = names[i]."-bg.txt" foregroundA = names[i]."-fg.txt" foregroundB = (i == 2 ? "$EMPTY" : "< ./stuff") plot background u 1:2:3 w image palette, \ foregroundA u 1:2 w lines, \ foregroundB u 1:2 w points } unset multiplot
内容的提问来源于stack exchange,提问作者A1987dM
相关产品推荐
相关产品推荐

