如何使用pyplot绘制Pandas DataFrame中按员工分类的工时区间图
实现思路
用matplotlib的横向条形图(barh)就可以完美实现这类时间区间展示,核心是利用它支持自定义条的起始位置、宽度的特性,匹配我们的工时Start值、工作时长。
分步实现逻辑
- 把字符串类型的员工标识映射成数值型的y轴坐标,解决matplotlib不支持字符串直接做刻度的问题
- 计算每条工时的实际长度(
End - Start),作为横向条的宽度参数 - 遍历每条工时记录,在对应条的居中位置添加起止时间的文本标注
- 调整坐标轴范围、刻度样式,避免图形元素被裁切
可直接运行的完整代码
import pandas as pd import matplotlib.pyplot as plt # 载入原始工时数据 data = [['Jack', 0, 6], ['Jack', 8, 12],['Barry', 0, 5], ['Barry', 7, 15]] df = pd.DataFrame(data, columns=['Employee', 'Start', 'End']) # 1. 建立员工到y轴位置的映射 unique_emps = df['Employee'].unique() emp_y_mapping = {emp: idx for idx, emp in enumerate(unique_emps)} df['y_coordinate'] = df['Employee'].map(emp_y_mapping) # 计算每条工时的持续时长,作为横向条的宽度 df['work_duration'] = df['End'] - df['Start'] # 2. 初始化画布并绘制横向区间条 plt.figure(figsize=(8, 4)) plt.barh( y=df['y_coordinate'], width=df['work_duration'], left=df['Start'], height=0.4, color='#619CFF' ) # 3. 为每个区间添加起止时间标注 for _, record in df.iterrows(): # 标注位置设在条的水平中心、垂直居中位置 label_x = record['Start'] + record['work_duration'] / 2 label_y = record['y_coordinate'] plt.text( x=label_x, y=label_y, s=f"{record['Start']}-{record['End']}", ha='center', va='center', color='white', fontsize=10 ) # 4. 调整坐标轴和图形样式 # 把y轴数值位置替换成对应员工名 plt.yticks(ticks=list(emp_y_mapping.values()), labels=list(emp_y_mapping.keys())) # 反转y轴方向,让第一个出现的员工在最上方,匹配常规图表阅读习惯 plt.gca().invert_yaxis() plt.xlabel('时间轴') plt.title('员工工作区间分布') # 扩展x轴范围,避免最右侧的条和文字被画布边缘裁切 plt.xlim(0, df['End'].max() + 1) # 隐藏顶部和右侧的边框,视觉上更清爽 plt.gca().spines[['top', 'right']].set_visible(False) plt.tight_layout() plt.show()
实用调整技巧
- 如果需要区分不同员工的条颜色,只要给
barh的color参数传入和记录数长度一致的颜色列表即可 - 如果标注文字在条上的可读性差,可以把文字颜色改成黑色,或者调整条的填充透明度
- 如果同一员工的多个区间存在重叠,可以适当缩小
height参数,或者给同一员工的不同条添加微小的y轴偏移量,避免元素遮挡 - 调整员工在y轴的上下顺序,只要修改员工映射的顺序,或者开关
invert_yaxis()即可
内容的提问来源于stack exchange,提问作者Jerry Stackhouse
相关产品推荐
相关产品推荐

