之前一直想尝试着用Matplotlib绘制计算结果中的二维密度分布图,这样即省去了许多数据处理的麻烦,也方便直接在Linux系统中观察计算的结果。但对Numpy和Maltplotlib的熟练程度还不够,对于计算程序产生的非矩阵式的数据结构不知道该怎么处理。今天花了一早上仔细研究了一下,终于将这块硬骨头啃下来了。
做colormap图的关键在于矩阵的创建,作为坐标的x与y在形状上为呈转置关系的两个矩阵(即x的行数与y的列数相等,反之亦然),在内容上则应为x以行的形式重复,y以列的形式重复。想要产生这样的两个矩阵,可以通过Numpy中的函数np.meshgrid(x,y)来实现。用于表示值变化的z则为一个二维数组,即对于每一对x,y都应存在一个值z[x][y]。在一般的做法中,z值可以通过以x,y为自变量的函数产生。
我这里遇到的问题是已有的数据是三个一维数组。相当与将上述的x,y,z矩阵一一对应地平铺开来。这样的数据在Origin中作图十分方便,但在Matplotlib中就得预先处理一下。这个过程实则是将平铺开的数组再压缩回去。
首先要用np.unique()函数对x和y的数组进行压缩,得到无重复数值的xn与yn,再使用np.meshgrid()函数将xn与yn编织成上文所述的矩阵。对z值的处理需要谨慎一些,需要依次寻找每一个x与y共同对应地唯一的z值。最初的x,y,z是三个等长度的数组,共同的索引编号是它们确保一一对应的锁链。这里可以借助np.argwhere()函数找出x与y数组中某个值的索引,由于x,y是具有重复值的数组,这个索引将是两个包含许多位置的数组。所以我们还需要对两个索引数组用np.intersect1d()函数求并集得到唯一的z数组中的索引数。具体的操作应为: