我想绘制一个条形图(或直方图,而不是其他图),以使x值对应于时间段,但x轴标签是从00:00到23:59,间隔时间为半小时。
问题出在我的数据帧中:[[Start Time]]列中的值类型为“ datetime.time”
0 00:30:00
1 06:00:00
2 07:00:00
3 09:10:00
4 15:30:00
5 18:00:00
6 19:00:00
['Main Street Green(s)']是相应的值。例如:
0 NaN
1 13.5
2 25.5
3 50.5
4 55.5
5 20.5
6 38.5
我希望从00:00到00:30的酒吧的高度为0,从00:30到06:00的酒吧的高度为13.5从06:30到07:00的酒吧的高度为25.5 ...
我看过很多线图。https://www.programcreek.com/python/example/61484/matplotlib.dates.HourLocator是我找到的最有价值的资源
plt.rcParams['figure.figsize'] = (8.0, 6.0)
ax = plt.subplot(111)
ax.plot(Dayton_weekday["Start Time"], Dayton_weekday['Main Street Green (s)'], color = 'blue', label="main street")
#set ticks every half an hour
ax.xaxis.set_major_locator(mdates.HourLocator(byhour=range(0,24,48)))
#set major ticks format
ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
ax.set_xlim(["00:00", "23:59"])
ax.set_ylim(bottom=0)
在我的代码中,我使用ax.plot,这是因为如果我使用ax.bar,则会返回“ ValueError:微秒必须在0..999999中”,因此我不知道如何使用我拥有的数据绘制条形图
这是一种应该为您提供所需方法的方法。
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()
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句