如何绘制脊髓灰质炎数据热力图:Y轴为州、X轴为年份
问题:Seaborn热力图展示各州脊髓灰质炎病例数不符合预期
我正在通过YouTube等平台学习数据科学技能,做个人小项目时遇到了问题。我用的是美国卫生与公众服务部Project Tycho的数据集(1966-2013年美国各州法定传染病周报告),导出为.csv后在Anaconda的Jupyter Notebook里处理,想通过Seaborn热力图展示各州历年脊髓灰质炎病例数,但生成的图表完全不符合预期。
现有代码
polio_data=polio[['state', 'cases','incidence_per_100000','year']] polio_years = list(polio_data['year'].unique()) polio_states= [v.title() for v in polio_data.state] polio_data = polio_data.groupby('year').sum() polio_data = polio_data.transpose().values plt.figure(figsize=(12,12))
sb.heatmap(polio_data, cmap='Reds', robust=True, xticklabels=[year if year % 5 == 0 or year == max(polio_years) else '' for year in polio_years], yticklabels=polio_states)
问题表现
- 错误输出:热力图的行是
cases和incidence_per_100000两个统计项,而非美国各州;列是年份,但数据是每年所有州的病例总和,完全偏离了「分州展示年度病例数」的需求。 - 期望效果:热力图行对应美国各州,列对应年份,每个单元格显示对应州对应年份的脊髓灰质炎病例数,颜色深浅代表病例数的多少。
解决方法
核心问题是你对数据的透视逻辑错误,应该把数据整理成「行=州,列=年份,值=病例数」的宽表结构,而非按年份求和全国总数。以下是修正步骤和代码:
修正后代码
import seaborn as sb import matplotlib.pyplot as plt # 1. 按州+年份汇总病例数(原数据是周报告,先合并年度数据) polio_yearly = polio.groupby(['state', 'year'])['cases'].sum().reset_index() # 2. 转成宽表:行=州,列=年份,单元格值=对应年度病例数 polio_pivot = polio_yearly.pivot(index='state', columns='year', values='cases') # 3. 填充缺失值(部分州某年无病例会出现NaN,用0填充) polio_pivot = polio_pivot.fillna(0) # 4. 准备标签:州名首字母大写,年份按5年间隔显示 polio_states = [s.title() for s in polio_pivot.index] polio_years = polio_pivot.columns.tolist() xtick_labels = [y if y % 5 == 0 or y == max(polio_years) else '' for y in polio_years] # 5. 绘制热力图 plt.figure(figsize=(16, 10)) # 调整尺寸适配州的数量 sb.heatmap(polio_pivot, cmap='Reds', robust=True, xticklabels=xtick_labels, yticklabels=polio_states, annot=False) # 若需要显示具体病例数,可将annot改为True plt.title('美国各州历年脊髓灰质炎病例数热力图(1966-2013)') plt.xlabel('年份') plt.ylabel('州') plt.show()
关键修正点
- 原代码
groupby('year').sum()是把所有州的病例按年份加总,得到的是全国年度总数,而非分州数据,这是核心错误; - 改用
groupby(['state', 'year'])['cases'].sum()先按州和年份汇总,再转成宽表,才能得到每个州每年的病例数; - 填充缺失值避免热力图出现空白,同时调整图表尺寸让州名显示更清晰。
内容的提问来源于stack exchange,提问作者Ude Marcel
相关产品推荐
相关产品推荐

