如何在实时更新的Matplotlib窗口中添加右侧独立刻度的游戏时间数据集
如何在实时更新的Matplotlib窗口中添加右侧独立刻度的游戏时间数据集
嘿,我来帮你解决这个双Y轴实时更新的问题!你的需求很明确:把分数和游戏时间这两个刻度差异大的数据集放在同一个实时刷新的图表里,同时还要避免每次调用函数都弹出新窗口,对吧?
下面是修改后的完整helper.py代码,我会一步步给你解释关键调整:
import matplotlib.pyplot as plt from IPython import display # 开启交互模式,保留原逻辑 plt.ion() # 全局初始化一次图和坐标轴——核心是复用同一个图,避免每次创建新窗口 fig, ax1 = plt.subplots() ax2 = ax1.twinx() # 创建右侧独立Y轴,和左侧轴共享X轴 def new_plot(scores, mean_scores, times, mean_times): # 清除IPython输出,保持实时更新的流畅性,和原逻辑一致 display.clear_output(wait=True) # 清除两个坐标轴的旧内容,避免数据重叠 ax1.cla() ax2.cla() # -------------------------- 左侧Y轴:处理分数数据 -------------------------- ax1.set_title('Game Data: Scores & Times') ax1.set_xlabel('Number of games') ax1.set_ylabel('Score', color='tab:blue') # 给左侧轴设置蓝色主题 # 绘制单局分数和平均分数曲线 ax1.plot(scores, color='tab:blue', label='Score per Game') ax1.plot(mean_scores, color='tab:cyan', label='Mean Score') ax1.set_ylim(ymin=0) # 保留分数最低为0的设置 # 在曲线末尾添加数值标注,延续原有的交互细节 if scores: ax1.text(len(scores)-1, scores[-1], str(scores[-1]), color='tab:blue') if mean_scores: ax1.text(len(mean_scores)-1, mean_scores[-1], str(mean_scores[-1]), color='tab:cyan') # 左侧轴刻度设为蓝色,方便视觉区分 ax1.tick_params(axis='y', labelcolor='tab:blue') ax1.legend(loc='upper left') # 分数图例放在左上,避免遮挡 # -------------------------- 右侧Y轴:处理时间数据 -------------------------- ax2.set_ylabel('Game Time', color='tab:red') # 右侧轴设置红色主题 # 绘制单局时间和平均时间曲线 ax2.plot(times, color='tab:red', label='Time per Game') ax2.plot(mean_times, color='tab:orange', label='Mean Time') ax2.set_ylim(ymin=0) # 时间最低为0,符合实际场景 # 同样在曲线末尾添加数值标注 if times: ax2.text(len(times)-1, times[-1], str(times[-1]), color='tab:red') if mean_times: ax2.text(len(mean_times)-1, mean_times[-1], str(mean_times[-1]), color='tab:orange') # 右侧轴刻度设为红色,和左侧形成明确区分 ax2.tick_params(axis='y', labelcolor='tab:red') ax2.legend(loc='upper right') # 时间图例放在右上,避免重叠 # 自动调整布局,防止轴标签被截断 fig.tight_layout() # 显示更新后的图表,暂停0.1秒保持交互性,延续原逻辑 display.display(fig) plt.pause(0.1)
关键修改说明
- 解决新窗口弹出问题:在函数外全局初始化
fig和坐标轴对象,每次调用new_plot只是清除轴内容重新绘制,不会创建新的图窗口,完美解决弹窗问题。 - 双Y轴实现:用
twinx()创建的ax2和左侧ax1共享X轴,但Y轴完全独立,刻度范围互不影响,正好匹配你“右侧显示时间”的需求。 - 视觉优化:给左右轴设置不同的主题色,图例分开放置,让两个数据集的区分度更高,图表更易读。
- 保留原有体验:完全延续了你原有的实时刷新逻辑,确保交互流畅性和数值标注这些细节和之前一致。
最后,只要你的main_code.py里的plot_times、total_game_times等时间相关变量和分数变量的累积逻辑一致,就能正常运行啦!
备注:内容来源于stack exchange,提问作者Nadim Ghaznavi




