cmaps
作为曾经地球科学领域最炙手可热脚本语言之一的NCL已经进入维护模式,不再更新。Python中的cmaps库提供了560条来自NCL的colorbar,使得我们可以在Python绘制出和NCL中一样的colorbar。
例图展示
在气象研究中,一个好看的colorbar可以让你的学术图表填色不少,如下面几张图。
NCL Colorbar查询
NCL的colorbar可在该网址中查询:https://www.ncl.ucar.edu/Document/Graphics/color_table_gallery.shtml
cmaps库GitHub网址:https://github.com/hhuangwx/cmaps
有喜欢的colorbar可通过以上两个网址中查询。
cmaps库colorbar大全
绘制以上图片的代码如下:
import cmaps
import numpy as np
import inspect
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rc('text', usetex=False)
def list_cmaps():
attributes = inspect.getmembers(cmaps, lambda _: not (inspect.isroutine(_)))
colors = [_[0] for _ in attributes if
not (_[0].startswith('__') and _[0].endswith('__'))]
return colors
if __name__ == '__main__':
color = list_cmaps()
a = np.outer(np.arange(0, 1, 0.001), np.ones(10))
plt.figure(figsize=(20, 20))
plt.subplots_adjust(top=0.95, bottom=0.05, left=0.01, right=0.99)
ncmaps = len(color)
nrows = 8
for i, k in enumerate(color):
plt.subplot(nrows, ncmaps // nrows + 1, i + 1)
plt.axis('off')
plt.imshow(a, aspect='auto', cmap=getattr(cmaps, k), origin='lower')
plt.title(k, rotation=90, fontsize=10)
plt.title(k, fontsize=10)
plt.savefig('colormaps.png', dpi=300)
注意:
以上代码在Python3.9-3.10
或者更高的版本中可能报错,这个问题也是我们今天推文需要解决的问题。
cmaps库的报错
报错内容
这里我们以BlueWhiteOrangeRed
colobar为例,在最近使用cmaps库会出现报错:
ValueError: A colormap named "BlueWhiteOrangeRed" is already registered.
接下来我们将解决这个问题。
解决cmaps报错问题
cmaps库的实现原理:
cmaps库的实现原理其实不难,通过下载NCL官网中的所有colormap的rgb文件使用正则表达式解析其中的 RGB 值,并将其转换为 Matplotlib 可以识别的颜色映射对象。最后将颜色映射对象被注册到 Matplotlib 的注册表中,我们可以直接调用这些映射进行绘图。
BlueWhiteOrangeRed colormap
cmaps库源码部分展示
解决方案
从以上源码可以看出,cmaps库创建了一个Cmaps的类,将BlueWhiteOrangeRed
定义为Cmaps类中的一个方法,而报错内容:ValueError: A colormap named "BlueWhiteOrangeRed" is already registered.
,则是告诉我们BlueWhiteOrangeRed
的colormap已经被注册。
使用以下代码将解决以上的问题:
import matplotlib.pyplot as plt
import cmaps
def register_cmap_if_needed(cmap_name, cmap_module):
try:
cmap_object = getattr(cmap_module, cmap_name)
if cmap_name not in plt.colormaps():
plt.register_cmap(cmap=cmap_object, name=cmap_name)
except:
pass
cmap_name = "WhiteBlueGreenYellowRed"
register_cmap_if_needed(cmap_name, cmaps)
根据源码,我们使用Python的内置函数getattr
获取对象的属性,从而避免colorbar的重复注册,从而解决问题。
以上代码的伪代码为:
函数 注册颜色映射(颜色映射名称, 颜色映射模块):
尝试:
获取颜色映射对象,通过 颜色映射名称 从 颜色映射模块 中获取
如果 颜色映射名称 不在当前已注册的颜色映射列表中:
注册颜色映射,使用 颜色映射对象 和 颜色映射名称
如果发生异常:
忽略异常并继续执行
定义 颜色映射名称 为 "WhiteBlueGreenYellowRed"
调用 注册颜色映射 函数,传入 颜色映射名称 和 颜色映射模块
使用建议:
每次绘图需要运行一次以上代码,可以将以上代码复制到代码的最上方,需要修改colorbar时,只需要修改cmap_name
即可。
使用例子
import matplotlib.pyplot as plt
import cmaps
def register_cmap_if_needed(cmap_name, cmap_module):
try:
cmap_object = getattr(cmap_module, cmap_name)
if cmap_name not in plt.colormaps():
plt.register_cmap(cmap=cmap_object, name=cmap_name)
except:
pass
cmap_name = "WhiteBlueGreenYellowRed"
register_cmap_if_needed(cmap_name, cmaps)
...
...
(中间省略)
...
...
contourf_plot = plt.contourf(lon, lat, sst, cmap="WhiteBlueGreenYellowRed")
往期回顾
-
Python | 北大西洋涛动 | NAO指数 | EOFhttps://mp.weixin.qq.com/s/PNo2ynw6tRTRngtloFxxKw
-
Python | HadSLP2 ASCII转NetCDFhttps://mp.weixin.qq.com/s/Y7ecB3M16b454B_xkWynCQ
-
Python | 半球间经度转换https://mp.weixin.qq.com/s/CURpXBkv2TfJmMyEZAHeKQ
-
Python | 大气科学 | 偏相关https://mp.weixin.qq.com/s/l6ADX2ELiaDFw2laZMNCVg
-
37个CMIP6模型对流参数化方案https://mp.weixin.qq.com/s/qWjHyzzLVaxMmahKLIdInQ
·投稿或转载请联系·
长按可关注