如何在Pandas中按年份批量展示全量数据的饼图?
解决按年份展示全量数据饼图的问题
看起来你搞反了饼图的维度哦!你当前的代码是按犯罪类型生成饼图(每个子图展示某类犯罪在所有年份的占比),但你想要的应该是每个年份对应一个饼图,展示当年各类犯罪的占比对吧?
关键问题分析
你的代码里循环的是df.columns(也就是三类犯罪),所以每个子图呈现的是某类犯罪在所有年份的分布。而我们需要循环的是df.index(每个年份),让每个子图展示该年份下三类犯罪的占比。
修正后的代码
import matplotlib.pyplot as plt import pandas as pd import math # 你的DataFrame数据(直接复用你提供的内容) data = { 'assualt': [2988,6033,5924,5631,5875,7434,5673,5695,6099,7038,6671,6046,5496,5666,4933,4972,5328,5909,6067,6448,6355], 'fraud': [11897,27660,28421,29539,30295,27141,27986,30070,26031,25845,21009,17768,18974,18458,14157,16849,18819,21915,21891,27390,25438], 'robbery': [1212,2482,2418,2298,2481,1940,2053,1879,1903,1889,1736,1791,1934,1726,1748,1962,1762,1341,1354,1608,1822] } dates = ['1997-1998','1998-1999','1999-2000','2000-2001','2001-2002','2002-2003','2003-2004','2004-2005','2005-2006','2006-2007','2007-2008','2008-2009','2009-2010','2010-2011','2011-2012','2012-2013','2013-2014','2014-2015','2015-2016','2016-2017','2017-2018'] df = pd.DataFrame(data, index=dates) plt.style.use('ggplot') colors = plt.rcParams['axes.color_cycle'] # 动态计算子图布局:每行放4个饼图,自动计算所需行数 cols = 4 rows = math.ceil(len(df) / cols) # 设置合适的画布尺寸,适配多行子图 fig, axes = plt.subplots(nrows=rows, ncols=cols, figsize=(16, 20)) # 循环遍历每个年份和对应的子图 for ax, year in zip(axes.flat, df.index): # 获取当前年份的三类犯罪数据 year_data = df.loc[year] # 绘制饼图,标签为犯罪类型,显示百分比 ax.pie(year_data, labels=year_data.index, autopct='%.2f%%', colors=colors) ax.set(ylabel='', title=f'Year: {year}', aspect='equal') # 隐藏多余的空白子图(当行数*列数大于年份数量时) for ax in axes.flat[len(df):]: ax.axis('off') # 添加统一图例,放在第一个子图左侧 axes[0, 0].legend(bbox_to_anchor=(-0.5, 0.5)) # 自动调整子图间距,避免标题和饼图重叠 plt.tight_layout() fig.savefig('yearly_crime_pies.png') plt.show()
代码优化点说明
- 动态布局:通过
math.ceil(len(df)/cols)自动计算所需行数,不管年份数量多少都能适配布局,多余的空白子图会被隐藏。 - 循环逻辑修正:把遍历对象从
df.columns改成df.index,每个子图对应一个年份的行数据,精准匹配你的需求。 - 样式调整:增大画布尺寸适配多行子图,用
plt.tight_layout()解决元素重叠问题,让整体布局更整洁。
这样就能一次性展示所有年份的饼图,每个饼图都清晰呈现当年各类犯罪的占比啦!
内容的提问来源于stack exchange,提问作者Veera Balla Deva
相关产品推荐
相关产品推荐

