这是一种可以为您提供所需内容的方法。
import datetime as dt
import matplotlib.pyplot as plt
import numpy as np
手动创建我们想要绘制的时间。在您的数据集中,列出的时间与上一栏的结束时间相对应。为了适应酒吧经过午夜的情况,时间可能更容易与酒吧的开始相对应。在下面的代码中,我修改了您的原始数据集以使用这种方法。列表中的第一个时间将是图的 x 轴上列出的第一个时间。
times = [dt.time(0,30,0),
dt.time(6,0,0),
dt.time(7,0,0),
dt.time(9,10,0),
dt.time(15,30,0),
dt.time(18,0,0),
dt.time(19,0,0)]
而不是绘制dt.time()
在 x 轴上,可以更轻松地绘制一天中经过的秒数。下面我们使用列表理解来转换times
进入经过的秒数。
seconds = [(x.hour * 3600 + x.minute * 60 + x.second)
for x in times]
注意:我删除了NaN
在。。。之初values
并添加了一个虚构的5.5
到最后,以便可以显示从 19:00 到 0:30 的柱线示例。
# manually add the y-axis values
values = [13.5,
25.5,
50.5,
55.5,
20.5,
38.5,
5.5]
现在我们创建两个列表,用于指定刻度在 x 轴上的放置位置,以及为每个刻度分配什么标签。如果经过的秒数可以被 1800(30 分钟)整除,则该数字将用作刻度之一。start_time
将是第一个项目经过的秒数times
。这是 x 轴开始的位置。
start_time = (times[0].hour * 3600 + times[0].minute * 60 + times[0].second)
xticks = [x + start_time for x in range(60 * 60 * 24) if x % 1800 == 0]
为了显示时间而不是经过的秒数,我们必须使用dt.timedelta()
将整数转换为dt.time
。如果start_time
是一个大于0
,那么就会有xticks
值至少为86400
。我们必须减去86400
从这些值,以防止xticklabels
从出现为one day, 0:30
.
def label_format(seconds):
if seconds >= 86400:
seconds -= 86400
return str(dt.timedelta(seconds=seconds))
xticklabels = [label_format(x) for x in xticks]
现在我们可以创建情节了。由于我们要创建条形宽度不等的直方图样式图表,因此我们需要一种方法来指定条形宽度。bar_traits()
可用于根据 x 轴的起点和下一个条形的起点来确定条形的起点和宽度。
def bar_traits(ix, second, seconds, start_time):
if ix < len(seconds) - 1:
if seconds[ix + 1] < second:
width = 86400 + seconds[ix + 1] - second
else:
width = seconds[ix + 1] - second
else:
if start_time < second:
width = 86400 + start_time - second
else:
width = start_time - second
if start_time > second:
second += 86400
return second, width
使用代码创建绘图bar_traits()
处理午夜的绘图。
fig, ax = plt.subplots(figsize=(16,8))
for ix, (second, value) in enumerate(zip(seconds, values)):
second, width = bar_traits(ix, second, seconds, start_time)
ax.bar(second, value, width=width, align='edge', color='C0')
ax.set_xticks(xticks)
ax.set_xticklabels(xticklabels, rotation=90)
plt.show()
![enter image description here](https://i.stack.imgur.com/vn5gN.png)