You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

分组DataFrame后如何设置分段条形图的排列顺序

解决分段水平条形图的Y轴排序问题

原有代码用于绘制乐队成员加入/离开时间段的分段水平条形图(broken barh),现在需要让Y轴的人员及对应条形按**最早加入年份(Year_start最小值)和最晚离开年份(Year_left最大值)**升序排列。已经写出了聚合排序的代码,但不知道怎么嵌入绘制逻辑。

修改后的完整代码

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

result = pd.DataFrame([['Bill', 1972, 1974],
                       ['Bill', 1976, 1978],
                       ['Bill', 1967, 1971],
                       ['Danny', 1969, 1975],
                       ['Danny', 1976, 1977],
                       ['James', 1971, 1972],
                       ['Marshall', 1967, 1975]],
                      columns=['Person', 'Year_start', 'Year_left'])

# 保留你写的聚合排序逻辑,提取排序后的人员列表
sorted_result = result.groupby('Person').agg({'Year_start': min, 'Year_left': max})
sorted_result = sorted_result.sort_values(['Year_start', 'Year_left'], ascending=[True, True]).reset_index()
ordered_names = sorted_result['Person'].tolist()

fig, ax = plt.subplots()

colormap = plt.get_cmap('plasma')
slicedColorMap = colormap(np.linspace(0, 1, len(ordered_names)))

height = 0.5
# 按排序后的人员顺序遍历绘图
for y, name in enumerate(ordered_names):
    g = result[result['Person'] == name]
    ax.broken_barh(list(zip(g['Year_start'],
                            g['Year_left']-g['Year_start'])),
                   (y-height/2, height),
                   facecolors=slicedColorMap[y]
                   )

ax.set_ylim(0-height, len(ordered_names)-1+height)
ax.set_xlim(result['Year_start'].min()-1, result['Year_left'].max()+1)
ax.set_yticks(range(len(ordered_names)), ordered_names)

ax.grid(True)
plt.show()

关键改动说明

  • 直接复用你写的聚合排序代码,从中提取出排序后的人员列表ordered_names,这就是Y轴最终的展示顺序
  • 替换原有默认分组遍历的逻辑,改为按ordered_names的顺序逐个获取对应成员的所有时间段数据
  • Y轴刻度、颜色映射全部基于排序后的列表设置,保证人员顺序与条形完全对应

这样修改不需要大幅重构原有脚本,只是调整了遍历顺序的来源,就能实现需求的排序效果。

内容的提问来源于stack exchange,提问作者muted_buddy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 14:42:08