从日期时间对象列表中绘制matplotlib中的日期和时间

时间:2019-12-14 20:48:17

标签: python pandas datetime matplotlib

我想做的只是从日期时间对象列表构建散点图,时间在Y轴上从00:00到24:00,在X轴上是日期,并且对应于列表中的datetime对象。

在阅读了尽可能多的关于该问题的参考文献之后,这样做似乎比我最初想象的要复杂得多,并且永远无法满足我的需求。也许我只是误读了关于matplotlib.dates的文档?从多个stackoverflow帖子和相应的文档中,您只能用日期绘制值,或者只用值绘制时间,或者如果可以同时绘制两个值,则不能正确使用matplotlib日期格式化程序。从我所见,Pandas可能是最好的解决方案,但是它也有缺点,特别是在日期格式器和定位器以及注册转换器方面,这似乎破坏了matplotlib的其他部分。更不用说我们是否应该将datetime对象转换为matplotlib.dates格式,还是使用plt.plot,plt.scatter或plot_dates,它们似乎都可以与某些功能一起使用,而对于其他功能却不起作用。更不用说Locator.MAXTICKS等报告的其他错误。

所以,请有人帮我清除所有这些信息。

就代码而言,我尝试了所有这些方法都有很多片段,但是如果有人需要一个起点,这是一个片段(如果有什么用的话,还有各种方法的注释):

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import datetime
import random

from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()

# Generate random datetime's
def getRandDate(i):
    randDate = '{}-{}-{}'.format(2019, random.randint(1, 12), i) #random.randint(1,28))
    randTime = '{}:{}:{}'.format(random.randint(1,23), random.randint(1,59), random.randint(1,59))
    timeStrng = randDate + ' ' + randTime
    return datetime.datetime.strptime(timeStrng, '%Y-%m-%d %H:%M:%S')

dteTms1 = [getRandDate(i) for i in range(1,28)]
dteTms2 = [getRandDate(i) for i in range(1,28)]

x_axis1, y_axis1 = zip(*[(item.date(),item.time()) for item in dteTms1])
x_axis2, y_axis2 = zip(*[(item.date(),item.time()) for item in dteTms2])

fig, ax = plt.subplots()

ax.plot(x_axis1, y_axis1, 'ro', markersize=1)
ax.plot(x_axis2, y_axis2, 'go', markersize=1)
ax.set_ylim(["00:00:00", "23:59:59"])

ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) 
ax.xaxis.set_minor_locator(mdates.DayLocator())
#ax.yaxis.set_major_locator(mdates.HourLocator()) # This breaks the y axis
#ax.yaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))

fig.autofmt_xdate()
plt.show()

如果有人愿意,我还可以添加所有SO帖子和文档的链接列表。最后,感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

Matplotlib不提供仅格式化时间的功能。因此,您需要绘制任意一天的时间。假设我们选择了1900年1月的第一天。那么该示例可能如下所示:

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import datetime
import random

from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()

# Generate random datetime's
def getRandDate(i):
    randDate = '{}-{}-{}'.format(2019, random.randint(1, 12), i) #random.randint(1,28))
    randTime = '{}:{}:{}'.format(random.randint(1,23), random.randint(1,59), random.randint(1,59))
    timeStrng = randDate + ' ' + randTime
    return datetime.datetime.strptime(timeStrng, '%Y-%m-%d %H:%M:%S')

dteTms1 = [getRandDate(i) for i in range(1,28)]
dteTms2 = [getRandDate(i) for i in range(1,28)]

x_axis1, y_axis1 = zip(*[(item.date(),item.time()) for item in dteTms1])
x_axis2, y_axis2 = zip(*[(item.date(),item.time()) for item in dteTms2])


dday = datetime.datetime(1900,1,1)
y_axis1 = [datetime.datetime.combine(dday, t) for t in y_axis1]
y_axis2 = [datetime.datetime.combine(dday, t) for t in y_axis2]

fig, ax = plt.subplots()

ax.plot(x_axis1, y_axis1, 'ro', markersize=1)
ax.plot(x_axis2, y_axis2, 'go', markersize=1)
ax.set_ylim([dday, dday+datetime.timedelta(days=1)])

ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) 
ax.xaxis.set_minor_locator(mdates.DayLocator())
ax.yaxis.set_major_locator(mdates.HourLocator())
ax.yaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))

fig.autofmt_xdate()
plt.show()

enter image description here