如何用Seaborn/Matplotlib绘制指定样式的柱状图与堆叠柱状图
可视化解决方案:分组柱状图 + 堆叠柱状图
我来帮你搞定这两个可视化需求!下面用Python的pandas和matplotlib实现,代码都写得很清楚,直接就能运行~
一、第一个数据集:分组柱状图
你的第一个数据集长这样:
import pandas as pd import numpy as np import matplotlib.pyplot as plt # 构建数据集 data1 = { 'A': [30, 39, 80, 80], 'B': [50, 72, 150, 70], 'C': [60, 79, 130, 90] } index1 = ['Above 90%', '80% - 90%', '65% - 80%', 'Below 65%'] df1 = pd.DataFrame(data1, index=index1)
要实现的是每个准确率区间下,A/B/C三个柱子并列对比的分组柱状图,代码如下:
# 设置柱子宽度,避免重叠 bar_width = 0.25 x = np.arange(len(df1.index)) # x轴位置 # 创建画布 fig, ax = plt.subplots(figsize=(10, 6)) # 分别绘制A、B、C的柱子,错开位置 bars_a = ax.bar(x - bar_width, df1['A'], width=bar_width, label='A') bars_b = ax.bar(x, df1['B'], width=bar_width, label='B') bars_c = ax.bar(x + bar_width, df1['C'], width=bar_width, label='C') # 给每个柱子添加数值标签 for bars in [bars_a, bars_b, bars_c]: for bar in bars: height = bar.get_height() ax.text(bar.get_x() + bar.get_width()/2., height, f'{height}', ha='center', va='bottom', fontsize=10) # 美化图表 ax.set_xlabel('准确率区间', fontsize=12) ax.set_ylabel('数值', fontsize=12) ax.set_title('各准确率区间下A/B/C数值对比', fontsize=14) ax.set_xticks(x) ax.set_xticklabels(df1.index) ax.legend() plt.tight_layout() plt.show()
运行后就能得到你想要的分组柱状图,每个区间下三个柱子清晰对比A/B/C的数值。
二、第二个数据集:自定义堆叠柱状图
你的第二个数据集是带分类的详细数据:
# 构建数据集 data2 = [ ['A', 'Fast Movers', 1, 11, 21, 9], ['A', 'Med Movers', 2, 13, 42, 40], ['A', 'Slow Movers', 34, 26, 44, 50], ['B', 'Fast Movers', 1, 11, 21, 9], ['B', 'Med Movers', 16, 48, 92, 45], ['B', 'Slow Movers', 33, 13, 37, 45], ['C', 'Fast Movers', 0, 0, 2, 30], ['C', 'Medi Movers', 11, 37, 74, 50], ['C', 'Slow Movers', 41, 42, 65, 30] ] columns2 = ['Company', 'Category', 'Above 90%', '80% - 90%', '65% - 80%', 'Below 65%'] df2 = pd.DataFrame(data2, columns=columns2)
你需要的是以Category区分颜色,Company+准确率区间作为x轴标签的堆叠柱状图,核心是先把宽格式数据转成长格式,再进行堆叠绘制:
# 第一步:把宽格式数据转成长格式(方便堆叠) df_melted = df2.melt( id_vars=['Company', 'Category'], var_name='Accuracy Interval', value_name='Count' ) # 生成x轴标签:合并Company和准确率区间 df_melted['X Label'] = df_melted['Company'] + ' - ' + df_melted['Accuracy Interval'] # 获取唯一的x标签和Category类别 x_labels = df_melted['X Label'].unique() categories = df_melted['Category'].unique() x = np.arange(len(x_labels)) # x轴位置 # 创建画布 fig, ax = plt.subplots(figsize=(16, 8)) # 初始化堆叠的底部位置(从0开始) bottom = np.zeros(len(x_labels)) # 按Category循环绘制堆叠部分,每个Category对应一种颜色 for category in categories: # 筛选当前Category的数据,并按x标签排序 category_data = df_melted[df_melted['Category'] == category] category_data = category_data.set_index('X Label').reindex(x_labels) # 绘制堆叠柱子 bars = ax.bar(x, category_data['Count'], bottom=bottom, label=category) # 给每个堆叠块添加数值标签(只显示非零值) for bar in bars: height = bar.get_height() if height > 0: ax.text(bar.get_x() + bar.get_width()/2., bar.get_y() + height/2., f'{height}', ha='center', va='center', fontsize=9) # 更新底部位置,为下一个Category的堆叠做准备 bottom += category_data['Count'].values # 美化图表 ax.set_xlabel('公司 - 准确率区间', fontsize=12) ax.set_ylabel('总数', fontsize=12) ax.set_title('按Category颜色区分的堆叠柱状图', fontsize=14) ax.set_xticks(x) ax.set_xticklabels(x_labels, rotation=45, ha='right') # 旋转标签避免重叠 ax.legend(title='分类', bbox_to_anchor=(1.05, 1), loc='upper left') # 把图例放右边 plt.tight_layout() plt.show()
这个代码生成的堆叠图完全符合你的要求:每个x轴标签是“公司-准确率区间”,柱子内部按Category用不同颜色堆叠,还加了数值标签让数据更直观~
内容的提问来源于stack exchange,提问作者Ahamed Moosa
相关产品推荐
相关产品推荐

