color-mapping
color-mapping in matplotlib
color-mapping需要两个信息,对应两个步骤,
首先需要确定如何将要展示的数据映射到\((0\sim 1)\)区间,最基本的映射关系就是线性映射,将数据的最大值映射到1,最小值映射到0. 在matplotlib的绘图中,不同绘图方法的API都是一致的,这个关系通过
norm
参数指定,这个参数接收一个matplotlib.colors.Normalize
对象,根据Normalize
对象种类或属性的不同,我们可以指定不同的映射关系,比如线性映射或者对数映射.其次需要确定如何把\((0\sim 1)\)区间的值再映射到RGBA空间,即颜色空间,这个信息我们称之为色图 (colormap),这个参数通过
cmap
参数指定. 这个参数接收一个字符串或者一个matplotlib.colors.Colormap
对象. 对于matplotlib自带的colormap,用字符串指定cmap
就可以了,比如cmap='jet'
. 当然一些库可能提供了其他的colormap,这时候可以提供对应的Colormap对象. 任何绘图工具都会提供很多不同种类的colormap可供选择,下面是matplotlib中提供的一部分colormap,jet
看起来比较适合描述温度场或者产热.
不同绘图工具的设计逻辑应该都是类似的. 有了这两个信息说明,我们就可以完全确定该如何进行color-mapping了. 以绘制某一个物理场的分布为例,在绘图过程中有两个地方需要进行color-mapping,一个是在绘制物理场分布的时候,需要将物理场的数值大小和颜色对应起来;另一个是在绘制colorbar的时候,我们也需要同样的映射信息.
关于plt.colorbar(mappable, ax)
需要再说明一下,它主要需要两个参数,一个是mappable
参数,也是第一个默认参数,它接收一个plt.cm.ScalarMappable(norm, cmap)
对象,这个对象有两个属性norm
和cmap
,和上面提到的是一样的. 我们可以手动创建一个ScalarMappable
对象传给colorbar,也可以把绘制了等值线的Axes
对象传给它,因为绘制了等值线的Axes
对象有同样的接口,比如norm
或者cmap
,此时colorbar也可以成功检测到对应属性并且完成绘制. ax
参数决定了这个colorbar要绘制到哪一个Axes
对象上.
一个小例子
1 | import numpy as np |
一些说明
plt.style.use('science')
制定了默认绘图风格,science
样式文件可以通过安装SciencePlots库获得.science
风格默认用Latex渲染,如果未配置好Latex,上面代码中cbar_linear.ax.set_title
里面的Latex命令需要删除..否则无法正常运行.remove_spines
和remove_ticklines
两个函数接收一个Axes
对象,分别删去它的Spines和Major+Minor ticks,这里这样指定是为了说明colorbar
对象中也包含一个Axes
对象,因此要修改colorbar
对象的某些属性,实际上是修改colorbar
对象中Axes
对象的属性,这些接口都是一致的. 可以参考一下以前写的Artist对象.Linear color mapping中说明了一下使用
plt.cm.ScalarMappable
传递给plt.colorbar
作参数的方法,如果直接传给plt.colorbar(contourf_linear)
,这时候绘制的colorbar是离散的,因为plt.contourf(levels=5)
得到的等值线图是离散的,离散出来的色块数量由levels
参数决定,不是很好看.Logarithmic color mapping中说明了
plt.pcolor
绘制物理场分布以及color-mapping对数映射的方法,这个方法实际上并不是绘制等值线,而是用类似于sns.heatmap
这种像素式的热图,这种方法绘制出来的分布更加漂亮一些,看起来更高级一点.