之前在使用 PyCWR 库进行雷达数据处理时,遇到了以下错误:
Traceback (most recent call last):
File "pycwr_test.py", line 1, in <module>
from pycwr.draw.RadarPlot import Graph, plot_xy
File "D:\anaconda\envs\wrfdeal\lib\site-packages\pycwr\__init__.py", line 1, in <module>
from . import configure, core, draw, io, interp, retrieve, qc
File "D:\anaconda\envs\wrfdeal\lib\site-packages\pycwr\draw\__init__.py", line 1, in <module>
from . import colormap, SingleRadarPlot, SingleRadarPlotMap, VerticalSectionPlot
File "D:\anaconda\envs\wrfdeal\lib\site-packages\pycwr\draw\colormap\__init__.py", line 1, in <module>
from . import cm, cm_colorblind
File "D:\anaconda\envs\wrfdeal\lib\site-packages\pycwr\draw\colormap\cm.py", line 171, in <module>
matplotlib.cm.register_cmap(name=full_name, cmap=cmap)
AttributeError: module 'matplotlib.cm' has no attribute 'register_cmap'
这个错误是由于 Matplotlib 版本更新导致的 API 变化。在新版本的 Matplotlib(3.10.1 及以上版本)中,matplotlib.cm.register_cmap 方法已被移除,改为使用 matplotlib.colormaps.register 方法。
PyCWR 库中的颜色映射模块(cm.py 和 cm_colorblind.py)仍在使用旧的 API,导致在新版本 Matplotlib 中无法正常工作。
此前我们是把Matplotlib降低到合适的版本,本次我们采用了一种兼容新旧版本 Matplotlib 的解决方案,使用 try-except 结构来处理不同版本的 API:
matplotlib.colormaps.register 方法matplotlib.cm.register_cmap 方法首先需要找到需要修改的文件。根据错误信息,问题出现在以下两个文件中:
pycwr/draw/colormap/cm.pypycwr/draw/colormap/cm_colorblind.py在 cm.py 文件中,找到以下代码段:
# register the colormaps so that can be accessed with the names pyart_XXX
for name, cmap in cmap_d.items():
if name in ["ref", "vel"]:
matplotlib.cm.register_cmap(name="CN_"+name, cmap=cmap)
else:
full_name = 'copy_pyart_' + name
matplotlib.cm.register_cmap(name=full_name, cmap=cmap)
hid_colors = ['LightBlue', 'MediumBlue', 'DarkOrange', 'LightPink',
'Cyan', 'DarkGray', 'Lime', 'Yellow', 'Red', 'Fuchsia']
cmaphid = colors.ListedColormap(hid_colors)
matplotlib.cm.register_cmap(name="CN_hcl", cmap=cmaphid)
将其替换为:
# register the colormaps so that can be accessed with the names pyart_XXX
for name, cmap in cmap_d.items():
if name in ["ref", "vel"]:
try:
# Try new matplotlib API first
matplotlib.colormaps.register(name="CN_"+name, cmap=cmap)
except AttributeError:
# Fall back to old API for older matplotlib versions
matplotlib.cm.register_cmap(name="CN_"+name, cmap=cmap)
else:
full_name = 'copy_pyart_' + name
try:
# Try new matplotlib API first
matplotlib.colormaps.register(name=full_name, cmap=cmap)
except AttributeError:
# Fall back to old API for older matplotlib versions
matplotlib.cm.register_cmap(name=full_name, cmap=cmap)
hid_colors = ['LightBlue', 'MediumBlue', 'DarkOrange', 'LightPink',
'Cyan', 'DarkGray', 'Lime', 'Yellow', 'Red', 'Fuchsia']
cmaphid = colors.ListedColormap(hid_colors)
try:
# Try new matplotlib API first
matplotlib.colormaps.register(name="CN_hcl", cmap=cmaphid)
except AttributeError:
# Fall back to old API for older matplotlib versions
matplotlib.cm.register_cmap(name="CN_hcl", cmap=cmaphid)
在 cm_colorblind.py 文件中,找到以下代码段:
# register the colormaps so that can be accessed with the names pyart_XXX
for name, cmap in cmap_d.items():
full_name = 'copy_pyart_' + name
mpl.cm.register_cmap(name=full_name, cmap=cmap)
将其替换为:
# register the colormaps so that can be accessed with the names pyart_XXX
for name, cmap in cmap_d.items():
full_name = 'copy_pyart_' + name
try:
# Try new matplotlib API first
mpl.colormaps.register(name=full_name, cmap=cmap)
except AttributeError:
# Fall back to old API for older matplotlib versions
mpl.cm.register_cmap(name=full_name, cmap=cmap)
修复完成后,我们创建一个测试脚本来验证修复是否有效:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
完整的 pycwr 测试脚本,验证所有模块可以正常导入
"""
print("开始测试 pycwr 模块导入...")
try:
from pycwr.draw.RadarPlot import Graph, plot_xy
print("✓ 成功导入 RadarPlot 模块")
except Exception as e:
print(f"✗ 导入 RadarPlot 模块失败: {e}")
try:
import pycwr.draw.colormap.cm as cm
print("✓ 成功导入 cm 模块")
except Exception as e:
print(f"✗ 导入 cm 模块失败: {e}")
try:
import pycwr.draw.colormap.cm_colorblind as cm_colorblind
print("✓ 成功导入 cm_colorblind 模块")
except Exception as e:
print(f"✗ 导入 cm_colorblind 模块失败: {e}")
try:
import matplotlib
print(f"✓ Matplotlib 版本: {matplotlib.__version__}")
except Exception as e:
print(f"✗ 导入 matplotlib 失败: {e}")
print("\n测试完成!所有模块导入成功。")
运行测试脚本,如果所有模块都能成功导入,说明修复成功。
路径问题:在修改文件时,确保修改的是 Python 环境实际使用的路径。可以通过以下命令查看 Python 路径:
import sys
print(sys.path)
备份原文件:在修改系统文件之前,建议先备份原始文件,以防修改出现问题。
版本兼容性:这种修复方法确保了代码在不同版本的 Matplotlib 中都能正常工作,既兼容新版本又保持了对旧版本的支持。
问题定位并不难,解决思路在于我们的想法
是保守不动源码,让仓库保持原样,强行让其他仓库兼容,还是直奔源头,完成版本迭代。