You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Matplotlib实现强化学习电池充电动态折线图绘制

解决强化学习电池充电模拟的动态可视化问题

原代码存在两个核心问题导致渲染异常:

  • 每次调用_render_frame都新建Matplotlib图形和Pygame窗口,造成图形对象堆积、渲染重叠
  • 帧率控制不合理,画面刷新过快无法看清细节

修正方案

把图形和窗口的初始化逻辑移到类的初始化方法中(仅执行一次),每次渲染时只更新数据而非重建整个图形:

第一步:在类的__init__中完成初始化

def __init__(self):
    # 你的其他初始化代码(比如total_timesteps、_p_max等)
    # ...
    
    # 初始化Pygame环境
    pygame.init()
    self.window_size = (800, 600)
    self.screen = pygame.display.set_mode(self.window_size)
    pygame.display.set_caption('电池充电模拟可视化')
    self.clock = pygame.time.Clock()
    
    # 初始化Matplotlib图形(仅执行一次)
    self.fig, self.axes = plt.subplots(2, 1, figsize=(8, 6))
    
    # 配置功率输出子图
    self.ax_power = self.axes[0]
    self.ax_power.set_title('Power output')
    self.ax_power.set_xlabel('Time step')
    self.ax_power.set_ylabel('Power (kW)')
    self.ax_power.set_xlim(0, self.total_timesteps)
    self.ax_power.set_xticks(np.arange(0, self.total_timesteps, 2), minor=True)
    self.ax_power.set_ylim(0, self._p_max)
    self.ax_power.grid(True)
    self.power_plot = None  # 存储功率图对象
    
    # 配置SoE子图
    self.ax_soe = self.axes[1]
    self.ax_soe.set_title('State of Energy')
    self.ax_soe.set_xlabel('Time step')
    self.ax_soe.set_ylabel('SoE (kWh)')
    self.ax_soe.set_xlim(0, self.total_timesteps)
    self.ax_soe.set_xticks(np.arange(0, self.total_timesteps, 2), minor=True)
    self.ax_soe.set_ylim(0, self._target_soe)
    self.ax_soe.grid(True)
    self.soe_plot = None  # 存储SoE图对象
    
    # 初始化Matplotlib画布
    self.canvas = agg.FigureCanvasAgg(self.fig)

第二步:重写_render_frame方法

def _render_frame(self):
    # 处理Pygame窗口事件(防止假死)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            plt.close(self.fig)
            return False
    
    # 更新功率图:移除旧图→绘制新图
    if self.power_plot:
        for element in self.power_plot:
            element.remove()
    self.power_plot = self.ax_power.stem(self._current_time_step, self._currnt_power)
    
    # 更新SoE图:移除旧图→绘制新图
    if self.soe_plot:
        for element in self.soe_plot:
            element.remove()
    self.soe_plot = self.ax_soe.stem(self._current_time_step, self._agent_soe)
    
    # 刷新Matplotlib画布
    self.canvas.draw()
    renderer = self.canvas.get_renderer()
    
    # 将Matplotlib渲染结果转为Pygame表面并显示
    self.screen.fill((255, 255, 255))
    raw_data = renderer.tostring_rgb()
    size = self.canvas.get_width_height()
    surf = pygame.image.fromstring(raw_data, size, "RGB")
    self.screen.blit(surf, (0, 0))
    
    # 控制帧率:设为5帧/秒,可根据需要调整
    self.clock.tick(5)
    pygame.display.flip()
    
    return True

额外优化建议

  • 如果想展示连续变化的SOC趋势,把stem换成plot即可,折线图更适合表现连续更新的状态
  • 若不需要Pygame窗口,直接用Matplotlib的animation模块更轻量,比如FuncAnimation可以直接实现动态更新

内容的提问来源于stack exchange,提问作者nkp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 01:17:43