在独立轴上绘制时间
- 2024-12-13 08:36:00
- admin 原创
- 132
问题描述:
我有一个格式为 (HH:MM:SS.mmmmmm) 的时间戳数组和另一个浮点数数组,每个数组对应时间戳数组中的一个值。
我可以使用 Matplotlib 在 x 轴上绘制时间并在 y 轴上绘制数字吗?
我尝试过,但不知何故它只接受浮点数组。我怎样才能让它绘制时间?我必须以某种方式修改格式吗?
解决方案 1:
更新:
自 matplotlib 3.5 版以来,此答案已过时。该plot
函数现在直接处理日期时间数据。请参阅https://matplotlib.org/3.5.1/api/_as_gen/matplotlib.pyplot.plot_date.html
不鼓励使用 plot_date。此方法因历史原因而存在,将来可能会被弃用。
类似日期时间的数据应该直接使用 plot 来绘制。
如果您需要将纯数字数据绘制为 Matplotlib 日期格式或需要设置时区,请在绘图前调用 ax.xaxis.axis_date / ax.yaxis.axis_date。请参阅 Axis.axis_date。
旧的、过时的答案:
您必须首先将时间戳转换为 Pythondatetime
对象(使用datetime.strptime
)。然后使用date2num
将日期转换为 matplotlib 格式。
使用以下方法绘制日期和值plot_date
:
import matplotlib.pyplot as plt
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)
plt.plot_date(dates, y_values)
解决方案 2:
您还可以使用pyplot.plot绘制时间戳、值对(从其字符串表示形式解析它们之后)。(使用 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()
产生类似这样的图像:
解决方案 3:
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),时间就正确显示了。
这一切都要感谢社区。
解决方案 4:
我在使用 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()
这样就会生成一幅气泡按所需分布的图像。
解决方案 5:
尚未提及 Pandas 数据框。我想展示它们如何解决我的日期时间问题。我有精确到毫秒的日期时间2021-04-01 16:05:37
。我从 /proc 提取 linux/haproxy 吞吐量,因此我可以按照自己喜欢的方式对其进行格式化。这对于将数据输入实时图形动画非常有用。
以下是 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 将日期字符串作为“对象”提取,该对象只是 char 类型。在脚本中按原样使用它:
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()
这可能并不适合您的使用情况,但可能会对其他人有所帮助。