使用Python绘制2D随机游走的问题

时间:2014-12-03 22:24:13

标签: python python-3.x matplotlib

我试图用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")

此代码生成如下图: enter image description here

正如您所看到的,每当粒子穿过其中一侧时,我就会得到这些条纹&#39;在情节上,因为plot()将连接两个点,无论它们有多远。有没有办法防止这种情况发生?

1 个答案:

答案 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到下一点的线是没有绘制,因此你的行中断了。 output

作为旁注,大部分模拟都可以进行矢量化:

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作为读者的练习;)