如何用Pandas绘制以分类为Y轴的多内容堆叠条形图?
实现分类堆叠水平条形图的解决方案
这里提供两种Python实现方案,分别基于原生Matplotlib和Pandas,都能满足你的需求:
方案一:原生Matplotlib手动实现
适合需要精细控制绘图细节的场景:
import matplotlib.pyplot as plt # 整理数据为统一字典结构 category_data = { 'category1': {'A': 23.5, 'B': 48, 'C': 32.4}, 'category2': {'D': 12, 'E': 54.3, 'F': 65}, 'category3': {'G': 7.5, 'H': 43, 'I': 24.8} } # 收集所有子类别并分配唯一颜色 all_subcategories = [] for cat in category_data.values(): all_subcategories.extend(cat.keys()) color_map = {key: plt.cm.tab10(i) for i, key in enumerate(all_subcategories)} # 设置Y轴位置和分类标签 y_positions = range(len(category_data)) category_labels = list(category_data.keys()) # 初始化每个分类的堆叠起始位置 left_offsets = [0] * len(category_data) # 创建绘图对象 fig, ax = plt.subplots() # 逐个绘制每个子类别的堆叠块 for subcat in all_subcategories: # 获取每个分类中当前子类别的宽度(无对应子类则为0) bar_widths = [category_data[cat].get(subcat, 0) for cat in category_labels] # 绘制水平堆叠条形 ax.barh(y_positions, bar_widths, left=left_offsets, label=subcat, color=[color_map[subcat]]*len(category_data)) # 更新下一个堆叠块的起始位置 left_offsets = [offset + width for offset, width in zip(left_offsets, bar_widths)] # 设置轴标签和标题 ax.set_yticks(y_positions) ax.set_yticklabels(category_labels) ax.set_xlabel('数值') ax.set_title('分类堆叠水平条形图') # 添加图例并调整布局 ax.legend(title='子类别') plt.tight_layout() plt.show()
关键逻辑说明
- 使用
barh()绘制水平条形图,通过left参数控制每个堆叠块的起始位置,实现堆叠效果 - 为每个子类别(A-I)分配唯一颜色,确保同一子类别在不同分类中颜色一致
- 用
get(subcat, 0)处理不同分类子类别不重叠的情况,避免绘图报错
方案二:Pandas快速实现
适合追求简洁高效的场景,Pandas会自动处理堆叠和颜色映射:
import pandas as pd import matplotlib.pyplot as plt # 整理数据并转换为DataFrame,缺失值填充为0 category_data = { 'category1': {'A': 23.5, 'B': 48, 'C': 32.4}, 'category2': {'D': 12, 'E': 54.3, 'F': 65}, 'category3': {'G': 7.5, 'H': 43, 'I': 24.8} } df = pd.DataFrame(category_data).T.fillna(0) # 绘制堆叠水平条形图 df.plot.barh(stacked=True, colormap='tab10') # 设置轴标签和标题 plt.xlabel('数值') plt.ylabel('分类') plt.title('分类堆叠水平条形图') plt.legend(title='子类别') plt.tight_layout() plt.show()
关键逻辑说明
- 将原始字典转换为DataFrame并转置(
.T),让分类作为行索引(对应Y轴),子类别作为列(对应堆叠块) - 使用
stacked=True参数直接开启堆叠模式,colormap指定颜色映射确保子类别颜色唯一
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

