[Python] Matplotlib plot continuous time series of data

Discussão em 'Python' iniciado por Stack, Maio 12, 2025.

  1. Stack

    Stack Membro Participativo

    I'm trying to continuously plot data received via network using matplotlib.

    On the y-axis, I want to plot a particular entity, while the x-axis is the current time.

    The x-axis should cover a fixed period of time, ending with the current time.

    Here's my current test code, which simulates the data received via network with random numbers.

    import threading
    import random
    import time
    import signal
    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.dates as md

    class NPData():
    def __init__(self, size):
    self.data = np.zeros((size,2)) # size rows, 2 cols
    self.size = size
    self.head = 0
    def __len__(self):
    return self.data.__len__()
    def __str__(self):
    return str(self.data)
    def append(self, data):
    self.data[self.head] = data
    self.head = (self.head + 1) % self.size
    def get_x_range(self):
    return (self.data.min(axis=0)[0], self.data.max(axis=0)[0])

    class Producer(threading.Thread):
    def __init__(self):
    super().__init__()
    random.seed()
    self.running = True
    self.data = NPData(100)
    def get_data(self):
    return self.data.data
    def stop(self):
    self.running = False
    def run(self):
    while self.running:
    now_ms = md.date2num(int(time.time() * 1000)) # ms
    sample = np.array([now_ms, np.random.randint(0,999)])
    self.data.append(sample)
    time.sleep(0.1)

    prog_do_run = True

    def signal_handler(sig, frame):
    global prog_do_run
    prog_do_run = False

    def main():
    signal.signal(signal.SIGINT, signal_handler)
    p = Producer()
    p.start()

    fig, ax = plt.subplots()
    xfmt = md.DateFormatter('%H:%M:%S.%f')
    ax.xaxis.set_major_formatter(xfmt)
    #ax.plot(p.get_data())
    #ax.set_ylim(0,999)
    plt.show(block=False)

    while prog_do_run:
    x_range = p.data.get_x_range()
    ax.set_xlim(x_range)
    #ax.set_ylim(0,999)
    print(p.get_data())
    #ax.plot(p.get_data())
    plt.draw()
    plt.pause(0.05)

    p.stop()


    Notes:

    The Producer class is supposed to emulate data received via network.

    I've encountered two main issues:


    1. I'm struggling to find out what actually needs to be called inside an endless loop in order for matplotlib to continuously update a plot (efficiently). Is it draw(), plot(), pause() or a combination of those?


    2. I've been generating milliseconds timestamps and matplotlib seems to not like them at all. The official docs say to use date2num(), which does not work. If I just use int(time.time() * 1000) or round(time.time() * 1000), I get OverflowError: int too big to convert from the formatter.

    Continue reading...

Compartilhe esta Página