我试图用Python创建2D随机游走。随机游走是在一个正方形内发生的,如果粒子穿过正方形的任何一侧,则粒子将出现在另一侧 - 实际上,随机游走是在圆环上发生的。
这是我的代码的副本:
from random import randrange as rand
from math import cos, sin, radians
import matplotlib.pyplot as plt
N = 100 # Size of square as a multiple of the step size.
NSteps = 5000 # Number of steps in simulation.
xStart = 0 # x coordinate of starting location. Origin is at centre of square
yStart = 0 # y coordinate of starting location. Origin is at centre of square
s = 1 # Step number.
x = xStart # x coordinate of point.
y = yStart # y coordinate of point.
xList = [] # List of the x coordinates of all points visited.
yList = [] # List of the y coordinates of all points visited.
while s <= NSteps:
angle = radians(rand(361))
x += cos(angle)
if x > N/2:
x -= N
elif x < -N/2:
x += N
xList += [x]
y += sin(angle)
if y > N/2:
y -= N
elif y < -N/2:
y += N
yList += [y]
s += 1
plt.figure(figsize=(13,8))
frame = plt.gca()
plt.plot(xList,yList,c="b")
plt.xlim(-N/2,N/2)
plt.ylim(-N/2,N/2)
frame.axes.get_xaxis().set_visible(False)
frame.axes.get_yaxis().set_visible(False)
plt.savefig("randomWalk.png", bbox_inches="tight")
此代码生成如下图:
正如您所看到的,每当粒子穿过其中一侧时,我就会得到这些条纹&#39;在情节上,因为plot()
将连接两个点,无论它们有多远。有没有办法防止这种情况发生?
答案 0 :(得分:3)
我还重新编写了你的步进代码,以便更容易(在我看来)阅读:
from random import randrange as rand
from numpy import cos, sin, radians
import numpy as np
import matplotlib.pyplot as plt
N = 100 # Size of square as a multiple of the step size.
NSteps = 5000 # Number of steps in simulation.
xStart = 0 # x coordinate of starting location. Origin is at centre of square
yStart = 0 # y coordinate of starting location. Origin is at centre of square
s = 1 # Step number.
x = xStart # x coordinate of point.
y = yStart # y coordinate of point.
xList = [] # List of the x coordinates of all points visited.
yList = [] # List of the y coordinates of all points visited.
def wrap(v, N):
if v > N/2:
return v - N, True
elif v < -N/2:
return v + N, True
return v, False
for j in range(NSteps):
angle = radians(rand(361))
x, wrap_flag_x = wrap(x + cos(angle), N)
y, wrap_flag_y = wrap(y + sin(angle), N)
if wrap_flag_x or wrap_flag_y:
xList.append(np.nan)
yList.append(np.nan)
xList.append(x)
yList.append(y)
fig, ax = plt.subplots()
ax.plot(xList,yList,c="b")
ax.set_xlim(-N/2,N/2)
ax.set_ylim(-N/2,N/2)
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
他们放np.nan
(非数字,这是浮动的一部分
spec)进入你的清单。当mpl绘制线条时(使用默认线条样式)连接所有点。 np.nan
的点无法绘制到屏幕上,因此不会绘制从最后一点到np.nan
点的线,而np.nan
到下一点的线是没有绘制,因此你的行中断了。
作为旁注,大部分模拟都可以进行矢量化:
from numpy.random import randint
from numpy import cos, sin, radians, cumsum
import numpy as np
import matplotlib.pyplot as plt
N = 100 # Size of square as a multiple of the step size.
NSteps = 5000 # Number of steps in simulation.
x_start = 0 # x coordinate of starting location. Origin is at centre of square
y_start = 0 # y coordinate of starting location. Origin is at centre of square
# get all of the angles
angles = radians(randint(low=0, high=361, size=NSteps))
# get (unwrapped) positions
x = cumsum(cos(angles)) + x_start
y = cumsum(sin(angles)) + y_start
# find where the position crosses the boundary
x_wraps = np.where(np.diff((x + N/2) // N))[0]
y_wraps = np.where(np.diff((y + N/2) // N))[0]
# do the wrapping
x = x - N * ((x + N/2)//N)
y = y - N * ((y + N/2)//N)
我使用包裹位置来插入nans作为读者的练习;)