Arduino Live Serial Plotting с MatplotlibAnimation становится медленным

Я делаю живой плоттер, чтобы показать аналоговые изменения от датчика Arduino. Arduino печатает значение для серийного номера с бодратом 9600. Код Python выглядит следующим образом:

import matplotlib.pyplot as plt import matplotlib.animation as animation import serial import time ser = serial.Serial("com3", 9600) ser.readline() optimal_frequency = 100 fig = plt.figure(figsize=(6, 6)) ax1 = fig.add_subplot(1, 1, 1) # the following arrays must be initialized outside the loop xar = [] yar = [] print(time.ctime()) def animate(i): global b, xar, yar # otherwise a for i in range(optimal_frequency): a = str(ser.readline(), 'utf-8') try: b = float(a) except ValueError: ser.readline() xar.append(str(time.time())) yar.append(b) ax1.clear() ax1.plot(xar, yar) ani = animation.FuncAnimation(fig, animate, interval=optimal_frequency) plt.show() 

Получите время отклика в графике, но когда я планирую более 20 минут, время реакции увеличивается примерно до 1 минуты. Т.е. для получения графика с новыми значениями требуется 1 мин. Я также пытался с PyQtGraph, но это задерживается с самого начала.

Помимо задержки на время более 20 минут, я получаю некоторые перерегулирования и недомогания в сюжете.

Любая помощь?

  • Что делает оператор == на языке Python?
  • Шифрование и расшифровка с использованием PyCrypto AES 256
  • Ошибка R_HOME с rpy2
  • Django 1.8+ расширяет модель User
  • Python Lambda в цикле
  • Python3 - reload () нельзя вызвать в объекте __import__?
  • случайный десятичный в python
  • Как исправить значение ValueError: прочитать исключение закрытого файла?
  • 2 Solutions collect form web for “Arduino Live Serial Plotting с MatplotlibAnimation становится медленным”

    как указано в комментариях, вы делаете две вещи неправильно:

    • вы продолжаете добавлять входящие данные в свои массивы, которые через некоторое время становятся огромными
    • вы очищаете свои оси и создаете новый ax.plot() на каждой итерации.

    вместо этого вы хотите:

    в функции инициализации, создайте пустой объект Line2D

     def init(): line, = ax.plot([], [], lw=2) return line, 

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

     def animate(i): (...) xar.append(str(time.time())) yar.append(b) line.set_data(xar, yar) return line, 

    Ознакомьтесь с некоторыми учебниками, подобными этому . На SO также много вопросов, которые уже отвечают на ваш вопрос. Например, этот ответ содержит все элементы, необходимые для работы вашего кода.

    Как отмечалось в комментариях, чтение из массивов естественно замедляется из-за их большого размера. При скорости передачи 9600 я получаю около 130 серийных отсчетов и временных меток в секунду в переменных xar и yar ; который через 20 минут получает размер 156000. Уменьшение скорости передачи до 2400 уменьшает длину переменных до 36000, и их можно легко перекомпоновать.

    Python - лучший язык программирования в мире.