堆叠条形图优化求助:内部排序、渐变配色及图例调整
堆叠条形图三项优化的Python实现方案
我已经绘制了堆叠条形图,尝试通过以下三项优化提升可读性但未成功,仅找到JavaScript示例,现寻求Python代码解决:
- 按计数对每个条形(根意图列)内部的元素从大到小排序
- 为每个根意图列分配不同色系的渐变配色(比如蓝色系、绿色系等)
- 图例按根意图列的堆叠元素顺序排列,而非字母顺序
以下是修改后的完整代码,针对三个需求逐一实现:
import pandas as pd import matplotlib.pyplot as plt def predicted_intents_plot(excel_file): intents = pd.read_excel(excel_file, usecols=['root_intent_title','predicted_intent_title']) # 获取Top5根意图 root_intents_counts = intents['root_intent_title'].value_counts() top_5_root_intents = root_intents_counts.nlargest(5).index.tolist() filtered_intents = intents[intents['root_intent_title'].isin(top_5_root_intents)] # 分组统计每个根意图下的预测意图计数 grouped_intents = filtered_intents.groupby(['root_intent_title','predicted_intent_title']).size() # 每个根意图保留Top3预测意图 top_3_predicted_intents_per_root = grouped_intents.groupby(level=0).apply( lambda x: x.nlargest(3 if len(x) > 3 else len(x)) ).reset_index(level=1, drop=True).reset_index() top_3_predicted_intents_per_root.columns = ['Root Intent Title', 'Intent', 'Counts'] # 按根意图总计数排序根意图顺序 total_counts = top_3_predicted_intents_per_root.groupby('Root Intent Title')['Counts'].sum().sort_values(ascending=False) root_order = total_counts.index.tolist() top_3_predicted_intents_per_root['Root Intent Title'] = pd.Categorical( top_3_predicted_intents_per_root['Root Intent Title'], categories=root_order, ordered=True ) # 1. 为每个根意图单独处理内部堆叠顺序(按Counts降序) sorted_groups = top_3_predicted_intents_per_root.groupby('Root Intent Title', group_keys=False).apply( lambda x: x.sort_values('Counts', ascending=False) ) # 2. 定义每个根意图的渐变色系 root_color_palettes = { root_order[0]: ['#001f3f', '#0074D9', '#7FDBFF'], # 蓝色系渐变 root_order[1]: ['#00441b', '#2ECC40', '#A3F7BF'], # 绿色系渐变 root_order[2]: ['#4a0000', '#FF4136', '#FF9F99'], # 红色系渐变 root_order[3]: ['#4B0082', '#B10DC9', '#F1EAFF'], # 紫色系渐变 root_order[4]: ['#85660d', '#FFDC00', '#FFF69F'] # 黄色系渐变 } # 建立意图到颜色的映射 color_map = {} for root in root_order: group = sorted_groups[sorted_groups['Root Intent Title'] == root] colors = root_color_palettes[root][:len(group)] for intent, color in zip(group['Intent'], colors): color_map[intent] = color # 绘制堆叠条形图(手动控制堆叠顺序) fig, ax = plt.subplots(figsize=(10,5)) bar_width = 0.8 x_pos = range(len(root_order)) bottom = [0]*len(root_order) # 收集图例项,按根意图的堆叠顺序排列 legend_handles = [] legend_labels = [] # 按根意图顺序,逐个绘制每个堆叠层 for root in root_order: group = sorted_groups[sorted_groups['Root Intent Title'] == root] for idx, row in group.iterrows(): intent = row['Intent'] count = row['Counts'] root_idx = root_order.index(root) # 绘制当前堆叠段 bar = ax.bar( root_idx, count, bar_width, bottom=bottom[root_idx], color=color_map[intent], label=intent if intent not in legend_labels else "" ) bottom[root_idx] += count # 只添加一次图例项 if intent not in legend_labels: legend_handles.append(bar[0]) legend_labels.append(intent) # 3. 按堆叠顺序设置图例 ax.legend(handles=legend_handles, labels=legend_labels, bbox_to_anchor=(1.05, 1), loc='upper left') # 图表样式调整 ax.set_xticks(x_pos) ax.set_xticklabels(root_order, rotation=0, ha='center') ax.set_xlabel("", size=10) ax.set_ylabel("", size=10) plt.tick_params(axis='both', which='both', length=0) # 边框样式 ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.spines['left'].set_visible(False) ax.spines['bottom'].set_color((64/255, 64/255, 64/255)) # 文字颜色 text_color = (64/255, 64/255, 64/255) ax.xaxis.label.set_color(text_color) ax.yaxis.label.set_color(text_color) for tick in ax.get_xticklabels(): tick.set_color(text_color) for tick in ax.get_yticklabels(): tick.set_color(text_color) plt.tight_layout() plt.show()
优化点说明
- 条形内部按计数排序:通过对每个根意图的分组数据单独按
Counts降序排序,手动绘制每个堆叠段,确保每个条形内的元素从大到小排列,解决了原pivot方式导致的全局顺序问题。 - 根意图专属渐变色系:为每个Top5根意图定义了从深到浅的专属色系,通过
color_map将每个意图映射到对应色系的颜色,让不同根意图的条形区分度更高。 - 按堆叠顺序排列图例:在绘制过程中收集图例项,确保图例顺序与每个根意图内堆叠元素的出现顺序一致(即计数从高到低的顺序),而非默认的字母排序。
内容的提问来源于stack exchange,提问作者tribolil
相关产品推荐
相关产品推荐

