我有一个格式为(HH:MM:SS.mmmmmm)的时间戳数组和另一个浮点数数组,每个数组对应于时间戳数组中的一个值。

我可以用Matplotlib在x轴上绘制时间,在y轴上绘制数字吗?

我尝试了,但不知为何它只接受浮点数数组。我怎样才能让它画出时间呢?我需要以任何方式修改格式吗?


更新:

这个答案在matplotlib 3.5版之后就过时了。plot函数现在直接处理datetime数据。参见https://matplotlib.org/3.5.1/api/_as_gen/matplotlib.pyplot.plot_date.html

不鼓励使用plot_date。这种方法存在于历史上 原因,并可能在将来弃用。 类似datetime的数据应该直接使用plot绘制。 如果您需要绘制纯数字数据为Matplotlib日期格式或 需要设置一个时区,调用ax.xaxis。Axis_date / ax.yaxis.axis_date 之前的情节。看到Axis.axis_date。


过时的答案:

首先必须将时间戳转换为Python datetime对象(使用datetime.strptime)。然后使用date2num将日期转换为matplotlib格式。

使用plot_date绘制日期和值:

import matplotlib.pyplot
import matplotlib.dates

from datetime import datetime

x_values = [datetime(2021, 11, 18, 12), datetime(2021, 11, 18, 14), datetime(2021, 11, 18, 16)]
y_values = [1.0, 3.0, 2.0]

dates = matplotlib.dates.date2num(x_values)
matplotlib.pyplot.plot_date(dates, y_values)


您还可以使用pyplot绘制时间戳、值对。绘制(从它们的字符串表示解析后)。(使用matplotlib版本1.2.0和1.3.1进行测试。)

例子:

import datetime
import random
import matplotlib.pyplot as plt

# make up some data
x = [datetime.datetime.now() + datetime.timedelta(hours=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.plot(x,y)
# beautify the x-labels
plt.gcf().autofmt_xdate()

plt.show()

生成的图片:


这是与散点图相同的图:

import datetime
import random
import matplotlib.pyplot as plt

# make up some data
x = [datetime.datetime.now() + datetime.timedelta(hours=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.scatter(x,y)
# beautify the x-labels
plt.gcf().autofmt_xdate()

plt.show()

生成类似于下面的图像:


7年后,这个代码帮助了我。 然而,我的时间仍然没有正确显示。

使用Matplotlib 2.0.0,我必须从Paul H. Matplotlib编辑x轴标记标签的日期格式中添加以下代码。

import matplotlib.dates as mdates
myFmt = mdates.DateFormatter('%d')
ax.xaxis.set_major_formatter(myFmt)

我将格式更改为(%H:%M),并正确显示时间。

这一切都要感谢社区。


我在使用matplotlib版本:2.0.2时遇到了问题。运行上面的示例,我得到了一组居中堆叠的气泡。

我通过添加另一行来“修复”这个问题:

plt.plot([],[])

整个代码片段变成:

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


# make up some data
x = [datetime.datetime.now() + datetime.timedelta(minutes=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.plot([],[])
plt.scatter(x,y)

# beautify the x-labels
plt.gcf().autofmt_xdate()
myFmt = mdates.DateFormatter('%H:%M')
plt.gca().xaxis.set_major_formatter(myFmt)

plt.show()
plt.close()

这就产生了一个气泡按需要分布的图像。


熊猫数据帧还没有被提到。我想展示这些是如何解决我的约会时间问题的。我的日期时间是2021-04-01 16:05:37毫秒。我拉linux/haproxy吞吐量从/proc,所以我可以真正格式化它,但我喜欢。这对于将数据输入实时图形动画非常有用。

下面是csv文件。(忽略每秒数据包列,我在另一个图中使用它)

head -2 ~/data
date,mbps,pps
2021-04-01 16:05:37,113,9342.00
...

通过使用print(dataframe.dtype),我可以看到数据是如何读取的:

(base) ➜  graphs ./throughput.py
date      object
mbps      int64
pps       float64
dtype:    object

Pandas将日期字符串拉入为“object”,这只是类型char。在脚本中使用这个as-is:

import matplotlib.pyplot as plt
import pandas as pd

dataframe = pd.read_csv("~/data")

dates = dataframe["date"]
mbps = dataframe["mbps"]

plt.plot(dates, mbps, label="mbps")
plt.title("throughput")
plt.xlabel("time")
plt.ylabel("mbps")
plt.legend()
plt.xticks(rotation=45)

plt.show()

Matplotlib呈现所有毫秒时间数据。我添加了plt.xticks(rotation=45)来倾斜日期,但这不是我想要的。我可以将日期“对象”转换为datetime64[ns]。matplotlib知道如何渲染。

dataframe["date"] = pd.to_datetime(dataframe["date"]) 

这次我的日期类型是datetime64[ns]

(base) ➜  graphs ./throughput.py
date    datetime64[ns]
mbps             int64
pps            float64
dtype:          object

相同的脚本,只差一行。

#!/usr/bin/env python
import matplotlib.pyplot as plt
import pandas as pd

dataframe = pd.read_csv("~/data")

# convert object to datetime64[ns]
dataframe["date"] = pd.to_datetime(dataframe["date"]) 

dates = dataframe["date"]
mbps = dataframe["mbps"]

plt.plot(dates, mbps, label="mbps")
plt.title("throughput")
plt.xlabel("time")
plt.ylabel("mbps")
plt.legend()
plt.xticks(rotation=45)

plt.show()

这对于您的用例可能不是理想的,但它可能会帮助其他人。