Python绘制径向热力图遇空图问题求助
Python径向热力图空图问题解决
问题核心错误排查
你的代码出现空图主要有以下几个关键问题:
- 列名不匹配:示例DataFrame中距离列名为
dist,但循环代码中使用value["distance"]读取,导致无法获取距离值,分箱后的round_bins全为0。 - 角度与极坐标不兼容:matplotlib极坐标使用弧度且从右侧(0弧度)逆时针递增,原始角度[-180,180]度未正确转换为对应范围。
- 网格与数据维度不匹配:分箱后的counts矩阵与极坐标网格的维度未对齐,导致
pcolormesh无法正确渲染。
修正后的完整代码
1. 数据分箱(两种可选方式)
方式一:循环分箱(修正列名与边界判断)
import pandas as pd import numpy as np import matplotlib.pyplot as plt # 示例DataFrame(统一列名为distance) df = pd.DataFrame({ 'angle': [-180.0]*10, 'distance': [0.64, 0.67, 0.68, 0.72, 0.75, 0.76, 0.78, 0.79, 0.80, 0.82], 'counts': [1,1,1,1,2,2,1,4,1,2] }) # 定义分箱区间 degree_bins = np.arange(-180, 181, 5) # -180到180,步长5 distance_bins = np.arange(0, 20.25, 0.25) # 0到20.25,覆盖0-20的所有值 # 初始化分箱汇总矩阵 round_bins = pd.DataFrame(0, index=distance_bins, columns=degree_bins) # 循环汇总counts for _, value in df.iterrows(): degree = value["angle"] distance = value["distance"] count = value["counts"] # 获取分箱索引,避免越界 degree_bin = np.digitize(degree, degree_bins) - 1 distance_bin = np.digitize(distance, distance_bins) - 1 if 0 <= degree_bin < len(degree_bins) and 0 <= distance_bin < len(distance_bins): round_bins.iloc[distance_bin, degree_bin] += count # 提取有效分箱区间(bins数量减1) counts = round_bins.iloc[:-1, :-1]
方式二:groupby快速分箱(推荐)
import pandas as pd import numpy as np import matplotlib.pyplot as plt df = pd.DataFrame({ 'angle': [-180.0]*10, 'distance': [0.64, 0.67, 0.68, 0.72, 0.75, 0.76, 0.78, 0.79, 0.80, 0.82], 'counts': [1,1,1,1,2,2,1,4,1,2] }) degree_bins = np.arange(-180, 181, 5) distance_bins = np.arange(0, 20.25, 0.25) # 生成分箱标签(用区间左边界) df['angle_bins'] = pd.cut(df['angle'], bins=degree_bins, labels=degree_bins[:-1]) df['distance_bins'] = pd.cut(df['distance'], bins=distance_bins, labels=distance_bins[:-1]) # 分组汇总,填充缺失分箱的0值 counts = df.groupby(['distance_bins', 'angle_bins'])['counts'].sum().unstack(fill_value=0) # 确保索引与分箱区间完全匹配 counts = counts.reindex(index=distance_bins[:-1], columns=degree_bins[:-1], fill_value=0)
2. 径向热力图绘制(修正极坐标转换)
# 准备绘图参数 n_angles = len(degree_bins) - 1 n_radii = len(distance_bins) - 1 # 将角度转换为matplotlib极坐标支持的弧度:[-180,180] → [0, 2π],取区间中点 angles_rad = np.deg2rad(degree_bins[:-1] + 2.5) # 取距离区间中点 radii = distance_bins[:-1] + 0.125 # 生成极坐标网格 th, r = np.meshgrid(angles_rad, radii) # 转置counts矩阵以匹配网格维度 z = counts.to_numpy().T # 绘图 plt.figure(figsize=(10,10)) ax = plt.subplot(projection='polar') # 使用shading='auto'避免网格间隙 pcm = ax.pcolormesh(th, r, z, cmap='jet', shading='auto') # 添加网格与刻度 ax.set_theta_grid(10) # 每10度显示一条角度网格线 ax.set_rgrids(distance_bins[::4]) # 每1个距离单位显示一条径向网格线 plt.colorbar(pcm, shrink=0.8, label='Counts') plt.show()
关键修正说明
- 列名统一:确保代码中读取的列名与DataFrame实际列名一致,否则分箱汇总全为0。
- 极坐标角度转换:将原始角度转换为[0,2π]的弧度范围,取区间中点能让热力图的颜色对应更准确。
- 维度匹配:分箱后的有效区间数是
bins数组长度-1,生成网格时需使用这些区间的中点,保证th、r、z三者维度完全一致。
内容的提问来源于stack exchange,提问作者milkz-boi
相关产品推荐
相关产品推荐

