Python Matplotlib x轴不正确地标记timedelta64对象

时间:2017-02-14 02:30:45

标签: python pandas matplotlib

我正在尝试使用Matplotlib从Python中的Pandas数据框生成一个图。以下是数据框的摘要。

import pandas as pd
import datetime
import matplotlib.pyplot as plt

# Summarize data frame.
>>> df.shape
(40, 4)

>>> df.dtypes
ID                         object
relative_time     timedelta64[ns]
value                     float64
relative_value            float64
dtype: object

>>> df.head()
    ID     relative_time  value  relative_value
0  001 -1 days +18:08:04    4.5            -1.0
1  001 -1 days +18:18:03    4.5            -1.0
2  001 -1 days +18:28:03    4.5            -1.0
3  001 -1 days +18:38:04    4.5            -1.0
4  001 -1 days +18:48:03    4.5            -1.0

>>> df.tail()
     ID     relative_time  value  relative_value
35  001 -1 days +23:58:03    5.5             0.0
36  001          00:08:03    5.5             0.0
37  001          00:18:03    5.5             0.0
38  001          00:28:02    5.5             0.0
39  001          00:38:04    5.5             0.0

我正在尝试在x轴上绘制relative_time,在y轴上绘制relative_value。但是,下面的代码产生了意想不到的结果,我无法知道x轴的单位是什么。

# Plot the desired plot.
plt.plot(test['relative_time'], test['relative_value'], marker='.')

enter image description here

注意,上图中的x轴不以小时为单位(相对于时间0)。这样的情节看起来如下。

plt.plot(test['relative_time'] / np.timedelta64(1, 'h'), test['relative_value'], marker='.')

enter image description here

如何绘制x轴以便以与relative_time列相同的格式显示时间?例如,如果x轴每小时都有刻度标记,则它们将被标记为-1 days +18:00:00-1 days +19:00:00,...,00:00:0001:00:00

1 个答案:

答案 0 :(得分:1)

x轴的单位是纳秒,如输出

所示
>>> df.dtypes
ID                         object
relative_time     timedelta64[ns]  <----- [ns] == nanoseconds
value                     float64
relative_value            float64
dtype: object

看起来matplotlib只显示纳秒,因此您需要将这些纳秒格式化为字符串格式。遗憾的是,numpy.timedelta64数据类型的功能有限,我在numpy文档中找不到任何可以执行此操作的内容。

示例Formatted x-axis labels

来源: matplotlib intelligent axis labels for timedelta

import datetime
import numpy as np
import matplotlib.pyplot as plt
import matplotlib

fig = plt.figure()
ax = fig.add_subplot(111)

创建一个np.timedelta64[ns]值数组。如果您执行了df["relative_time"].values,就会得到这样的结果。

# create list of times
x = [np.timedelta64(k, "ns") for k in range(0,300*10**9,10**9)]

# create some random y-axis data
y = np.random.random(len(x))

ax.plot(x, y)

# Function that formats the axis labels
def timeTicks(x, pos):
    seconds = x / 10**9 # convert nanoseconds to seconds
    # create datetime object because its string representation is alright
    d = datetime.timedelta(seconds=seconds)
    return str(d)

formatter = matplotlib.ticker.FuncFormatter(timeTicks)
ax.xaxis.set_major_formatter(formatter)
plt.show()