这可能是显而易见的,所以请提前抱歉这个不引人注目的问题。我想用matplotlib.pyplot动态更新时间序列。更确切地说,我想在while循环中绘制新生成的数据。
这是我到目前为止的尝试:
import numpy as np
import matplotlib.pyplot as plt; plt.ion()
import pandas as pd
import time
n = 100
x = np.NaN
y = np.NaN
df = pd.DataFrame(dict(time=x, value=y), index=np.arange(n)) # not neccessarily needed to have a pandas df here, but I like working with it.
# initialise plot and line
line, = plt.plot(df['time'], df['value'])
i=0
# simulate line drawing
while i <= len(df):
#generate random data point
newData = np.random.rand()
# extend the data frame by this data point and attach the current time as index
df.loc[i, "value"] = newData
df.loc[i, "time"] = pd.datetime.now()
# plot values against indices
line.set_data(df['time'][:i], df['value'][:i])
plt.draw()
plt.pause(0.001)
# add to iteration counter
i += 1
print(i)
返回TypeError: float() argument must be a string or a number, not 'datetime.datetime'
。但据我所知,matplotlib在x轴(?)上绘制日期时没有任何问题。
非常感谢。
答案 0 :(得分:2)
正如Andras Deak指出的那样,你应该明确告诉大熊猫你的time
列是日期时间。当您在代码末尾执行df.info()
时,您将看到df['time']
为float64。您可以使用df['time'] = pd.to_datetime(df['time'])
实现此目的。
我能够让你的代码运行,但我不得不添加几行代码。我在iPython(Jupyter)控制台中运行它,没有两行autoscale_view
和relim
,它没有正确更新绘图。剩下要做的是对x轴标签进行很好的格式化。
import numpy as np
import matplotlib.pyplot as plt; plt.ion()
import pandas as pd
import time
n = 100
x = np.NaN
y = np.NaN
df = pd.DataFrame(dict(time=x, value=y), index=np.arange(n)) # not neccessarily needed to have a pandas df here, but I like working with it.
df['time'] = pd.to_datetime(df['time']) #format 'time' as datetime object
# initialise plot and line
fig = plt.figure()
axes = fig.add_subplot(111)
line, = plt.plot(df['time'], df['value'])
i=0
# simulate line drawing
while i <= len(df):
#generate random data point
newData = np.random.rand()
# extend the data frame by this data point and attach the current time as index
df.loc[i, "value"] = newData
df.loc[i, "time"] = pd.datetime.now()
# plot values against indices, use autoscale_view and relim to readjust the axes
line.set_data(df['time'][:i], df['value'][:i])
axes.autoscale_view(True,True,True)
axes.relim()
plt.draw()
plt.pause(0.01)
# add to iteration counter
i += 1
print(i)