[Python] Python 3 - matplotlib - set_xdata/set_ydata not working

Discussão em 'Python' iniciado por Stack, Fevereiro 5, 2025.

  1. Stack

    Stack Membro Participativo

    I try to display sensor data using set_xdata/set_ydata instead of plot so it refreshes faster

    I found this tutorial

    Problem: nothing shows up

    Expected: I should see the plotted data (used to work with ax1.plot)

    import pprint
    import matplotlib.pyplot as plt
    import matplotlib.animation as animation
    import time
    from matplotlib.widgets import Button # Import Button

    fig,ax1 = plt.subplots(figsize=(10, 8))

    # Initialize the plot lines with some dummy data
    line1, = ax1.plot([0], [0], label="LEFT", color="gray")
    line2, = ax1.plot([0], [0], label="RIGHT", color="gray")
    line3, = ax1.plot([0], [0], label="LEFT smoothed", color="red")
    line4, = ax1.plot([0], [0], label="RIGHT smoothed", color="green")

    plt.title("Phil VL53L0X sensors", fontsize=20)

    # setting x-axis label and y-axis label
    plt.xlabel("time")
    plt.ylabel("distance")

    xarr = []
    yarr1 = []
    yarr2 = []
    yarr1_s = []
    yarr2_s = []
    count = 0

    WINDOW_SIZE = 10
    MIN_DISTANCE = 20

    # Create the button to clear data
    def clear_data(event):
    global xarr, yarr1, yarr2, count, yarr1_s, yarr2_s
    xarr.clear()
    yarr1.clear()
    yarr2.clear()
    yarr1_s.clear()
    yarr2_s.clear()
    count = 0
    ax1.clear()
    ax1.set_xlabel("Time")
    ax1.set_ylabel("Distance (mm)")
    ax1.legend()
    plt.draw()

    def animate(i):
    global count

    # faking data, this is usually read by a sensor returning values between 0 and 100
    distance1 = count
    distance2 = count

    distance1 = distance1 - MIN_DISTANCE
    if distance1 < 0:
    distance1 = 0
    distance2 = distance2 - MIN_DISTANCE
    if distance2 < 0:
    distance2 = 0

    count += 1

    # Append new data
    xarr.append(count)
    yarr1.append(distance1)
    yarr2.append(distance2)

    # Apply moving average
    smoothed_distance1 = moving_average(yarr1)
    smoothed_distance2 = moving_average(yarr2)

    yarr1_s.append(smoothed_distance1)
    yarr2_s.append(smoothed_distance2)

    # Limit size of arrays to avoid excessive memory usage
    if len(yarr1) > 100:
    yarr1.pop(0)
    yarr2.pop(0)
    yarr1_s.pop(0)
    yarr2_s.pop(0)
    xarr.pop(0)

    pprint.pprint(xarr)
    pprint.pprint(yarr1)

    # Update the X data (only once)
    line1.set_xdata(xarr)
    line2.set_xdata(xarr)
    line3.set_xdata(xarr)
    line4.set_xdata(xarr)

    # Update the plot (without clearing it)
    line1.set_ydata(yarr1)
    line2.set_ydata(yarr2)
    line3.set_ydata(yarr1_s)
    line4.set_ydata(yarr2_s)

    # Update the plot (this works)
    #ax1.plot(xarr, yarr1, label="LEFT", color="gray")
    #ax1.plot(xarr, yarr2, label="RIGHT", color="gray")
    #ax1.plot(xarr, yarr1_s, label="LEFT s", color="red")
    #ax1.plot(xarr, yarr2_s, label="RIGHT s", color="green")

    fig.canvas.draw()
    fig.canvas.flush_events()
    time.sleep(0.1)


    ani = animation.FuncAnimation(fig, animate, interval=1) # Increased interval for smoother updates

    # Add a button to clear data
    ax_button = plt.axes([0.8, 0.05, 0.1, 0.075])
    btn = Button(ax_button, "Clear Data")
    btn.on_clicked(clear_data)

    plt.show()


    I pprint the data as it animates, it is clearly there.

    What am I missing here?

    [​IMG]

    Continue reading...

Compartilhe esta Página