我想在 Plotly 和 Pandas 中重新创建以下图像。但我不知道如何。
我研究过使用甘特图,但每次我看到一个时间线都是沿着 x 轴而不是像这张图中那样沿着 y 轴。有人有什么建议吗?
我认为甘特图不能轻易旋转,但最重要的信息是每个条形的持续时间。我们真正想要的是一个垂直条形图,其中每个条形都是时间的持续时间,使用开始时间作为每个条形的基础。
我建议您以 24 小时制输入时间,以便正确计算持续时间。
您可以使用以下内容作为要创建的图表的模板:
import pandas as pd
import plotly.graph_objects as go
from datetime import datetime
df = pd.DataFrame({
'start': ['2024-06-17 00:04', '2024-06-18 00:24', '2024-06-18 23:54', '2024-06-19 23:59'],
'end': ['2024-06-17 08:18', '2024-06-18 09:05', '2024-06-19 09:02', '2024-06-20 08:13'],
})
df['start'] = pd.to_datetime(df['start'])
df['end'] = pd.to_datetime(df['end'])
df['duration'] = df['end'] - df['start']
fig = go.Figure()
def get_exact_hour(ts):
## we want 23:54 to become -1 on the graph
if ts.hour > 12:
hour = ts.hour - 24
else:
hour = ts.hour
minute = ts.minute
return hour + minute/60
def convert_duration_to_hours(td: pd.Timedelta):
hours = duration.seconds // 3600
minutes = (duration.seconds % 3600) / 60
return hours + minutes/60
for start, end, duration in df.itertuples(index=False):
day_rounded = start.round('1d') - pd.Timedelta("1D")
day_name = day_rounded.day_name()
day_number = day_rounded.day
day_string = f"{day_name} </br></br> {day_number}"
start_hour = get_exact_hour(start)
end_hour = get_exact_hour(end)
duration_in_hours = convert_duration_to_hours(duration)
fig.add_trace(
go.Bar(
x=[day_string],
y=[duration_in_hours],
base=[start_hour],
marker=dict(color='lightblue'),
)
)
## add start and end times text annotations
start_time_formatted = start.strftime("%I:%M")
end_time_formatted = end.strftime("%I:%M")
padding = 0.2
fig.add_trace(
go.Scatter(
x=[day_string],
y=[start_hour-padding],
mode='text',
text=[start_time_formatted],
)
)
fig.add_trace(
go.Scatter(
x=[day_string],
y=[end_hour+padding],
mode='text',
text=[end_time_formatted],
)
)
## prettify the chart
fig.update_xaxes(type='category')
fig.update_layout(
template='plotly_dark',
title='TIME IN BED',
barcornerradius=15,
showlegend=False
)
fig.show()