简体   繁体   中英

matplotlib update plot in while-loop with dates as x-axis

This might be obvious, so sorry in advance for this nooby question. I want to update a time series dynamically with matplotlib.pyplot. More precisely, I want to plot newly generated data in a while-loop.

This is my attempt so far:

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)

This returns TypeError: float() argument must be a string or a number, not 'datetime.datetime' . But as far as I can remeber, matplotlib doesn't have any problems with plotting dates on the x-axis (?).

Many thanks.

As Andras Deak pointed out, you should tell pandas explicitly that your time column is datetime. When you do df.info() at the end of your code, you will see that it takes df['time'] as float64. You can achieve this with df['time'] = pd.to_datetime(df['time']) .

I was able to make your code run, but I had to add a few lines of code. I was running it in a iPython (Jupyter) console and without the two lines autoscale_view and relim , it was not updating the plot correctly. What's left to do is a nice formatting of the x-axis labels.

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM