如何修复动态折线图中的错误和内存泄漏
我正在尝试创建一个可以动态变化的图表,能够显示最新的数值。可是,我遇到了一个错误信息,并且还出现了内存泄漏,我不知道是什么原因。你能告诉我你知道的原因吗?
错误信息:
[ERROR:flutter/flow/layers/transform_layer.cc(23)] TransformLayer is constructed with an invalid matrix.
内存泄漏
通过使用top命令确认了内存泄漏。flet的内存随着时间的推移而增加。
我的代码如下:
import flet as ft
import schedule
import time
import random
vx_val = [0]*1000 # 10ms*100*1000=1000s
vx_time = [round(i*0.1,1) for i in range(-1000+1, 0+1, 1)] # 10ms*100*1000=1000s
time_start = time.perf_counter()
elapsed_time = time.perf_counter() - time_start
class GuiViewer_graph(ft.UserControl):
ref_vx_linechartdata = ft.Ref[ft.LineChartData]()
def __init__(self):
super().__init__()
def build(self):
chart_vx = ft.LineChartData(
data_points=[],
stroke_width=5,
color=ft.colors.BLUE,
curved=False,
stroke_cap_round=True,
ref=self.ref_vx_linechartdata,
)
for i in range(0, len(vx_val)):
chart_vx.data_points.append(
ft.LineChartDataPoint(x=vx_time[i], y=vx_val[i])
)
vx_graph=ft.LineChart(
data_series=[
chart_vx,
],
border=ft.border.all(3, ft.colors.with_opacity(0.2, ft.colors.ON_SURFACE)),
horizontal_grid_lines=ft.ChartGridLines(
interval=20, color=ft.colors.with_opacity(0.2, ft.colors.ON_SURFACE), width=1
),
# vertical_grid_lines=ft.ChartGridLines(
# interval=10, color=ft.colors.with_opacity(0.2, ft.colors.ON_SURFACE), width=1
# ),
left_axis=ft.ChartAxis(
title=ft.Text('velocity[km/h]', weight=ft.FontWeight.BOLD),
labels_size=40,
labels_interval=20,
),
bottom_axis = ft.ChartAxis(
title=ft.Text('time[sec]', weight=ft.FontWeight.BOLD),
labels_size=40,
labels_interval=10,
),
min_y=0,
max_y=180,
interactive=True,
animate=True,
#expand=True,
)
table = ft.Container(
content=ft.Column(
scroll=True,
controls=[
# speed graph,
ft.Container(
content=ft.Column(
horizontal_alignment = ft.CrossAxisAlignment.CENTER,
controls=[
ft.Text('Speed', size=20, weight=ft.FontWeight.BOLD),
vx_graph,
],
),
margin=30,
expand=True,
),
],
#expand=True,
),
)
return table
def update(self):
self.control.update()
def gui(page: ft.Page):
page.title = "Viewer"
page.horizontal_alignment = ft.CrossAxisAlignment.CENTER
main_window = ft.Container(
content=GuiViewer_graph()
)
page.add(main_window)
page.update()
def gui_update(page):
global time_start, elapsed_time, vx_val, vx_time
# Elapsed Time calc
elapsed_time = time.perf_counter() - time_start
# graph data update
vx_current = random.uniform(0, 160)
vx_val[0:-1] = vx_val[1:]
vx_val[-1] = vx_current
vx_time[0:-1] = vx_time[1:]
vx_time[-1] = elapsed_time
for i in range(0,len(vx_val)):
# Memory leak point !!
GuiViewer_graph.ref_vx_linechartdata.current.data_points[i] = ft.LineChartDataPoint(x=vx_time[i], y=vx_val[i])
GuiViewer_graph.ref_vx_linechartdata.current.update()
# Sceduler
every_second=0.1
schedule.every(every_second).seconds.do(gui_update,page=page)
while True:
schedule.run_pending()
time.sleep(0.1)
if __name__ == '__main__':
ft.app(target=gui)
1 个回答
0
与其在循环中一个一个地更新数据点,不如一次性清空并更新整个数据列表。这样做可以更高效。记得要好好管理引用,以免造成内存泄漏。
def gui_update(page):
global time_start, elapsed_time, vx_val, vx_time
# Elapsed Time calc
elapsed_time = time.perf_counter() - time_start
# graph data update
vx_current = random.uniform(0, 160)
vx_val = vx_val[1:] + [vx_current]
vx_time = vx_time[1:] + [elapsed_time]
# Update chart data
chart_data = GuiViewer_graph.ref_vx_linechartdata.current
chart_data.data_points = [ft.LineChartDataPoint(x=x, y=y) for x, y in zip(vx_time, vx_val)]
chart_data.update()