保存pcolormesh图时Matplotlib渲染器出现float类型转换错误
问题:Linux命令行下pcolormesh保存图像时float128转float64失败
背景与代码变更
我将处理NetCDF数据集的绘图脚本中,把contourf替换为pcolormesh,用于生成多时间步的地图和特定位置的变量时间剖面图。
原代码:
im = ax.contourf(X,Y,np.transpose(data),*args,**kwargs)
其中:
- X:float64类型的时间数据(单位:秒)
- Y:float64类型的高度数据
- data:NetCDF数据集的切片,类型为float32
替换后的代码:
im = ax.pcolormesh(X,Y,np.transpose(data),shading='gouraud',*args,**kwargs)
kwargs仅包含色条及色条范围配置,无特殊设置。
问题现象
本地Windows的Spyder环境中测试用例运行完全正常,但在Linux服务器命令行执行时,保存图像阶段抛出如下错误:
Traceback (most recent call last): File "(redacted)/main.py", line 37, in <module> dataset.make_plots() File "(redacted)/plotDataset.py", line 75, in make_plots self._crossecPlot(data, variable, crossec) File "(redacted)/plotDataset.py", line 196, in _crossecPlot plt.savefig(self.settings['output_path']+'/'+filename+'.png', bbox_inches='tight') File "(redacted)/miniconda3/lib/python3.10/site-packages/matplotlib/pyplot.py", line 1023, in savefig res = fig.savefig(*args, **kwargs) File "(redacted)/miniconda3/lib/python3.10/site-packages/matplotlib/figure.py", line 3343, in savefig self.canvas.print_figure(fname, **kwargs) File "(redacted)/miniconda3/lib/python3.10/site-packages/matplotlib/backends/backend_qtagg.py", line 75, in print_figure super().print_figure(*args, **kwargs) File "(redacted)/miniconda3/lib/python3.10/site-packages/matplotlib/backend_bases.py", line 2366, in print_figure result = print_method( File "(redacted)/miniconda3/lib/python3.10/site-packages/matplotlib/backend_bases.py", line 2232, in <lambda> print_method = functools.wraps(meth)(lambda *args, **kwargs: meth( File "(redacted)/miniconda3/lib/python3.10/site-packages/matplotlib/backends/backend_agg.py", line 509, in print_png self._print_pil(filename_or_obj, "png", pil_kwargs, metadata) File "(redacted)/miniconda3/lib/python3.10/site-packages/matplotlib/backends/backend_agg.py", line 457, in _print_pil FigureCanvasAgg.draw(self) File "(redacted)/miniconda3/lib/python3.10/site-packages/matplotlib/backends/backend_agg.py", line 400, in draw self.figure.draw(self.renderer) File "(redacted)/miniconda3/lib/python3.10/site-packages/matplotlib/artist.py", line 95, in draw_wrapper result = draw(artist, renderer, *args, **kwargs) File "(redacted)/miniconda3/lib/python3.10/site-packages/matplotlib/artist.py", line 72, in draw_wrapper return draw(artist, renderer) File "(redacted)/miniconda3/lib/python3.10/site-packages/matplotlib/figure.py", line 3140, in draw mimage._draw_list_compositing_images( File "(redacted)/miniconda3/lib/python3.10/site-packages/matplotlib/image.py", line 131, in _draw_list_compositing_images a.draw(renderer) File "(redacted)/miniconda3/lib/python3.10/site-packages/matplotlib/artist.py", line 72, in draw_wrapper return draw(artist, renderer) File "(redacted)/miniconda3/lib/python3.10/site-packages/matplotlib/axes/_base.py", line 3064, in draw mimage._draw_list_compositing_images( File "(redacted)/miniconda3/lib/python3.10/site-packages/matplotlib/image.py", line 131, in _draw_list_compositing_images a.draw(renderer) File "(redacted)/miniconda3/lib/python3.10/site-packages/matplotlib/artist.py", line 72, in draw_wrapper return draw(artist, renderer) File "(redacted)/miniconda3/lib/python3.10/site-packages/matplotlib/collections.py", line 2095, in draw renderer.draw_gouraud_triangles( TypeError: Cannot cast array data from dtype('float128') to dtype('float64') according to the rule 'safe'
已尝试的解决方法
- 将
shading改为默认的nearest,报错位置变为renderer.draw_quad_mesh,问题依旧 - 更换Anaconda/Miniconda环境,未解决问题
异常细节
同一数据集的另一个绘图场景中,使用pcolormesh搭配Cartopy时无报错:
im = ax.pcolormesh(lons,lats,values,transform=ccrs.PlateCarree(),*args, **kwargs)
目前不清楚float128类型的来源,也无法理解为何不能转换为float64(绘图场景下精度损失完全可接受)。
解决方案
1. 显式转换所有输入数组为float64
强制将X、Y、data转换为matplotlib后端支持的float64类型,避免内部生成float128数组:
# 在调用pcolormesh前添加类型转换 X = X.astype(np.float64) Y = Y.astype(np.float64) transposed_data = np.transpose(data).astype(np.float64) im = ax.pcolormesh(X, Y, transposed_data, shading='gouraud', *args, **kwargs)
2. 检查并调整numpy浮点类型配置(可选)
Linux环境下的numpy可能默认启用了float128支持,可在脚本开头强制设置默认浮点类型为float64:
import numpy as np np.set_default_dtype(np.float64)
注意:此设置会影响脚本中所有numpy数组的默认类型,若有其他高精度计算需求,优先使用显式类型转换。
3. 原因分析
Linux环境中numpy的浮点类型支持与Windows存在差异,pcolormesh在处理无Cartopy transform的网格数据时,内部计算可能将数组类型提升为float128,而matplotlib的Agg后端仅支持float64,且转换时使用了safe规则(不允许精度损失),导致报错。而Cartopy的transform内部会自动将输入数组转换为float64,因此未触发问题。
内容的提问来源于stack exchange,提问作者Florian Sauerland
相关产品推荐
相关产品推荐

