如何解决matplotlib contourf绘制日期-时间辐射等值图的类型错误
解决contourf绘制辐射等值图的datetime类型错误
问题描述
我有一个以datetime为索引、Radiation为列的DataFrame,想要绘制以日期为X轴、时间为Y轴的辐射数据等值图(contour plot)。尝试提取Date和Time列后用contourf绘制,代码如下:
data['DateTime'] = pd.to_datetime(data['DateTime'], format='%d-%m-%Y %H:%M') data['Date'] = data['DateTime'].dt.date data['Time'] = data['DateTime'].dt.time fig, ax = plt.subplots() ax.contourf(data['Date'], data['Time'],data['SW(W/m2)'])
出现错误:TypeError: float() argument must be a string or a real number, not 'datetime.time'
核心原因
contourf仅支持数值型(整数/浮点数)的坐标轴输入,无法直接解析datetime.date或datetime.time类型;同时它要求X、Y轴数据是二维网格结构,而非一维序列。
解决步骤与代码示例
1. 数值化日期与时间
- 将时间转换为小时数(浮点数,如13:30对应13.5)
- 日期用整数索引(从起始日开始的天数,或直接用序号)
2. 构建二维网格数据
通过pivot_table将一维数据整理为「日期×时间」的二维矩阵,确保每个(X,Y)点对应唯一的辐射值。
完整代码
import pandas as pd import matplotlib.pyplot as plt import numpy as np # 处理时间格式,提取数值化的日期和时间 data['DateTime'] = pd.to_datetime(data['DateTime'], format='%d-%m-%Y %H:%M') data['Date'] = data['DateTime'].dt.date # 将时间转换为小时数(小时+分钟/60) data['Hour'] = data['DateTime'].dt.hour + data['DateTime'].dt.minute / 60 # 构建二维辐射数据矩阵:日期为行,小时为列 pivot_data = data.pivot_table( index='Date', columns='Hour', values='SW(W/m2)', aggfunc='mean' # 若存在重复时间点,用均值聚合,可替换为'first'等 ).fillna(0) # 填充缺失值,避免绘图报错 # 生成数值化的坐标轴网格 x_indices = np.arange(len(pivot_data.index)) # 日期的整数索引 y_hours = pivot_data.columns.values X, Y = np.meshgrid(x_indices, y_hours) Z = pivot_data.values.T # 转置矩阵匹配网格维度 # 绘制等值图 fig, ax = plt.subplots(figsize=(12, 6)) contour_plot = ax.contourf(X, Y, Z, cmap='viridis', levels=20) # 还原X轴为可读日期 ax.set_xticks(x_indices) ax.set_xticklabels([d.strftime('%Y-%m-%d') for d in pivot_data.index], rotation=45) # 设置轴标签与颜色条 ax.set_xlabel('日期') ax.set_ylabel('时间(小时)') plt.colorbar(contour_plot, label='辐射强度 (W/m²)') plt.tight_layout() plt.show()
关键说明
- 数值化转换:通过将时间转为小时数、日期转为整数索引,满足
contourf对数值输入的要求。 - 二维网格:
pivot_table将分散的一维数据重组为二维矩阵,确保每个坐标点有对应的辐射值,这是绘制等值图的必要条件。 - 刻度还原:最后通过
set_xticklabels将整数索引替换为实际日期,保证图表可读性。
内容的提问来源于stack exchange,提问作者shravani banerjee
相关产品推荐
相关产品推荐

