【问题标题】:Python: DateTime-Objects can be plotted in matplotlib, but only sometimes?Python:DateTime-Objects 可以在 matplotlib 中绘制,但只是有时?
【发布时间】:2020-08-25 11:55:37
【问题描述】:

所以,我制作了一个如下所示的 DataFrame:

DF 按日期时间对象按时间顺序排列。这些日期时间是通过将包含时间戳的列“attributes.timestamp”转换为字符串生成的:

df["DateTime"] = df["attributes.timestamp"].apply(lambda x: datetime.strptime(x, '%Y-%m-%dT%H:%M:%SZ'))

相应的 y 值是一个计数器,用于对相应分钟内的对象进行计数。 当我尝试在 matplotlib 中绘制这个 DF 时,它确实有效。它将日期时间对象作为 x 值并绘制该分钟的计数,如下所示:

当然,必须在 x 轴上显示完整的 DateTime 对象看起来很愚蠢。它按此顺序显示月、日和小时(在示例中是 3 月 2 日下午 2 点到 20 点)。我希望它只显示小时(或至少只显示时间,而不是随之而来的整个日期)。所以我尝试向 DF 添加一个新列(称为“时间”)。该列将使用以下代码从 DateTime 列中提取时间:

df["Time"] = df["DateTime"].time()

但是,这不起作用,因为它给了我属性错误“'Series' object has no attribute 'time'”。相反,我尝试了其他方法。当我生成 DateTime 对象并向其中添加“.time()”时,我只是重复了之前使用的整个代码。

df["Time"] = df["attributes.timestamp"].apply(lambda x: datetime.strptime(x, '%Y-%m-%dT%H:%M:%SZ').time())

我不知道为什么,但现在它工作得很好。我能够从我的 Datetime 对象中添加时间:

我的下一个想法是使用 x 轴上的“时间”列而不是整个日期时间进行绘图。来自计数器的 y 值保持不变。但由于某种原因,这不起作用。当我尝试这样绘制它时,它给了我以下错误: TypeError: float() argument must be a string or a number, not 'datetime.time' 奇怪的是,在使用整个 DateTime 对象进行绘图时没有问题。我不知道,为什么提取的时间会成为问题,因为它也是按时间顺序排列的值。

我的问题是:为什么我的方法不起作用?并且:有什么办法可以解决这个问题吗?

【问题讨论】:

  • df["Time"] = df["DateTime"].dt.time
  • 确实也提取了时间。在 x 轴上绘制它时,它仍然给我同样的错误:TypeError: float() argument must be a string or a number, not 'datetime.time'
  • 该 api 不是为处理 datetime.time 而构建的

标签: python pandas dataframe datetime matplotlib


【解决方案1】:

Matplotlib 支持绘制 pandas DatetimeIndex 以及 numpy datetime64 对象,但不支持 datetime.time 的序列。此外,df["Time"] = df["DateTime"].time() 不起作用,因为您将 .time() 方法应用于 Series 本身,而不是应用于其中的 Series 元素,这些元素是确实定义了 .time() 方法的 pandas.Timestamp 对象。

要回答您的主要问题,您只希望 x 轴不显示冗余信息,是吗?不要只为 itme 创建一个新列,正确的方法是使用 matplotlib.dates.DateFormatter 格式化 matplotlib x 轴。

这是一个最小的例子:

import matplotlib.pyplot as plt
import pandas as pd

# Example DatetimeIndex and data
x = pd.date_range(start='2020-05-10', end='2020-05-11', freq='1h')
y = list(range(len(x)))

fig, ax = plt.subplots()
plt.plot(x, y)

# The following specifies the format for dates
import matplotlib.dates as mdates
date_fmt = mdates.DateFormatter('%I: %M%p')
ax.xaxis.set_major_formatter(date_fmt)

# autofmt_xdate helps with auto-rotating dates so they do not overlap
fig.autofmt_xdate()
plt.show()

至于如何知道将什么字符串传递给DateFormatter,请参考https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior了解strftime的格式。

Matplotlib 有一个专门用于修复常见日期烦恼的页面,您可能会发现它很有用:https://matplotlib.org/3.1.1/gallery/recipes/common_date_problems.html

【讨论】:

  • 谢谢伙计,你真的帮了我大忙!如果可以的话,会给你竖起大拇指。但它不会让我:P
猜你喜欢
  • 1970-01-01
  • 2013-09-18
  • 1970-01-01
  • 2020-10-11
  • 2012-05-14
  • 2013-09-15
  • 2011-01-29
  • 2010-10-05
相关资源
最近更新 更多