如何基于指定DataFrame绘制带两级X轴的柱状图(支持Matplotlib/Seaborn)
实现两级X轴的柱状图(基于你的DataFrame)
下面用Matplotlib实现你要的两级X轴柱状图,完全匹配需求:
步骤1:导入库并准备数据
先导入依赖库,再加载你的DataFrame数据:
import pandas as pd import matplotlib.pyplot as plt # 你的DataFrame数据 data = { 'SP1-SP2': ['AFR-AMR', 'AFR-AMR', 'AFR-AMR', 'AFR-EAS', 'AFR-EUR', 'AFR-EUR', 'AFR-EUR', 'AFR-EUR', 'AFR-SAS', 'AMR-AMR', 'AMR-EAS'], 'P1-P2': ['ACB-CLM', 'CLM-LWK', 'ESN-MXL', 'KHV-MSL', 'CEU-ACB', 'FIN-LWK', 'GWD-GBR', 'LWK-IBS', 'YRI-PJL', 'PEL-CLM', 'CHS-MXL'], 'gmm Fowlkes Mallows': [0.883981, 0.630063, 0.944129, 0.916021, 0.892367, 0.875518, 0.934915, 0.943654, 0.646557, 0.993127, 0.886552], 'kmeans Fowlkes Mallows': [0.973784, 0.649272, 0.974126, 0.960642, 0.911122, 0.886502, 0.963250, 0.974227, 0.517052, 0.996963, 0.924213] } df = pd.DataFrame(data)
步骤2:处理分组与位置参数
按SP1-SP2分组,计算每个分组的子项数量,用来确定柱子和主X轴标签的位置:
# 按SP1-SP2分组,获取分组名称和每个分组的子项数 groups = df.groupby('SP1-SP2') group_names = list(groups.groups.keys()) group_sizes = [len(groups.get_group(name)) for name in group_names] # 计算每个柱子的位置(每个子项对应gmm和kmeans两个柱子) bar_width = 0.35 total_positions = [] current_pos = 0 for size in group_sizes: # 每个子项占bar_width*2的宽度,给两个柱子留空间 positions = [current_pos + i*(bar_width*2) + j*bar_width for i in range(size) for j in range(2)] total_positions.extend(positions) current_pos += size*(bar_width*2) + bar_width # 分组之间留间隙 # 计算主X轴标签的位置(每个分组的中间位置) group_mid_positions = [] current_mid = (group_sizes[0]*(bar_width*2))/2 - bar_width/2 group_mid_positions.append(current_mid) for i in range(1, len(group_sizes)): current_mid += group_sizes[i-1]*(bar_width*2) + bar_width + (group_sizes[i]*(bar_width*2))/2 group_mid_positions.append(current_mid)
步骤3:绘制柱状图并设置两级X轴
plt.figure(figsize=(12, 6)) # 绘制gmm和kmeans的柱子 gmm_bars = plt.bar([pos for pos in total_positions[::2]], df['gmm Fowlkes Mallows'], width=bar_width, label='gmm Fowlkes Mallows', color='#1f77b4') kmeans_bars = plt.bar([pos for pos in total_positions[1::2]], df['kmeans Fowlkes Mallows'], width=bar_width, label='kmeans Fowlkes Mallows', color='#ff7f0e') # 设置次级X轴(下方显示P1-P2标签) plt.xticks([(total_positions[2*i] + total_positions[2*i+1])/2 for i in range(len(df))], df['P1-P2'], rotation=45, ha='right') # 添加主X轴(上方显示SP1-SP2分组) ax = plt.gca() ax2 = ax.twiny() ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(group_mid_positions) ax2.set_xticklabels(group_names) # 调整主X轴标签位置,避免和次级标签重叠 ax2.tick_params(axis='x', pad=25) # 添加图表元素 plt.ylabel('Fowlkes Mallows Score') plt.title('GMM vs KMeans Fowlkes Mallows Scores Comparison') plt.legend() plt.tight_layout() plt.show()
效果说明
- 下方次级X轴显示每个柱子对应的
P1-P2子标签 - 上方主X轴显示
SP1-SP2分组名称,每个分组对应一组柱子 - 两种颜色分别区分gmm和kmeans的指标值,直观对比两组数据
内容的提问来源于stack exchange,提问作者Eitamar Saraf
相关产品推荐
相关产品推荐

