在动画中实现方程式的问题
Problem implementing an equation into an animation
我正在使用以下代码来模拟一组粒子的运动,其中参数 p
确定给定粒子移动与否的概率,并生成动画图:
# Comparação entre random walk e difusão em 1d
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib.patches as mpatches
import random
M = 100 # Número de walkers
L = 50 # Tamanho da malha
# A cada intervalo de tempo, mover o walker e propagar a difusão
p = 0.22 # Probabilidade de andar, difusividade em μm²/s
pinv = 1.0-p
nsteps = 2001 # Número de intervalos de tempo
# Iniciando os walkers
x = np.zeros(M) # Posição inicial dos walkers nos eixos x, y e z
Z = [(0,0,0) for i in range (M)]
edgesrw = np.array(range(-L,L+1))-0.5
xc = 0.5*(edgesrw[:-1]+edgesrw[1:])
#%%
def animate(it):
global x
x = get_data(Z, M)
# Trajetória dos walkers nos eixos x, y e z
if (np.mod(it,noutput)==0):
A = np.float64(Z)
plot._offsets3d = (A[:,0], A[:,1], A[:,2])
ax.set_title('Tempo = {}, p = {}'.format(it, str(round(p, 4))))
return plot
def get_data(Z, M):
# Atualizar a posição de todos os walkers
for iw in range(M):
rndx = random.random()
dx = -1*(rndx<p)+1*(rndx>pinv)
rndy = random.random()
dy = -1*(rndy<p)+1*(rndy>pinv)
rndz = random.random()
dz = -1*(rndz<p)+1*(rndz>pinv)
x, y, z = Z[iw]
Z[iw] = x+dx, y+dy, z+dz
return Z
plt.ion()
noutput = 5
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
fig.set_size_inches(6, 6)
ax.set_xlim((-50, 50))
ax.set_ylim((-50, 50))
ax.set_zlim((-50, 50))
ax.set_xlabel('Distância percorrida (x)')
ax.set_ylabel('Distância percorrida (y)')
ax.set_zlabel('Distância percorrida (z)')
subs1 = mpatches.Patch(color = 'blue', label = "Ca²\u207A")
ax.legend(handles = [subs1])
x = get_data(Z, M)
plot = ax.scatter (*zip(*Z), marker = 'o', s = 3, color = 'blue')
ani = animation.FuncAnimation(fig = fig, func = animate, frames = nsteps, interval = 50)
ani.save('Íons Ca2+, Dab constante.gif')
plt.show()
现在,p
是一个常数值。此代码给我以下结果:
我现在要做的是,不要总是使用 p
作为常数值,而是使用以下等式随时间更新它:
其中p0是之前的常数值,t是时间(由代码中的参数it
计算),alpha是另一个常数值。我知道当 t 等于 0 时这个等式不成立,在这种情况下我会认为 p 等于 p0。
所以,我定义了 p0
和 alpha
,以及将验证 it
是否等于零的条件,然后决定要做什么:
# Comparação entre random walk e difusão em 1d
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib.patches as mpatches
import random
M = 100 # Número de walkers
L = 50 # Tamanho da malha
# A cada intervalo de tempo, mover o walker e propagar a difusão
p = 0.22 # Probabilidade de andar, difusividade em μm²/s
p0 = 0.22
pinv = 1.0-p
nsteps = 2001 # Número de intervalos de tempo
alpha = 0.76 # Slope da curva experimental
# Iniciando os walkers
x = np.zeros(M) # Posição inicial dos walkers nos eixos x, y e z
Z = [(0,0,0) for i in range (M)]
edgesrw = np.array(range(-L,L+1))-0.5
xc = 0.5*(edgesrw[:-1]+edgesrw[1:])
#%%
def animate(it):
global x
x = get_data(Z, M)
# Trajetória dos walkers nos eixos x, y e z
if (np.mod(it,noutput)==0):
if it == 0:
p = p0
else:
p = p0*it**(alpha-1)
pinv = 1.0-p
A = np.float64(Z)
plot._offsets3d = (A[:,0], A[:,1], A[:,2])
ax.set_title('Tempo = {}, p = {}'.format(it, str(round(p, 4))))
return plot
def get_data(Z, M):
# Atualizar a posição de todos os walkers
for iw in range(M):
rndx = random.random()
dx = -1*(rndx<p)+1*(rndx>pinv)
rndy = random.random()
dy = -1*(rndy<p)+1*(rndy>pinv)
rndz = random.random()
dz = -1*(rndz<p)+1*(rndz>pinv)
x, y, z = Z[iw]
Z[iw] = x+dx, y+dy, z+dz
return Z
plt.ion()
noutput = 5
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
fig.set_size_inches(6, 6)
ax.set_xlim((-50, 50))
ax.set_ylim((-50, 50))
ax.set_zlim((-50, 50))
ax.set_xlabel('Distância percorrida (x)')
ax.set_ylabel('Distância percorrida (y)')
ax.set_zlabel('Distância percorrida (z)')
subs1 = mpatches.Patch(color = 'blue', label = "Ca²\u207A")
ax.legend(handles = [subs1])
x = get_data(Z, M)
plot = ax.scatter (*zip(*Z), marker = 'o', s = 3, color = 'blue')
ani = animation.FuncAnimation(fig = fig, func = animate, frames = nsteps, interval = 50)
ani.save('Íons Ca2+, alpha = {}.gif'.format(alpha))
plt.show()
但我很确定这个位置是错误的,因为我没有得到预期的结果(我预计粒子的整体扩散会减少,因为 p
应该会减少根据等式随时间推移)。
animate
函数中的变量 p
和 pinv
是 animate
的局部变量:这意味着您为 p
和 pinv
这个函数内部不会被全局“共享”。因此,每次从 animate
内部调用 get_data(Z, M)
时,您都会使用 p
和 pinv
.
的初始全局值计算新数据
这里我修改了get_data
以接收更新的值。另请注意,我已更改 animate
:
中的命令顺序
# Comparação entre random walk e difusão em 1d
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib.patches as mpatches
import random
M = 100 # Número de walkers
L = 50 # Tamanho da malha
# A cada intervalo de tempo, mover o walker e propagar a difusão
p = 0.22 # Probabilidade de andar, difusividade em μm²/s
p0 = 0.22
pinv = 1.0-p
nsteps = 2001 # Número de intervalos de tempo
alpha = 0.76 # Slope da curva experimental
# Iniciando os walkers
x = np.zeros(M) # Posição inicial dos walkers nos eixos x, y e z
Z = [(0,0,0) for i in range (M)]
edgesrw = np.array(range(-L,L+1))-0.5
xc = 0.5*(edgesrw[:-1]+edgesrw[1:])
#%%
def animate(it):
global x
# Trajetória dos walkers nos eixos x, y e z
if (np.mod(it,noutput)==0):
if it == 0:
p = p0
else:
p = p0*it**(alpha-1)
pinv = 1.0-p
x = get_data(Z, M, p, pinv)
A = np.float64(Z)
plot._offsets3d = (A[:,0], A[:,1], A[:,2])
ax.set_title('Tempo = {}, p = {}'.format(it, str(round(p, 4))))
def get_data(Z, M, p, pinv):
# Atualizar a posição de todos os walkers
for iw in range(M):
rndx = random.random()
dx = -1*(rndx<p)+1*(rndx>pinv)
rndy = random.random()
dy = -1*(rndy<p)+1*(rndy>pinv)
rndz = random.random()
dz = -1*(rndz<p)+1*(rndz>pinv)
x, y, z = Z[iw]
Z[iw] = x+dx, y+dy, z+dz
return Z
plt.ion()
noutput = 5
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
fig.set_size_inches(6, 6)
ax.set_xlim((-50, 50))
ax.set_ylim((-50, 50))
ax.set_zlim((-50, 50))
ax.set_xlabel('Distância percorrida (x)')
ax.set_ylabel('Distância percorrida (y)')
ax.set_zlabel('Distância percorrida (z)')
subs1 = mpatches.Patch(color = 'blue', label = "Ca²\u207A")
ax.legend(handles = [subs1])
x = get_data(Z, M, p, pinv)
plot = ax.scatter (*zip(*Z), marker = 'o', s = 3, color = 'blue')
ani = animation.FuncAnimation(fig = fig, func = animate, frames = nsteps, interval = 50)
# ani.save('Íons Ca2+, alpha = {}.gif'.format(alpha))
plt.show()
我正在使用以下代码来模拟一组粒子的运动,其中参数 p
确定给定粒子移动与否的概率,并生成动画图:
# Comparação entre random walk e difusão em 1d
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib.patches as mpatches
import random
M = 100 # Número de walkers
L = 50 # Tamanho da malha
# A cada intervalo de tempo, mover o walker e propagar a difusão
p = 0.22 # Probabilidade de andar, difusividade em μm²/s
pinv = 1.0-p
nsteps = 2001 # Número de intervalos de tempo
# Iniciando os walkers
x = np.zeros(M) # Posição inicial dos walkers nos eixos x, y e z
Z = [(0,0,0) for i in range (M)]
edgesrw = np.array(range(-L,L+1))-0.5
xc = 0.5*(edgesrw[:-1]+edgesrw[1:])
#%%
def animate(it):
global x
x = get_data(Z, M)
# Trajetória dos walkers nos eixos x, y e z
if (np.mod(it,noutput)==0):
A = np.float64(Z)
plot._offsets3d = (A[:,0], A[:,1], A[:,2])
ax.set_title('Tempo = {}, p = {}'.format(it, str(round(p, 4))))
return plot
def get_data(Z, M):
# Atualizar a posição de todos os walkers
for iw in range(M):
rndx = random.random()
dx = -1*(rndx<p)+1*(rndx>pinv)
rndy = random.random()
dy = -1*(rndy<p)+1*(rndy>pinv)
rndz = random.random()
dz = -1*(rndz<p)+1*(rndz>pinv)
x, y, z = Z[iw]
Z[iw] = x+dx, y+dy, z+dz
return Z
plt.ion()
noutput = 5
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
fig.set_size_inches(6, 6)
ax.set_xlim((-50, 50))
ax.set_ylim((-50, 50))
ax.set_zlim((-50, 50))
ax.set_xlabel('Distância percorrida (x)')
ax.set_ylabel('Distância percorrida (y)')
ax.set_zlabel('Distância percorrida (z)')
subs1 = mpatches.Patch(color = 'blue', label = "Ca²\u207A")
ax.legend(handles = [subs1])
x = get_data(Z, M)
plot = ax.scatter (*zip(*Z), marker = 'o', s = 3, color = 'blue')
ani = animation.FuncAnimation(fig = fig, func = animate, frames = nsteps, interval = 50)
ani.save('Íons Ca2+, Dab constante.gif')
plt.show()
现在,p
是一个常数值。此代码给我以下结果:
我现在要做的是,不要总是使用 p
作为常数值,而是使用以下等式随时间更新它:
其中p0是之前的常数值,t是时间(由代码中的参数it
计算),alpha是另一个常数值。我知道当 t 等于 0 时这个等式不成立,在这种情况下我会认为 p 等于 p0。
所以,我定义了 p0
和 alpha
,以及将验证 it
是否等于零的条件,然后决定要做什么:
# Comparação entre random walk e difusão em 1d
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib.patches as mpatches
import random
M = 100 # Número de walkers
L = 50 # Tamanho da malha
# A cada intervalo de tempo, mover o walker e propagar a difusão
p = 0.22 # Probabilidade de andar, difusividade em μm²/s
p0 = 0.22
pinv = 1.0-p
nsteps = 2001 # Número de intervalos de tempo
alpha = 0.76 # Slope da curva experimental
# Iniciando os walkers
x = np.zeros(M) # Posição inicial dos walkers nos eixos x, y e z
Z = [(0,0,0) for i in range (M)]
edgesrw = np.array(range(-L,L+1))-0.5
xc = 0.5*(edgesrw[:-1]+edgesrw[1:])
#%%
def animate(it):
global x
x = get_data(Z, M)
# Trajetória dos walkers nos eixos x, y e z
if (np.mod(it,noutput)==0):
if it == 0:
p = p0
else:
p = p0*it**(alpha-1)
pinv = 1.0-p
A = np.float64(Z)
plot._offsets3d = (A[:,0], A[:,1], A[:,2])
ax.set_title('Tempo = {}, p = {}'.format(it, str(round(p, 4))))
return plot
def get_data(Z, M):
# Atualizar a posição de todos os walkers
for iw in range(M):
rndx = random.random()
dx = -1*(rndx<p)+1*(rndx>pinv)
rndy = random.random()
dy = -1*(rndy<p)+1*(rndy>pinv)
rndz = random.random()
dz = -1*(rndz<p)+1*(rndz>pinv)
x, y, z = Z[iw]
Z[iw] = x+dx, y+dy, z+dz
return Z
plt.ion()
noutput = 5
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
fig.set_size_inches(6, 6)
ax.set_xlim((-50, 50))
ax.set_ylim((-50, 50))
ax.set_zlim((-50, 50))
ax.set_xlabel('Distância percorrida (x)')
ax.set_ylabel('Distância percorrida (y)')
ax.set_zlabel('Distância percorrida (z)')
subs1 = mpatches.Patch(color = 'blue', label = "Ca²\u207A")
ax.legend(handles = [subs1])
x = get_data(Z, M)
plot = ax.scatter (*zip(*Z), marker = 'o', s = 3, color = 'blue')
ani = animation.FuncAnimation(fig = fig, func = animate, frames = nsteps, interval = 50)
ani.save('Íons Ca2+, alpha = {}.gif'.format(alpha))
plt.show()
但我很确定这个位置是错误的,因为我没有得到预期的结果(我预计粒子的整体扩散会减少,因为 p
应该会减少根据等式随时间推移)。
animate
函数中的变量 p
和 pinv
是 animate
的局部变量:这意味着您为 p
和 pinv
这个函数内部不会被全局“共享”。因此,每次从 animate
内部调用 get_data(Z, M)
时,您都会使用 p
和 pinv
.
这里我修改了get_data
以接收更新的值。另请注意,我已更改 animate
:
# Comparação entre random walk e difusão em 1d
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib.patches as mpatches
import random
M = 100 # Número de walkers
L = 50 # Tamanho da malha
# A cada intervalo de tempo, mover o walker e propagar a difusão
p = 0.22 # Probabilidade de andar, difusividade em μm²/s
p0 = 0.22
pinv = 1.0-p
nsteps = 2001 # Número de intervalos de tempo
alpha = 0.76 # Slope da curva experimental
# Iniciando os walkers
x = np.zeros(M) # Posição inicial dos walkers nos eixos x, y e z
Z = [(0,0,0) for i in range (M)]
edgesrw = np.array(range(-L,L+1))-0.5
xc = 0.5*(edgesrw[:-1]+edgesrw[1:])
#%%
def animate(it):
global x
# Trajetória dos walkers nos eixos x, y e z
if (np.mod(it,noutput)==0):
if it == 0:
p = p0
else:
p = p0*it**(alpha-1)
pinv = 1.0-p
x = get_data(Z, M, p, pinv)
A = np.float64(Z)
plot._offsets3d = (A[:,0], A[:,1], A[:,2])
ax.set_title('Tempo = {}, p = {}'.format(it, str(round(p, 4))))
def get_data(Z, M, p, pinv):
# Atualizar a posição de todos os walkers
for iw in range(M):
rndx = random.random()
dx = -1*(rndx<p)+1*(rndx>pinv)
rndy = random.random()
dy = -1*(rndy<p)+1*(rndy>pinv)
rndz = random.random()
dz = -1*(rndz<p)+1*(rndz>pinv)
x, y, z = Z[iw]
Z[iw] = x+dx, y+dy, z+dz
return Z
plt.ion()
noutput = 5
fig = plt.figure()
ax = fig.add_subplot(111, projection = '3d')
fig.set_size_inches(6, 6)
ax.set_xlim((-50, 50))
ax.set_ylim((-50, 50))
ax.set_zlim((-50, 50))
ax.set_xlabel('Distância percorrida (x)')
ax.set_ylabel('Distância percorrida (y)')
ax.set_zlabel('Distância percorrida (z)')
subs1 = mpatches.Patch(color = 'blue', label = "Ca²\u207A")
ax.legend(handles = [subs1])
x = get_data(Z, M, p, pinv)
plot = ax.scatter (*zip(*Z), marker = 'o', s = 3, color = 'blue')
ani = animation.FuncAnimation(fig = fig, func = animate, frames = nsteps, interval = 50)
# ani.save('Íons Ca2+, alpha = {}.gif'.format(alpha))
plt.show()