график обновления matplotlib в цикле while с датами по оси x

#python #matplotlib #plot #while-loop

#python #matplotlib #график #while-цикл #цикл while

Вопрос:

Это может быть очевидно, поэтому заранее извините за этот вопрос nooby. Я хочу динамически обновлять временные ряды с помощью matplotlib.pyplot. Точнее, я хочу отобразить вновь сгенерированные данные в цикле while.

Пока это моя попытка:

 import numpy as np
import matplotlib.pyplot as p< 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 (?).

Большое спасибо.

Комментарии:

1. Разве это не pandas.plot тот, который плавно строит даты? Во всяком случае, в документах matplotlib есть глава , посвященная построению графиков, связанных с датой. В этом примере используется ax.plot_date .

Ответ №1:

Как указал Андраш Дик, вы должны явно указать pandas, что ваш time столбец имеет значение datetime . Когда вы это сделаете 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 p< 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)
  

Комментарии:

1. Красивые. Спасибо!

2. Могу ли я попросить вас отредактировать ваш пример таким образом, чтобы ось x правильно отображала дату и время?

3. Я пытался, но у меня были проблемы. Каким-то образом обычный способ set_major_formatter использования matplotlib.dates не работает с форматом времени фрейма данных pandas, и когда я использую фрейм данных с плавающей запятой, это снова приводит к вашей ошибке с плавающей запятой. Возможно, я могу попробовать еще раз завтра, но если вы не можете разобраться в этом самостоятельно, было бы, вероятно, лучше создать новый вопрос, поскольку этот вопрос уже принят (хотя люди могут просто сослаться на «анимацию matplotlib»).).