Python蒙特卡洛模拟骰子游戏:图表无数据及动态更新问题求助
问题分析与解决方案
核心问题
- 仅绘制单一点而非折线:原代码在每次模拟结束后只绘制
(max_num_rolls, balance)这个终点,plt.plot默认连接多个点成折线,但单个点无标记的话不会显示,导致图表空框架。 - 未跟踪每一步的余额变化:要生成折线图,需要记录每个模拟中每一次掷骰后的余额,而非仅最终值。
- 图例逻辑错误:循环内每次重置图例列表,且用总模拟次数而非当前模拟序号,导致图例无法正确对应每条折线。
- 缺少实时更新机制:要实现实时刷新图表,需要开启matplotlib的交互模式。
修改后的代码
# 双骰赌博游戏:掷10次骰子,掷出对子得4倍赔付,蒙特卡洛模拟100次 import matplotlib.pyplot as plt import random # 掷骰子函数 def roll_dice(): die_1 = random.randint(1,6) die_2 = random.randint(1,6) same_num = die_1 == die_2 if same_num: print(f"骰子点数相同:{die_1}") else: print(f"骰子点数不同:{die_1} 和 {die_2}") return same_num # 模拟参数 num_simulations = 100 max_num_rolls = 10 # 开启交互模式,支持实时更新 plt.ion() fig, ax = plt.subplots() ax.set_xlabel('掷骰次数') ax.set_ylabel('账户余额 ($)') ax.set_title('蒙特卡洛模拟:双骰赌博余额变化') ax.set_xlim(0, max_num_rolls) # 预设y轴范围,避免频繁缩放 ax.set_ylim(0, 100) # 循环执行模拟 for i in range(num_simulations): balance = 50 bet = 1.00 payout_factor = 4 num_wins = 0 # 记录每一步的余额 balance_history = [balance] for roll in range(max_num_rolls): if roll_dice(): balance += payout_factor * bet num_wins += 1 else: balance -= bet balance_history.append(balance) # 打印模拟结果 print(f"第{i+1}次模拟:{max_num_rolls}次掷骰中赢了{num_wins}次,最终余额:{balance:.2f}") # 绘制当前模拟的余额变化折线 line, = ax.plot(range(max_num_rolls + 1), balance_history, label=f'模拟{i+1}') # 更新图例 ax.legend(loc='upper right', bbox_to_anchor=(1.15, 1)) # 实时刷新图表 plt.pause(0.1) # 关闭交互模式,保持图表显示 plt.ioff() plt.show()
关键修改说明
- 开启交互模式:
plt.ion()让matplotlib支持实时更新,plt.pause(0.1)每次绘制后短暂暂停以刷新画面。 - 跟踪每步余额:新增
balance_history列表,记录每次掷骰前后的余额,确保折线有足够的点连接。 - 正确绘制折线:用
range(max_num_rolls + 1)作为x轴数据(对应0到max_num_rolls次掷骰的余额),每个模拟生成一条完整折线。 - 优化图例与坐标轴:提前设置坐标轴范围,避免图表频繁缩放;动态更新图例,确保每条折线对应正确的模拟序号。
内容的提问来源于stack exchange,提问作者kca062
相关产品推荐
相关产品推荐

