如何实现matplotlib.imshow()动画?2D伊辛模型空白图问题求解
问题根源
程序输出空白图像是以下几个问题共同导致的:
- 缺少必要的依赖导入:代码中使用的
numpy、matplotlib动画/绘图模块、scipy卷积工具都没有导入声明,运行时会直接抛出名称错误,无法执行绘图逻辑,弹出的图窗自然为空白。 - 迭代量级严重不足:原有代码仅执行100次自旋翻转,对于50×50共2500个自旋的晶格,仅不到4%的格点发生变化,视觉上几乎和初始状态无差异,很难观测到演化过程。
- 变量命名冲突:
metropolis函数的迭代步数参数和内部循环变量都命名为t,极易引发逻辑错误,代码可维护性极差。 - 冗余变量干扰:全局定义的
ims列表、传入metropolis但从未使用的初始能量参数e,会造成变量污染,提高调试难度。
修正方案
调整迭代逻辑(将1个蒙特卡洛步定义为翻转与总格点数等量的自旋,每完成1个蒙特卡洛步保存1帧),补全导入,修正变量命名,删除冗余内容,修正后的代码可直接运行:
import numpy as np import matplotlib.pyplot as plt from matplotlib import animation from scipy.ndimage import convolve, generate_binary_structure n = 50 def lattice(p): init_random = np.random.random((n,n)) d = np.zeros((n,n)) d[init_random>=p] = 1 d[init_random<p] = -1 return d def energy(lattice): kern = generate_binary_structure(2, 1) kern[1][1] = False e = -lattice * convolve(lattice, kern, mode='constant', cval=0) return e.sum() def metropolis(s, beta, n_steps): s = s.copy() grid_size = s.shape[0] frame_list = [] for _ in range(n_steps): # 1个蒙特卡洛步:翻转N = grid_size*grid_size次自旋 for _ in range(grid_size * grid_size): x = np.random.randint(0, grid_size) y = np.random.randint(0, grid_size) si = s[x,y] sf = -si # 计算自旋翻转的能量差 delta_e = 0 if x > 0: delta_e += 2 * si * s[x-1,y] if x < grid_size-1: delta_e += 2 * si * s[x+1,y] if y > 0: delta_e += 2 * si * s[x,y-1] if y < grid_size-1: delta_e += 2 * si * s[x,y+1] # Metropolis接受判定 if delta_e <= 0 or np.random.random() < np.exp(-beta * delta_e): s[x,y] = sf # 每完成1个蒙特卡洛步保存一帧 im = plt.imshow(s, animated=True, cmap='gray') frame_list.append([im]) return frame_list # 参数初始化 beta = 0.7 # 逆温度β=1/(kT),0.7对应温度低于2D Ising模型临界温度,会出现磁畴 total_mcs = 200 # 总模拟蒙特卡洛步数 init_spin_down_ratio = 0.25 # 初始化晶格 spin_lattice = lattice(init_spin_down_ratio) # 创建绘图画布 fig = plt.figure(figsize=(6,6)) plt.axis('off') # 隐藏坐标轴提升观测效果 # 生成动画帧 frames = metropolis(spin_lattice, beta, total_mcs) # 渲染并展示动画 ani = animation.ArtistAnimation(fig, frames, interval=50, blit=True, repeat_delay=1000) plt.show()
运行后可以清晰观测到低温下磁畴逐渐合并、最终形成统一磁化方向的演化过程。如果需要观测高温无序态,将beta调小到0.4以下即可。
内容的提问来源于stack exchange,提问作者Praveen Murali
相关产品推荐
相关产品推荐

