使用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")
这段代码产生这样一个情节:
正如你所看到的,只要粒子穿越一个侧面我得到这些“条纹',因为plot()
将连接两点,不管它们有多远。有没有办法来防止这种情况发生?
我还重新写你的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
到下一点的线未绘制,因此线条中断。
作为一个侧面说明,大多数这种模拟进行矢量化:
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作为练习读者;)
谢谢你的好答案,但不幸的是我不明白它是如何工作的! “xList.append(np.nan)'和'yList.append(np.nan)'做了什么? – 2014-12-04 14:52:15
请参阅编辑以回答。 – tacaswell 2014-12-04 18:40:21
我会想你可能必须手动完成(例如,将连续的散步片分开并单独绘制) - 绘图代码无法知道不连续点在哪里。 – Ajean 2014-12-03 22:56:14
您也可以在执行环绕代码的系列中引入'np.nan'。 – tacaswell 2014-12-04 04:42:13