愚蠢的绘图

最近要为论文加入一张Voronoi镶嵌的概念图。这类图在之前用Matlab编写运算程序的时候就有方便的赝色函数把各个区块映射成一张彩色图。可这几个月来我对Gnuplot非常着迷,所有的图都想用她来画。昨天花了十几分钟自定义了一个函数,用三个if判断用来划分三个不同的区域,然后再把这三个区域分别涂上红黄蓝的三原色。虽然麻烦了点,但不用借助别的软件来生成数据,一小段代码完整又清晰,对比不同分辨率只要一个参数即可解决。自觉有些得意。

nav_demo_bad

一试用却发现问题。红黄之间的区域总有一条蓝色夹在中间。这条不该出现的色彩很奇怪,我用了半个小时才终于明白原因所在。这张图是用splot命令做曲面图然后再用colorbar映射颜色实现的。为此红色区域对应的数值为1,蓝色为2,黄色为3。这三个区域的接缝处自然是直上直下地跳跃,如从1直接跳到2。可从1跳到3必经过2,所以红黄之间夹着蓝色。本以为降低取样值就可解决,实际发现没有变化。因为从1到3的跳跃也是所绘制的曲面的一部分,无论如何是躲不开的。昨晚到此为止,心力憔悴,赶紧睡去。

今日早上继续尝试新办法。先用splot绘制同样的曲面,把结果输出为文件,再用plot把文件内容绘制成二维平面图就避开了区域间数值跳跃引入的狭缝。结果很成功,正是我想要的效果。如下图。

nav_demo_good_thumb

这样其实还是有些累赘,因为初衷本是懒得写代码生成数据文件。再图改进!这里就要提到Gnuplot 4.4以后新加入的伪文件功能。这个功能可以让函数制图和数据制图一样。这对色彩映射尤其有用。本例中把x和y设置成从伪文件中读取,其实就是整个绘图区域的一个矩阵,矩阵大小可由取样值决定。然后用自定的区域函数把三个区域对应的矩阵元标记成对应的1,2,3。写成代码如下。

plot ‘++’ u 1:2:(colorfunc($1,$2)) w image

用这个方法就能直接跳过生成文件的步骤作图了。所遗留的唯一问题是调用这个脚本时要把分辨率作为参数,所以要用call的方式调用脚本。这是为了论文做图的系统化和保持脚本本身的兼容。如此以来上面语句里的$1和$2就不再是x和y的数值而是调用call时的第二个和第三个参数了。解决方法说来好笑。只要在调用时照样参数’$1’和’$2’就好了。

前前后后四个小时,真是一次愚蠢的绘图行动啊。最后还是想感叹Gnuplot功能越来越丰富了!

  1. 留下评论

留下评论