admin管理员组文章数量:1415697
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?
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?
Share Improve this question edited Feb 5 at 9:28 DavidG 25.4k14 gold badges100 silver badges86 bronze badges asked Feb 4 at 18:47 philphil 527 bronze badges1 Answer
Reset to default 0I think the main problem is that you need to make sure that the axis limits are set such that they include your data. Another issue is using:
fig.canvas.draw()
fig.canvas.flush_events()
time.sleep(0.1)
in your animate
function while also using the FuncAnimation
class - you should do one or the other (see the FuncAnimation
examples here).
An working example (simplified further from your example) would be:
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([], [], label="LEFT", color="C0")
line2, = ax1.plot([], [], label="RIGHT", color="C1")
plt.title("Phil VL53L0X sensors", fontsize=20)
# setting x-axis label and y-axis label
plt.xlabel("time")
plt.ylabel("distance")
xarr = []
yarr1 = []
yarr2 = []
count = 0
WINDOW_SIZE = 10
MIN_DISTANCE = -10
# set initial x and y bounds of the plot
INI_X_BOUNDS = [-10, 10]
INI_Y_BOUNDS = [0, 10]
ax1.set_xlim(INI_X_BOUNDS)
ax1.set_ylim(INI_Y_BOUNDS)
# Create the button to clear data
def clear_data(event):
global xarr, yarr1, yarr2, count
xarr.clear()
yarr1.clear()
yarr2.clear()
count = 0
ax1.set_xlim(INI_X_BOUNDS)
ax1.set_ylim(INI_Y_BOUNDS)
def animate(i):
global count
# faking data, this is usually read by a sensor returning values between 0 and 100
distance1 = count
distance2 = count / 2
distance1 = distance1 - MIN_DISTANCE
if distance1 < 0:
distance1 = 0
distance2 = distance2 - MIN_DISTANCE
if distance2 < 0:
distance2 = 0
# Append new data
xarr.append(count)
yarr1.append(distance1)
yarr2.append(distance2)
# Limit size of arrays to avoid excessive memory usage
if len(yarr1) > 100:
yarr1.pop(0)
yarr2.pop(0)
xarr.pop(0)
# Update the X data (only once)
line1.set_data(xarr, yarr1)
line2.set_data(xarr, yarr2)
# update the upper limit on the x-y axis ranges
# play around with this as you see fit
xlims = ax1.get_xlim()
ylims = ax1.get_ylim()
if xarr[-1] > xlims[-1]:
# double x limit
ax1.set_xbound(upper=xlims[-1] * 2)
if max(yarr1[-1], yarr2[-1]) > ylims[-1]:
# double y limit
ax1.set_ybound(upper=ylims[-1] * 2)
count += 1
# using frames=None will give infinite running
ani = animation.FuncAnimation(fig, animate, frames=None, interval=0.05)
# 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()
The main things this does is:
- set the initial axes x-y bounds
- update the upper x-y bounds if the data gets out the current range (play about with this as you require)
- remove the updating of the
fig.canvas
from within theanimate
function - to simplify things, it just uses
set_data
rather thanset_xdata
andset_ydata
separately.
本文标签: Python 3matplotlibsetxdatasetydata not workingStack Overflow
版权声明:本文标题:Python 3 - matplotlib - set_xdataset_ydata not working - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745238938a2649207.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论