TypeError: Datetime на оси x с помощью анимации matplotlib - PullRequest
0 голосов
/ 09 июня 2018

Я занимался этим полтора дня, и, наверное, пришло время позвать на помощь.Следующий код выдает ошибку:

TypeError: float() аргумент должен быть строкой или числом, а не 'datetime.datetime'

Я пытаюсь поставить datetime переменная, сгенерированная в функции frames1, по оси x через функцию анимации.

Код:

import random
import time
from matplotlib import pyplot as plt
from matplotlib import animation
import datetime

# Plot parameters
fig, ax = plt.subplots()
line, = ax.plot([], [], 'k-', label = 'ABNA: Price', color = 'blue')
legend = ax.legend(loc='upper right',frameon=False)
plt.setp(legend.get_texts(), color='grey')
ax.margins(0.05)
ax.grid(True, which='both', color = 'grey')

# Creating data variables
x = []
y = []
x.append(1)
y.append(1)

def init():
    line.set_data(x[:1],y[:1])
    return line,

def animate(args):
    # Args are the incoming value that are animated    
    animate.counter += 1
    i = animate.counter
    win = 60
    imin = min(max(0, i - win), len(x) - win)

    x.append(args[0])
    y.append(args[1])

    xdata = x[imin:i]
    ydata = y[imin:i]

    line.set_data(xdata, ydata)
    line.set_color("red")

    plt.title('ABNA CALCULATIONS', color = 'grey')
    plt.ylabel("Price", color ='grey')
    plt.xlabel("Time", color = 'grey')

    ax.set_facecolor('black')
    ax.xaxis.label.set_color('grey')
    ax.tick_params(axis='x', colors='grey')
    ax.yaxis.label.set_color('grey')
    ax.tick_params(axis='y', colors='grey')

    ax.relim()
    ax.autoscale()

    return line, #line2
animate.counter = 0

def frames1():
    # Generating time variable
    x = 10
    target_time = datetime.datetime.now().strftime("%d %B %Y %H:%M:%000")
    # Extracting time
    FMT = "%d %B %Y %H:%M:%S"
    target_time = datetime.datetime.strptime(target_time, FMT)
    target_time = target_time.time().isoformat()    
    # Converting to time object
    target_time = datetime.datetime.strptime(target_time,'%H:%M:%S') 
    while True:
        # Add new time + 60 seconds
        target_time = target_time + datetime.timedelta(seconds=60)
        x = target_time
        y = random.randint(250,450)/10
        yield (x,y)  
        time.sleep(random.randint(2,5))

anim = animation.FuncAnimation(fig, animate,init_func=init,frames=frames1)

plt.show()

Я попробовал следующие решения:

Построение даты на оси x с помощью matplotlib Python

Изменение форматирования оси дата-время в matplotlib

Без положительного результата пока.

Большое спасибо заранее за внимание к этой проблеме.

1 Ответ

0 голосов
/ 09 июня 2018

Не уверен, почему вы сначала добавляете 1 к вашему массиву.Я предполагаю, что вы имеете в виду

# Creating data variables
x = []
y = []
x.append(datetime.datetime.now())
y.append(1)

Тогда внутри функции генератора есть много чего я не понимаю.Мне кажется, что вы можете пропустить большую часть преобразования вперед и назад и просто использовать now() как есть.

def frames1():
    # Generating time variable
    target_time = datetime.datetime.now()

    while True:
        # Add new time + 60 seconds
        target_time = target_time + datetime.timedelta(seconds=60)
        x = target_time
        y = random.randint(250,450)/10
        yield (x,y)  
        time.sleep(random.randint(2,5))

Однако вы можете отформатировать ось, чтобы показать время вместо чисел.Внутри функции init вы можете добавить

line.axes.xaxis.set_major_formatter(mdates.DateFormatter("%H:%M:%S"))

, куда вы импортировали matplotlib.dates как mdates.

Строка imin = min(max(0, i - win), len(x) - win) не имеет особого смысла, почемуне использовать max(0, i - win) в одиночку?

Таким образом, в итоге рабочая версия может выглядеть так:

import random
import time
from matplotlib import pyplot as plt
import matplotlib.dates as mdates
from matplotlib import animation
import datetime

# Plot parameters
fig, ax = plt.subplots()
line, = ax.plot([], [], 'k-', label = 'ABNA: Price', color = 'blue')
legend = ax.legend(loc='upper right',frameon=False)
plt.setp(legend.get_texts(), color='grey')
ax.margins(0.05)
ax.grid(True, which='both', color = 'grey')

# Creating data variables
x = [datetime.datetime.now()]
y = [1]

def init():
    line.set_data(x[:1],y[:1])
    line.axes.xaxis.set_major_formatter(mdates.DateFormatter("%H:%M:%S"))
    return line,

def animate(args):
    # Args are the incoming value that are animated    
    animate.counter += 1
    i = animate.counter
    win = 60
    imin = max(0, i - win)
    x.append(args[0])
    y.append(args[1])

    xdata = x[imin:i]
    ydata = y[imin:i]

    line.set_data(xdata, ydata)
    line.set_color("red")

    plt.title('ABNA CALCULATIONS', color = 'grey')
    plt.ylabel("Price", color ='grey')
    plt.xlabel("Time", color = 'grey')

    ax.set_facecolor('black')
    ax.xaxis.label.set_color('grey')
    ax.tick_params(axis='x', colors='grey')
    ax.yaxis.label.set_color('grey')
    ax.tick_params(axis='y', colors='grey')

    ax.relim()
    ax.autoscale()

    return line,

animate.counter = 0

def frames1():
    # Generating time variable
    target_time = datetime.datetime.now()
    while True:
        # Add new time + 60 seconds
        target_time = target_time + datetime.timedelta(seconds=60)
        x = target_time
        y = random.randint(250,450)/10
        yield (x,y)  
        time.sleep(random.randint(2,5))

anim = animation.FuncAnimation(fig, animate,init_func=init,frames=frames1)

plt.show()

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...