如何使用Python基于三类分类变量绘制单张静态统计图表
解决方案
适配需求的可视化方案选择
你需要同时展示3个分类变量+1个数值变量,最适配的是分组堆叠柱状图,三个维度的展示逻辑如下:
- X轴按城市划分大组,每个城市组内相邻放置对应两个年份的柱子
- 单根柱子内部按水果类型堆叠,不同水果用不同颜色区分
- Y轴直接映射产量数值
该方案不需要将年份转成度量值,通过X轴位置偏移的方式就能把年份维度加入堆叠柱状图体系,完美适配你的需求。
完整可运行Matplotlib实现代码
import pandas as pd import matplotlib.pyplot as plt # 构造数据集 data= { 'city':['amsterdam','amsterdam','amsterdam','amsterdam','amsterdam','amsterdam','paris','paris','paris','paris','paris','paris','berlin','berlin','berlin','berlin','berlin','berlin'], 'fruits':['apples','oranges','bananas','apples','oranges','bananas','apples','oranges','bananas','apples','oranges','bananas','apples','oranges','bananas','apples','oranges','bananas'], 'year':[2000,2000,2000,2001,2001,2001,2000,2000,2000,2001,2001,2001,2000,2000,2000,2001,2001,2001], 'amount':[384,289,347,242,390,274,175,334,245,116,252,366,255,400,300,240,600,180] } df = pd.DataFrame(data) # 数据预处理:按城市、年份、水果聚合,整理成便于绘图的结构 df_agg = df.groupby(['city', 'year', 'fruits'])['amount'].sum().unstack() # 绘图参数配置 city_list = df['city'].unique() year_list = df['year'].unique() fruit_list = df['fruits'].unique() fruit_colors = ['#FF8888', '#FFCC88', '#88DD88'] # 三种水果对应的自定义颜色 bar_width = 0.35 # 单根年份柱子的宽度 x_base = range(len(city_list)) # 城市组的X轴基准位置 plt.figure(figsize=(12, 6)) # 遍历年份绘制堆叠柱 for year_idx, year in enumerate(year_list): # 计算当前年份柱子的实际X轴位置 current_x = [pos + year_idx * bar_width for pos in x_base] # 堆叠底高度初始化 stack_bottom = [0] * len(city_list) for fruit_idx, fruit in enumerate(fruit_list): # 提取当前城市、当前年份、当前水果的产量数据 plot_values = df_agg.xs(year, level='year')[fruit].reindex(city_list).values # 绘制柱子,仅第一次添加图例避免重复 plt.bar(current_x, plot_values, width=bar_width, bottom=stack_bottom, color=fruit_colors[fruit_idx], label=fruit if year_idx == 0 else "") # 更新堆叠底高度 stack_bottom = [stack_bottom[i] + plot_values[i] for i in range(len(plot_values))] # 图表样式调整 plt.xlabel('城市', fontsize=12) plt.ylabel('产量', fontsize=12) plt.title('2000-2001年各城市三类水果产量统计', fontsize=14) # 调整X轴刻度到城市组的中间位置 plt.xticks([pos + bar_width/2 for pos in x_base], city_list, fontsize=11) plt.legend(title='水果类型', bbox_to_anchor=(1.01, 1), loc='upper left') plt.grid(axis='y', linestyle='--', alpha=0.6) plt.tight_layout() plt.show()
可选替代方案
如果你更关注单类水果的跨年份对比,不需要看年度总产量,可以换成簇状柱状图:每个城市组内按年份+水果拆分6根柱子,相同水果统一颜色,同一年份的柱子放在一起即可,只需要在上述代码中去掉堆叠逻辑,调整X轴偏移量即可实现。
内容的提问来源于stack exchange,提问作者serkan
相关产品推荐
相关产品推荐

