0

I am attempting to graph some heartrate data that is collected over the course of 4 minutes. The ideal graph will be an animation of the heart rate that moves in real time with the data (i.e., a 4 minute animated graph). The data looks like something this:

import pandas as pd
import random
import more_itertools as mit

data = pd.DataFrame({'time': mit.random_combination(range(708709, 987067), r=410), 
                   'HR': [random.randint(70,110) for x in range(410)]})

The original code I tried from this very helpful article (https://towardsdatascience.com/dynamic-replay-of-time-series-data-819e27212b4b) managed to make a dynamic time series graph that was unable to stretch across the needed 4 minutes. As you can see there are inconsistent lapses when the device collected HR data and thus the original solution was not ideal. (Original solution below). Ideally I would like to avoid imputing missing time values.

Thanks for your time!

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from collections import deque
%matplotlib qt5
plt.ion()

Heartrate = 'HR'
%matplotlib qt5

plt.ion()

visible = 40

dy1 = deque(np.zeros(visible), visible)
dx = deque(np.zeros(visible), visible)

#interval = np.linspace(0, data.shape[0], num=data.shape[0])
interval = data['time']
fig = plt.figure(figsize=(15,10))

ah1 = fig.add_subplot(111)
ah1.set_xlabel("Time [ms]", fontsize=14, labelpad=10)
ah1.set_ylabel("Heart Rate Last 5 Seconds", fontsize=14, labelpad=5)
l1, = ah1.plot(dx, dy1, color='rosybrown', label='HR')
ah1.legend(loc="upper right", fontsize=12, fancybox=True, framealpha=0.5)

start = 0

while start+visible <= data.shape[0]-1:

    # extend deques (both x and y axes)
    dy1.extend(data[Heartrate].iloc[start:start+visible])
    dx.extend(interval[start:start+visible])

    # update axes
    l1.set_ydata(dy1)  
    l1.set_xdata(dx)

    # get mean of deques
    mdy1 = np.mean(dy1)

    # set x- and y-limits based on their mean
    dist = 20
    ah1.set_ylim(-dist+min(data['HR']), max(data['HR'])+dist) # static y-axis
    #ah1.set_ylim(-35+mdy1, 35+mdy1) # dynamic y-axis
    ah1.set_xlim(interval[start], interval[start+visible])

    # control speed of moving time-series
    start += 1

    fig.canvas.draw()
    fig.canvas.flush_events()
KNichs
  • 13
  • 4
  • 1
    have you looked at the [animation](https://matplotlib.org/3.2.1/api/animation_api.html) tools included with matplotlib? they are generally much easier to deal with than interactive mode. – David May 16 '20 at 14:57
  • .. [animation examples in the Gallery](https://matplotlib.org/gallery/index.html#animation) – wwii May 16 '20 at 15:15
  • What is the `%matplotlib qt5` statement? – wwii May 16 '20 at 15:19
  • Curious how *we* can help without any data to work with. Please read [mre]. – wwii May 16 '20 at 15:21
  • @wwii I thought a concise example of data would suffice - my mistake. Please find more representative data included. – KNichs May 16 '20 at 16:02
  • @wwii `%matplotlib qt5` initializes interactive plotting (e.g., https://matplotlib.org/gallery/user_interfaces/embedding_in_qt5_sgskip.html) – KNichs May 16 '20 at 16:04
  • `As you can see there are inconsistent lapses` - what are you seeing? - I'm seeing a line plot scrolling right-to-left along with the x-axis tick labels. Looks fine but a bit jittery. – wwii May 16 '20 at 16:16
  • @wwii Apologies again for being unclear. What I mean is, in the original code I am adapting this from, the data was structured such that there was a row for every possible value of time. In this data there are obviously breaks from one millisecond value to the next. Consequently, the animated graph is much shorter than 4 minutes. I am just trying to make the animation run in "real time" i.e., be 4 minutes long. Sorry again for some confusion, Python isn't my forte – KNichs May 16 '20 at 17:14

0 Answers0