Matplotlib不平衡数据集堆叠柱状图:小堆叠百分比标签优化求助
解决Matplotlib堆叠柱状图小区域标签拥挤问题
基于大规模不平衡数据集绘制堆叠柱状图,需要为每个堆叠添加百分比标签,但堆叠区域过小时标签显示杂乱拥挤。数据集为动态数据无法修改,尝试用
matplotlib.text调整未解决问题,原实现代码如下:
def plot_stack_bar(plot_df, xlabel, ylabel, title): plot_df_percent=pd.DataFrame() cols = list(plot_df) plot_df_percent[cols] = plot_df[cols].div( plot_df[cols].sum(axis=1), axis=0 ) plot_df.plot(kind='bar', stacked=True, figsize=(20, 17)) plt.xlabel(xlabel) plt.ylabel(ylabel) plt.title(title) for n, x in enumerate([*plot_df.index.values]): i=0 for (proportion, y_loc) in zip(plot_df_percent.loc[x], plot_df_percent.loc[x].cumsum()): y_loc = plot_df.iloc[n,I] / 2 + plot_df.iloc[n,:i].sum() plt.text(x=n-0.17, y=y_loc, s=f'{np.round(proportion * 100, 1)}%', color="black", fontsize=12, fontweight="bold") i=i+1 plt.savefig(f'draft/{title}.png') plt.show()
解决思路
- 过滤极小占比标签:设置占比阈值(如1%),占比低于阈值的标签直接不显示,从根源避免小区域标签拥挤
- 动态调整字体大小:根据占比大小自动缩小小占比标签的字号,既保留关键信息又减少空间占用
- 修正标签位置计算:修复原代码中变量大小写错误(
I改为i),确保标签始终落在堆叠区域的垂直中心 - 可选优化柱子宽度:绘制柱状图时指定
width参数缩小柱子宽度,给标签预留更多横向空间
修改后的代码
import matplotlib.pyplot as plt import pandas as pd import numpy as np def plot_stack_bar(plot_df, xlabel, ylabel, title, label_threshold=1): # 计算各堆叠的百分比 cols = plot_df.columns plot_df_percent = plot_df[cols].div(plot_df[cols].sum(axis=1), axis=0) # 绘制堆叠柱状图,可选调整柱子宽度 ax = plot_df.plot(kind='bar', stacked=True, figsize=(20, 17), width=0.8) plt.xlabel(xlabel) plt.ylabel(ylabel) plt.title(title) # 遍历每个柱子和堆叠层 for n, x in enumerate(plot_df.index.values): cumulative_sum = 0 for i, (col, proportion) in enumerate(zip(cols, plot_df_percent.loc[x])): current_value = plot_df.iloc[n, i] # 计算标签垂直位置:当前堆叠的中心 y_loc = cumulative_sum + current_value / 2 # 计算百分比数值 percent = np.round(proportion * 100, 1) # 仅显示占比超过阈值的标签 if percent >= label_threshold: # 根据占比动态调整字体大小,最小保证8号字可读性 font_size = max(8, 12 - int((10 - percent) * 0.4)) plt.text( x=n - 0.17, y=y_loc, s=f'{percent}%', color="black", fontsize=font_size, fontweight="bold" ) cumulative_sum += current_value plt.savefig(f'draft/{title}.png') plt.show()
代码关键说明
label_threshold为可自定义参数,可根据数据集情况调整(比如设为0.5显示更低占比的标签)- 字体大小随占比动态变化,避免小区域标签过大占用空间
- 用
cumulative_sum替代原代码的切片求和,计算更高效且逻辑更清晰
内容的提问来源于stack exchange,提问作者moonwalker7
相关产品推荐
相关产品推荐

