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

如何用Python/Plotly绘制x轴为工作日y轴为24小时范围的柱状图

Plotly人员工时可视化实现方案

核心功能实现

  • 支持美国4个常用时区切换(MT/PT/CT/ET),自动换算对应工时
  • X轴为周一到周日7个工作日,Y轴为24小时时间范围,反转后时段垂直向下展示
  • 多人工时重叠展示,透明度设置为0.6区分重叠区域
  • 下拉菜单切换时自动刷新全图数据

完整可运行代码

import plotly.graph_objects as go
import pandas as pd
from datetime import datetime, timedelta

# ---------------------- 1. 基础配置与原始数据定义 ----------------------
# 员工列表与对应UTC时区的上班时间、工时长度、工作日期,可按格式补充所有员工
employee_config = [
    {"name": "Paige", "utc_start_hour": 13, "work_hours": 8, "work_days": [0,1,2,3,4]}, # 0=周一,6=周日
    {"name": "Julissa", "utc_start_hour": 16, "work_hours": 8, "work_days": [0,1,2,3,4]},
    {"name": "Jessica", "utc_start_hour": 13, "work_hours": 8, "work_days": [0,1,2,3,4]},
    {"name": "David", "utc_start_hour": 14, "work_hours": 8, "work_days": [0,1,2,3,4]},
    {"name": "Nicole", "utc_start_hour": 12, "work_hours": 8, "work_days": [0,1,2,3,4]}
]
week_days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
# 美国时区定义:时区名与UTC偏移小时
timezone_config = {
    "ET": -5,
    "CT": -6,
    "MT": -7,
    "PT": -8
}

# ---------------------- 2. 数据转换函数 ----------------------
def generate_tz_data(tz_offset):
    df_list = []
    for emp in employee_config:
        for day_idx in emp["work_days"]:
            # 换算对应时区的开始时间,跨天自动取模
            tz_start_hour = (emp["utc_start_hour"] + tz_offset) % 24
            df_list.append({
                "dow": week_days[day_idx],
                "employee": emp["name"],
                "start": tz_start_hour,
                "duration": emp["work_hours"]
            })
    return pd.DataFrame(df_list)

# ---------------------- 3. 初始化绘图 ----------------------
# 默认加载MT时区数据
initial_tz = "MT"
initial_offset = timezone_config[initial_tz]
df = generate_tz_data(initial_offset)

fig = go.Figure()
# 批量添加员工trace
for emp in df["employee"].unique():
    emp_df = df[df["employee"] == emp]
    fig.add_trace(go.Bar(
        x=emp_df["dow"],
        y=emp_df["duration"],
        base=emp_df["start"],
        name=emp,
        opacity=0.6,
        width=0.8
    ))

# ---------------------- 4. 配置下拉菜单 ----------------------
buttons = []
for tz_name, tz_offset in timezone_config.items():
    tz_df = generate_tz_data(tz_offset)
    # 构造每个按钮的更新参数
    x_list = []
    y_list = []
    base_list = []
    for emp in df["employee"].unique():
        emp_df = tz_df[tz_df["employee"] == emp]
        x_list.append(emp_df["dow"])
        y_list.append(emp_df["duration"])
        base_list.append(emp_df["start"])
    buttons.append(dict(
        label=tz_name,
        method="update",
        args=[
            {"x": x_list, "y": y_list, "base": base_list},
            {"title": f"CSI工作小时({tz_name}时区)"}
        ]
    ))

fig.update_layout(
    updatemenus=[dict(
        active=list(timezone_config.keys()).index(initial_tz),
        buttons=buttons,
        x=0.1,
        y=1.15
    )],
    title=f"CSI工作小时({initial_tz}时区)",
    xaxis={"title": "工作日", "categoryorder": "array", "categoryarray": week_days},
    yaxis={
        "title": "时间",
        "range": [24, 0], # 反转Y轴,0点在顶部
        "tickmode": "linear",
        "dtick": 1,
        "ticktext": [f"{h}:00" for h in range(24)],
        "tickvals": list(range(24))
    },
    barmode="overlay", # 重叠展示
    legend={"title": "员工"}
)

fig.show()

关键调整说明

  • 原始数据统一用UTC时间存储,切换时区时仅做小时偏移换算,无需维护多份数据,支持跨天工时自动适配
  • 取消原代码的barmode=group,改为barmode=overlay配合透明度参数,实现同个工作日多人工时重叠展示
  • Y轴固定为0-23的小时刻度,反转后天然符合时段垂直向下展示的需求
  • 下拉菜单切换时直接更新所有trace的x、y、base参数,无需重建图表,响应速度更快

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 23:48:03