python - 有没有办法用 plotly 或 python 创建条形图可视化,其中 y 轴是 24 小时范围,x 轴是所有工作日?
问题描述
我正在尝试创建一组人的工作时间的可视化(最好使用 plotly,因为我想合并一个下拉栏,允许用户在美国的时区之间切换并相应地调整时间)。x 轴是工作日,y 轴是 24 小时范围,条形图会垂直向下(显示某人在周一至周五早上 7 点至下午 3 点工作)并且可以与其他人的工作时间重叠(我知道我需要使用不透明度参数)。
到目前为止,我已经尝试了很多东西,最接近的是以下代码:
import plotly.graph_objects as go
import pandas as pd
# Initialize figure
fig = go.Figure()
week_days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
# Add Traces
fig.add_trace(
go.Bar(x=week_days,
name="Nicole",
#line=dict(color="#33CFA5")
))
#fig.update_yaxes(strftime("%H:%M"))
fig.update_layout(
updatemenus=[
dict(
active=0,
buttons=list([
dict(label="None",
method="update",
args=[{"visible": [True, False, True, False]},
{"title": "CSI Work Hours",
#"annotations": []
}]),
dict(label="MT",
method="update",
args=[{"visible": [True, False, False, False]},
{"title": "MT",
#"annotations": high_annotations
}]),
dict(label="PT",
method="update",
args=[{"visible": [False, False, True, True]},
{"title": "PT",
#"annotations": low_annotations
}]),
dict(label="HT",
method="update",
args=[{"visible": [True, True, True, True]},
{"title": "HT",
#"annotations": high_annotations + low_annotations
}]),
]),
)
])
# Set title
fig.update_layout(title_text="CSI")
fig.show()
#create plot with days of week as x-axis, 24hr range as y-axis
fig, ax = plt.subplots(figsize=(15,15))
#ax.plot_date(start_date, end_date, ydate=True, xdate=False)
#number of days in week 7, set to x-axis to display all week days
l = range(0,7)
week_days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
# reformat axis ticks to only show hour/min on y-axis; label x-axis w/ week days
from matplotlib.dates import DateFormatter
from matplotlib.axis import Axis
ax.yaxis.set_major_formatter(DateFormatter('%H:%M'))
ax.yaxis.set_major_locator(HourLocator())
ax.invert_yaxis()
#ax.set_yticks(t)
ax.set_xticks(l)
ax.set_xticklabels(week_days)
![上面代码的情节#2][2]
对于实际的数据点,我尝试为每个人或每个时区创建字典,但我不知道如何绘制数据点列表。
person1_hrs_dict = {'Monday' : [7,8,9,10,11,12,13,14,15],
'Tuesday' : [7,8,9,10,11,12,13,14,15],
'Wednesday' : [7,8,9,10,11,12,13,14,15],
'Thursday' : [7,8,9,10,11,12,13,14,15],
'Friday' : [7,8,9,10,11,12,13,14,15],
'Saturday' : 0,
'Sunday' : 0
}
MT_hrs_dict = {"weekdays":["Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday", "Sunday"],
"csi team": ["person1","person2",etc],
"work hours": []}
#I don't think MT_hrs_dict would work since some people work weekends and have some weekdays off.
#I think I'm overcomplicating it or maybe creating text document might be easier?
这是新的尝试:
employees = list(["Paige","Julissa","Jessica","David","Jamila","Eric Pt",
"Nicole","Jackie","Christian","McKay","Eric Pxt","Krissa",
"Brynn","Jordan","Ethan","Andrew","Tysen","Austin","Dalin",
"Alex","Pierce","Astha","Spencer","Edgar","Mike","Tiffany"])
df = pd.DataFrame(
itertools.product(
pd.date_range("18-oct-2021", periods=7, freq="D").values, employees
),
columns=["date", "employee"],
)
csi_times=["8:00:00.00","11:00:00.00","8:00:00.00","9:00:00.00",
"10:00:00.00","8:00:00.00","7:00:00.00","9:00:00.00",
"8:00:00.00","14:30:00.00","9:00:00.00","7:00:00.00",
"8:00:00.00","9:00:00.00","9:00:00.00","7:00:00.00",
"22:00:00.00","22:00:00.00","9:00:00.00","15:00:00.00",
"10:00:00.00","9:00:00.00","8:00:00.00","22:00:00.00",
"10:00:00.00","7:30:00.00"]
times_format = '%H:%M:%S.%f'
worked_hours = []
n=8
for time in csi_times:
given_times = datetime.strptime(time, date_format_str)
final_times = given_times + timedelta(hours=n)
final_time_strngs = final_times.strftime('%H:%M')
worked_hours.append(final_time_strngs)
#print(csitimes)
df["start"]=csi_times*7
df["hoursworked"]= worked_hours*7
df["dow"]=df["date"].dt.strftime("%a")
#8,11,8,9,10,8,7,9,8,14,9,7,8,9,9,7,22,22,9,15,10,9,8,22,10,7
#create the figure as bar graph
fig = px.bar(df, x="dow", y="hoursworked", base="start", color="employee", barmode="group",
labels={
"dow": "Days of Week",
"hoursworked": "Working Hours",
"employee": "CSI Team"
},
title="CSI Working Hours")
#reverse y axis so it starts with 0 (12AM) and goes down to 23(11PM)
fig.update_layout(
yaxis = dict(autorange = "reversed")
)
fig.show()
解决方案
- 做你描述的很简单。已经完成了你所描述的,用星期几、开始、工作时间、员工构建了一个数据框
- 然后这变成一个简单的条形图,其中dayofweek是xaxis和yaxis一个条形图,显示开始时间和工作小时数
import itertools
import pandas as pd
import numpy as np
import plotly.express as px
employees = list("ABC")
df = pd.DataFrame(
itertools.product(
pd.date_range("18-oct-2021", periods=7, freq="D").values, employees
),
columns=["date", "employee"],
).pipe(
lambda d: d.assign(
start=np.random.randint(1, 10, len(d)),
hoursworked=lambda d: np.random.randint(3, 10, len(d)),
dow=d["date"].dt.strftime("%a")
)
)
px.bar(df, x="dow", y="hoursworked", base="start", color="employee", barmode="group")
数据框样本
日期 | 员工 | 开始 | 工作时间 | 道琼斯指数 |
---|---|---|---|---|
2021-10-18 00:00:00 | 一个 | 3 | 5 | 星期一 |
2021-10-18 00:00:00 | 乙 | 3 | 5 | 星期一 |
2021-10-18 00:00:00 | C | 4 | 4 | 星期一 |
2021-10-19 00:00:00 | 一个 | 6 | 6 | 周二 |
2021-10-19 00:00:00 | 乙 | 1 | 8 | 周二 |
2021-10-19 00:00:00 | C | 9 | 5 | 周二 |
2021-10-20 00:00:00 | 一个 | 7 | 4 | 星期三 |
2021-10-20 00:00:00 | 乙 | 2 | 4 | 星期三 |
2021-10-20 00:00:00 | C | 1 | 4 | 星期三 |
2021-10-21 00:00:00 | 一个 | 3 | 6 | 星期四 |
数据框构造 - 更简单的语法
df = pd.DataFrame(
itertools.product(
pd.date_range("18-oct-2021", periods=7, freq="D").values, employees
),
columns=["date", "employee"],
)
df["start"] = np.random.randint(1, 10, len(df))
df["hoursworked"] = np.random.randint(3, 10, len(df))
df["dow"] = df["date"].dt.strftime("%a")
推荐阅读
- vba - VBA - 对象被拒绝
- javascript - 如何从灯箱画廊中触发无限滚动 - Django / FancyBox / Waypoints.js
- google-cloud-platform - 计算实例在 100% CPU 使用数小时后被删除
- c# - 使用 AT 命令发送包含表情符号的短信
- flutter - 如何更改颤动中图表的默认调色板?
- javascript - 如何使用 DRY 概念获取这些数据?
- saml-2.0 - 颁发者 ITfoxtec.Identity.Saml2 的多个证书
- express - 使用 vue cdn 分离组件文件
- python - Words 中的反斜杠冲突和 Pyparsing 中的换行符
- java - Gradle JAR 添加到类路径