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

问题描述:

我正在尝试使用Python创建2D随机游走。随机游走发生在一个正方形内,如果粒子穿过正方形的任何一边,粒子将出现在另一边 - 实际上,随机游走发生在环面上。使用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

正如你所看到的,只要粒子穿越一个侧面我得到这些“条纹',因为plot()将连接两点,不管它们有多远。有没有办法来防止这种情况发生?

+0

我会想你可能必须手动完成(例如,将连续的散步片分开并单独绘制) - 绘图代码无法知道不连续点在哪里。 – Ajean 2014-12-03 22:56:14

+2

您也可以在执行环绕代码的系列中引入'np.nan'。 – tacaswell 2014-12-04 04:42:13

我还重新写你的steping代码位,使其更容易(在我看来)阅读:

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(不是一个数字,这是浮动 规范的一部分)加入你的清单。当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) 

我离开使用wrap位置插入的NaN作为练习读者;)

+0

谢谢你的好答案,但不幸的是我不明白它是如何工作的! “xList.append(np.nan)'和'yList.append(np.nan)'做了什么? – 2014-12-04 14:52:15

+1

请参阅编辑以回答。 – tacaswell 2014-12-04 18:40:21