python - Python:matplotlib livedata plot with buffer,更有效的方法
问题描述
我尝试编写脚本来绘制真实对象的实时数据,但我需要更有效的方法。我认为问题在于始终存储相同数量的样本来绘制,并同时收集和绘制它。我得到了一些代码,但我对它并不完全满意。
import time
from math import sin, cos
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
x_value = 0
x_list = []
y1_list = []
y2_list = []
props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
plt.rcParams['animation.html'] = 'jshtml'
fig, (ax1, ax2) = plt.subplots(2,1)
ax1.set_title("Power supply parameters")
ax1.set(ylabel='Voltage [V]')
ax2.set(xlabel='sample [n]', ylabel='Current [A]')
ax1.set_ylim(-1.5, 1.5)
ax2.set_ylim(-1.5,1.5)
ax1.grid(1)
ax2.grid(1)
box1 = ax1.text(.87, 0.95, str(0), transform=ax1.transAxes, fontsize=14,
verticalalignment='top', bbox=props)
box2 = ax2.text(0.87, 0.95, str(0), transform=ax2.transAxes, fontsize=14,
verticalalignment='top', bbox=props)
def annotate(last_y1, last_y2):
box1.set_text(str(round(last_y1,3)))
box2.set_text(str(round(last_y2,3)))
def data_gen(x_value):
x_value += 0.2
x_value = round(x_value,3)
total_1 = round(sin(x_value),3)
total_2 = round(cos(x_value),3)
time.sleep(0.1)
return (x_value,total_1,total_2)
def run(i):
global x_value ,x_list,y1_list, y2_list
x, y1, y2 = data_gen(x_value)
x_value += 0.2
if len(x_list) <=20:
x_list.append(x)
y1_list.append(y1)
y2_list.append(y2)
else:
x_list.append(x)
x_list.pop(0)
y1_list.append(y1)
y1_list.pop(0)
y2_list.append(y2)
y2_list.pop(0)
ax1.plot(x_list, y1_list, color='b')
ax2.plot(x_list, y2_list, color='r')
ax1.set_xlim(left=max(0, x_list[-1] - 50), right=x_list[-1] + 10)
ax2.set_xlim(left=max(0, x_list[-1] - 50), right=x_list[-1] + 10)
annotate(y1_list[-1], y2_list[-1])
ani = FuncAnimation(fig, run, interval=10)
plt.show()
我想知道如何memoryview()
为样本创建某种缓冲区,导致一遍又一遍地从列表中追加和弹出似乎太慢了,但我不知道如何使用它。
我会很高兴得到建议:)
[编辑] 下面是未来的固定版本:)
import time
from math import sin, cos
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib.lines import Line2D
x_value = 0
x_list = []
y1_list = []
y2_list = []
props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
plt.rcParams['animation.html'] = 'jshtml'
fig, (ax1, ax2) = plt.subplots(2,1)
ax1.set_title("Power supply parameters")
ax1.set(ylabel='Voltage [V]')
ax2.set(xlabel='sample [n]', ylabel='Current [A]')
ax1.set_ylim(-1.5, 1.5)
ax2.set_ylim(-1.5,1.5)
ax1.grid(1)
ax2.grid(1)
line1 = Line2D([0],[0.0],color='blue')
ax1.add_line(line1)
line2 = Line2D([0],[0.0],color='red')
ax2.add_line(line2)
box1 = ax1.text(.87, 0.95, str(0), transform=ax1.transAxes, fontsize=14,
verticalalignment='top', bbox=props)
box2 = ax2.text(0.87, 0.95, str(0), transform=ax2.transAxes, fontsize=14,
verticalalignment='top', bbox=props)
def annotate(last_y1, last_y2):
box1.set_text(str(round(last_y1,3)))
box2.set_text(str(round(last_y2,3)))
def data_gen(x_value):
x_value = round(x_value,3)
total_1 = round(sin(x_value),3)
total_2 = round(cos(x_value),3)
return (x_value,total_1,total_2)
def run(i):
global x_value ,x_list,y1_list, y2_list
x, y1, y2 = data_gen(x_value)
x_value += 0.2
if len(x_list) <=200:
x_list.append(x)
y1_list.append(y1)
y2_list.append(y2)
else:
x_list.append(x)
x_list.pop(0)
y1_list.append(y1)
y1_list.pop(0)
y2_list.append(y2)
y2_list.pop(0)
ax1.set_xlim(left=max(0, x_list[-1] - 20), right=x_list[-1] + 10)
ax2.set_xlim(left=max(0, x_list[-1] - 20), right=x_list[-1] + 10)
line1.set_data(x_list,y1_list)
line2.set_data(x_list,y2_list)
annotate(y1_list[-1], y2_list[-1])
ani = FuncAnimation(fig, run, interval=1)
plt.show()
解决方案
我将冒险并争辩说您存储数据的方式可能是代码中耗时最少的部分。
一个主要问题是您在每次迭代时都创建新行,而您应该创建 2 个 Line2D 对象并更新它们的数据(使用Line2D.set_data()
)。参见例如https://matplotlib.org/gallery/animation/unchained.html
推荐阅读
- javascript - React JS - 作为道具传递的调用函数
- javascript - 将 onClick 元素绑定到远程 API 的 React 组件
- c# - 无法读取对等记录
- email - CSS 背景图像“图像”未显示在 Outlook 中
- firebase - 如何从firebase获取特定时间戳后的数据
- gcc - Linux bootc.c 中的 GCC 内联汇编:汇编程序消息:错误:表达式后出现垃圾 'int 0x10h'
- java - 如何使用 Scanner.hasNextInt() 检查下一个 3 输入是否为 int 并仅在 java 中循环
- google-app-maker - 舍入绑定表达式 appmaker
- javascript - 稍微调整一下我的图像滑块(添加过渡动画)
- c# - 如何使用自适应卡片从 FormFlow 中保存和检索用户响应?