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

如何实现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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:45:39