1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Anuncie Aqui
    Anuncie aqui você Também: fdantas@4each.com.br

[Python] Plotting real-time graphs using Matplotlib does not allow plotting second graph

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

  1. Stack

    Stack Membro Participativo

    I am reading data from serial port and based on that, plotting graphs using matplotlib.

    The data from serial port is in format: ecg 9.89 4.5 123 . . end psd 2.1, 33.2 3.4, 92.10 . . end fft 2.1, 33.2 3.4, 92.10 . . end

    There are two different plots. One for ECG and another for FFT/PSD. For ECG, it plots data in real time as they come. But for FFT/PSD, it plots data at the end. The issue I am having is it plots ECG fine but shows fft/psd blank in the first reading. Now when I send second reading from serial port, it shows first fft/psd graph.

    Below is my code. I added some logs in plot_fft_psd. It prints Third!!!!!! in the first iteration. fft_data and psd_data is also fine. But does not plot graph, graph is black/empty.

    def plot_fft_psd(fft_data, psd_data):
    print("plotting fft and psd")
    fig2, (ax_fft, ax_psd) = plt.subplots(2, 1, figsize=(10, 6), num='Figure 2 - FFT & PSD')

    print("First!!!!!!")
    fft_x, fft_y = zip(*fft_data)
    ax_fft.plot(fft_x, fft_y, marker='o', color='blue')

    print("Second!!!!!!")
    psd_x, psd_y = zip(*psd_data)
    ax_psd.plot(psd_x, psd_y, marker='o', color='orange')

    plt.tight_layout()
    plt.show()
    plt.pause(0.01)
    print("Third!!!!!!")


    def plot_ecg(x_vals, y_vals, ax, line):
    line.set_xdata(x_vals)
    line.set_ydata(y_vals)

    ax.set_xlim(0, 180)
    ax.set_ylim(-150, 200)
    plt.draw()


    def serial_main():
    ser = serial.Serial(SERIAL_PORT, BAUDRATE, timeout=1)

    fig1, ecg_ax = plt.subplots(figsize=(12, 6), num='Figure 1 - ECG')

    ecg_x_vals = []
    ecg_y_vals = []
    line, = ecg_ax.plot([], [], color='green')

    count = 0
    fft_data = []
    psd_data = []
    received_fft = False
    received_psd = False

    current_mode = None
    buffer = []

    while True:
    line_data = ser.readline().decode('utf-8').strip()

    print(f"> {line_data}")

    if line_data in ("ecg", "fft", "psd"):
    current_mode = line_data
    buffer = []
    continue

    if line_data == "end":
    if current_mode == "fft":
    fft_data = buffer
    received_fft = True

    elif current_mode == "psd":
    psd_data = buffer
    received_psd = True

    current_mode = None
    buffer = []

    try:
    if current_mode == "ecg":
    value = float(line_data)
    ecg_x_vals.append(count * 0.01)
    ecg_y_vals.append(value)

    plot_ecg(ecg_x_vals, ecg_y_vals, ecg_ax, line)
    plt.pause(0.001)
    count += 1

    elif current_mode in ("fft", "psd"):
    x_str, y_str = line_data.split(",")
    x = float(x_str.strip())
    y = float(y_str.strip())
    buffer.append((x, y))

    except ValueError:
    print(f"Invalid data skipped: {line_data}")
    continue
    except Exception as e:
    print(f"Unexpected error: {e} for line: {line_data}")
    continue

    if received_fft and received_psd:
    print("received fft and psd")
    plot_fft_psd(fft_data, psd_data)
    received_fft = False
    received_psd = False

    plt.pause(0.001)

    Continue reading...

Compartilhe esta Página