Zbuduj w Pythonie wykres krzywej oddechowej w czasie rzeczywistym, korzystając z Aidlab SDK, filtrując dane i rysując go przy użyciu matplotlib.
Aidlab SDK udostępnia w Pythonie nowe możliwości, takie jak filtrowanie sygnałów czy dostęp do modułu wykrywania ćwiczeń. Dzięki nim możemy tworzyć bardziej rozbudowane projekty. Zobaczmy, jak filtrowanie danych przydaje się w projektach wykorzystujących oddech.
Wbudowany w Aidlab impedancyjny czujnik oddechu dostarcza wielu przydatnych danych, m.in. częstości oddechu i aktualnego poziomu wentylacji. Możesz na przykład stworzyć grę podobną do Birds, w której sterujesz ptakiem za pomocą oddechu.
W Aidlab SDK filtrowanie jest domyślnie włączone, dlatego do rozpoczęcia pomiaru oddechu wystarczy stosunkowo prosty kod:
import asyncio
from aidlab import AidlabManager, DataType, DeviceDelegate, DisconnectReason
class MainManager(DeviceDelegate):
async def run(self):
devices = await AidlabManager().scan()
if len(devices) > 0:
print("Connecting to:", devices[0].address)
await devices[0].connect(self)
while True:
await asyncio.sleep(1)
def did_connect(self, device):
print("Connected to:", device.address)
asyncio.create_task(device.collect([DataType.RESPIRATION], []))
def did_disconnect(self, device, reason: DisconnectReason):
print("Disconnected from:", device.address, reason)
def did_receive_respiration(self, device, timestamp: int, value: float):
print(value)
asyncio.run(MainManager().run())
Utwórz plik respiration-plotting.py, wklej do niego powyższy fragment i przygotuj następującą strukturę katalogów:
SleepDetector/
|-- respiration-plotting.py
Zainstaluj Aidlab Python SDK za pomocą pip:
python -m pip install aidlabsdk
W tym poradniku przedstawimy zebrane próbki na wykresie. Użyjemy do tego matplotlib, biblioteki Pythona do tworzenia wykresów. Matplotlib oferuje wiele narzędzi, dzięki którym szybko i łatwo narysujesz różne typy wykresów. Przydaje się zarówno do prezentowania wyników uzyskanych za pomocą Aidlaba, jak i do wizualizacji danych wejściowych. Ta druga możliwość ułatwia zrozumienie problemu, który chcemy rozwiązać, oraz działania naszych modeli i algorytmów.
Zainstaluj matplotlib za pomocą pip:
pip install matplotlib
Jedną z zalet matplotlib jest proste API do rysowania wykresów:
import matplotlib.pyplot as pyplot
pyplot.plot([1,2,3,4])
pyplot.ylabel('some numbers')
pyplot.show()
Najważniejsza funkcja, plot, przyjmuje tablicę próbek i przedstawia je na wykresie:
Rysowanie wykresu w czasie rzeczywistym
Dane z Aidlaba napływają strumieniowo, więc nasz wykres musi być na bieżąco odświeżany o nowe próbki. Pokażemy dwa sposoby rysowania wykresów w czasie rzeczywistym: z użyciem FuncAnimation i bez tej funkcji.
FuncAnimation
Korzystanie z FuncAnimation jest stosunkowo proste. W naszym przykładzie przekazujemy trzy parametry:
- obiekt
figure, w którym chcemy narysować wykres, - funkcję aktualizującą wykres,
- odstęp między odświeżeniami (w milisekundach).
Kod wygląda następująco:
figure = pyplot.figure()
axis1 = figure.add_subplot(1,1,1)
animation.FuncAnimation(figure, animate, interval=2)
pyplot.show()
Funkcję animate definiujemy tak:
def animate(self, i):
global y
axis1.clear()
axis1.plot(x, y)
Listy x i y zawierają odpowiednio pozycje próbek na osi oraz wartości sygnału oddechowego.
ion
Możemy też skorzystać ze starszego rozwiązania: metody ion z matplotlib.pyplot.
ion włącza tryb interaktywny, który pozwala dynamicznie aktualizować dane na wykresie:
def live_plotter(self):
if self.line == []:
# This is the call to matplotlib that allows dynamic plotting
pyplot.ion()
self.fig = pyplot.figure(figsize=(13, 6))
axis = self.fig.add_subplot(111)
# Create a variable for the line so we can update it later
self.line, = axis.plot(self.x, self.y, '', alpha=0.8)
pyplot.show()
# After the figure, axis, and line are created, we only need to update the
# y-data
self.line.set_ydata(self.y)
# Adjust limits if new data goes beyond bounds
pyplot.ylim([np.min(self.y) - np.std(self.y), np.max(self.y) + np.std(self.y)])
# This pauses the data so the figure/axis can catch up - the amount of pause
# can be altered above
self.fig.canvas.flush_events()
Utwórzmy funkcję, która będzie odświeżać wykres w stałych odstępach czasu:
def did_receive_respiration(self, device, timestamp, value):
self.sample_index += 1
chart_refresh_rate_in_milliseconds = 100
# shift left
self.y[:-1] = self.y[1:]
self.y[-1] = value
if self.current_time_in_milliseconds() - self.time > chart_refresh_rate_in_milliseconds:
self.time = self.current_time_in_milliseconds()
self.live_plotter()
def current_time_in_miliseconds(self):
global second_in_miliseconds
return int(round(time.time() * second_in_miliseconds))
Uruchomienie powyższego kodu rozpocznie wyszukiwanie urządzeń w pobliżu. Po nawiązaniu połączenia powinien pojawić się wykres podobny do tego:
Wznoszące i opadające fragmenty krzywej odpowiadają wdechom i wydechom.
Jeśli chcesz lepiej poznać matplotlib, zajrzyj do poradników na oficjalnej stronie matplotlib.







