Python掷骰子动态模拟程序出现KeyError报错求助
掷骰子模拟程序KeyError报错排查与解决
错误核心原因
- X轴取值与骰子结果不匹配:两个骰子的和范围是2-12,但原代码传入
sns.barplot的faces是[1,2,3,4,5,6],导致seaborn尝试按1-6分组统计时,找不到对应掷骰结果的键,触发KeyError。 - 频率统计逻辑错误:
update函数中把die_rolls赋值为单次掷骰结果的列表,而非每个可能结果的出现频率,不符合sns.barplot对参数的要求。 - 标题与Y轴计算逻辑错误:标题用
sum(die_rolls)计算的是所有掷骰结果的和(而非总掷骰次数),Y轴上限用max(die_rolls)取的是单次掷骰结果的最大值(而非频率最大值),完全偏离需求。
修复后的代码
# RollDieDynamic.py """Dynamically graphing frequencies of die rolls.""" from matplotlib import animation import matplotlib.pyplot as plt import random import seaborn as sns import sys def update(frame_number, rolls_per_frame, faces, total_counts): """Configures bar plot contents for each animation frame.""" # 模拟当前帧的掷骰并累计次数 for _ in range(rolls_per_frame): roll_sum = random.randint(1, 6) + random.randint(1, 6) total_counts[roll_sum] += 1 # 提取当前所有结果的频率 frequencies = [total_counts[face] for face in faces] total_rolls = sum(frequencies) # 重新绘制图表 plt.cla() axes = sns.barplot(x=faces, y=frequencies, palette='bright') axes.set_title(f'Die Frequencies for {total_rolls:,} Rolls') axes.set(xlabel='Sum of Two Dice', ylabel='Frequency') # Y轴上限设为当前最大频率的1.1倍,保证文字不超出 axes.set_ylim(top=max(frequencies) * 1.10 if frequencies else 1) # 在每个柱子上显示频率和百分比 for bar, freq in zip(axes.patches, frequencies): if freq == 0: continue # 跳过无数据的柱子 text_x = bar.get_x() + bar.get_width() / 2.0 text_y = bar.get_height() percentage = freq / total_rolls * 100 if total_rolls > 0 else 0 text = f'{freq:,}\n{percentage:.1f}%' axes.text(text_x, text_y, text, ha='center', va='bottom') # 读取命令行参数:总帧数、每帧掷骰次数 number_of_frames = int(sys.argv[1]) rolls_per_frame = int(sys.argv[2]) sns.set_style('whitegrid') figure = plt.figure('Rolling Two Six-Sided Dice') # 两个骰子的和范围是2到12 faces = list(range(2, 13)) # 初始化每个结果的计数为0 total_counts = {face: 0 for face in faces} # 配置动画 die_animation = animation.FuncAnimation( figure, update, repeat=False, frames=number_of_frames, interval=33, fargs=(rolls_per_frame, faces, total_counts)) plt.show()
关键修复说明
- 修正X轴取值:将
faces改为range(2,13),完全匹配两个骰子的所有可能和。 - 累计频率统计:用字典
total_counts持续累计所有帧的掷骰结果,避免每次重新生成数据,符合动态统计的需求。 - 修正图表计算逻辑:总次数取所有频率的和,Y轴上限基于频率最大值计算,确保图表展示的是真实的频率分布。
- 优化文本显示:跳过频率为0的柱子,避免无效文本干扰,提升图表可读性。
内容的提问来源于stack exchange,提问作者sqlearner
相关产品推荐
相关产品推荐

