关于 《python 从入门到实践》的 matplotlib 随机漫步小项目

使用 python 生成随机漫步数据,再使用 matplotlib 将数据呈现。

所谓随机漫步:

每次行走的路径都是完全随机的,就像蚂蚁在晕头转向的情况下,每次都沿随机方向前行路径。
在自然界,物理学,生物学,化学和经济领域,随机漫步都有很多实际用途。
例如:漂浮在水滴上的花粉因不断受到水分子的挤压而在水面上移动。水滴中的分子运动是随机的,因此花粉在水面上的运动路径犹如随机漫步。

现在我们来自己编写模仿现实世界中的情形:

创建 RandomWalk() 类

该类用于:

随机选择前进方向。它需要三个属性,其中一个是存储随机漫步次数的变量,其他两个是列表,分别存储随机漫步经过的每个点的 x 和 y 坐标。

random_walk.py

from random import choice

class RandomWalk():
    #一个生成随机漫步数据的类
    def __init__(self,num_points =5000):
        self.num_points = num_points
        
        #所有随机漫步都始于
        self.x_values = [0]
        self.y_values = [0]

为保证随机漫步可以做出随机决策,我们将所有的选择都存储在一个列表中,并在每次做决策时都使用 choice() 来做出使用哪种选择。
随机漫步包含的默认点数设置为 5000。既可以生成有趣的模式,同时又足够小。可确保快速模拟出随机漫步。

选择方向

下面我们继续在这个类中添加一个方法。
用于:

生成漫步时包含的点,并决定每次漫步的方向。

    def fill_walk(self):
        #计算漫步时包含的所有点
        #通过循环,不断漫步,知道列表到达指定的长度
        while len(self.x_values) < self.num_points:
            #决定前进方向以及沿着这个方向前进的距离
            x_direction = choice([1,-1])
            x_distance = choice([0,1,2,3,4])
            x_step = x_direction * x_distance
            
            y_direction = choice([1,-1])
            y_distance = choice([0,1,2,3,4])
            y_step = y_direction * y_distance
            
            #拒绝原地踏步
            if x_step == 0 and y_step == 0:
                continue
            #计算下一个点的x和y值
            next_x = self.x_values[-1] + x_step
            next_y = self.y_values[-1] + y_step
            self.x_values.append(next_x)
            self.y_values.append(next_y)

使用choice([1,-1]) 给 x_direction 选择一个值,结果要么是表示向右走的 1 ,要么是表示向左走的-1。接下来,choice([0,1,2,3,4]) 随机地选择一个 0~4 之间的整数,告诉 python 沿指定的方向走多远(x_distance) 通过包含0,我们不仅能够沿两个轴移动,还能够沿 y 轴移动。
.
将移动方向乘以距离,以确定沿x和y轴移动的距离。如果x_step为正,将向右移动,为负将向左移动,而为零意味着水平移动;如果y_step为正,就意味着向上移动,为负意味着向下移动,而为零意味着水平移动。如果x_step 和 y_step 都为零,则意味着原地踏步,我们拒绝这样的情况,接着执行下一次循环。

绘制随机漫步图

下面的代码将随机漫步的所有点都绘制起来。

rw_visual.py

import matplotlib.pyplot as plt
from random_walk import RandomWalk
rw = RandomWalk()
rw.fill_walk()
plt.scatter(rw.x_values,rw.y_values,s=15)
plt.show()

运行一下程序 查看效果:
在这里插入图片描述

报错说没有这个参数,我找了很久问题。
最后无奈,只能从 csdn查了一下,即便自己知道是哪的问题也没成功解决。。

看来还是功力尚浅啊!
这是因为 pychram 自动录入的 init方法 是缩写的。。。

有意思吗…

在看一下运行效果:
在这里插入图片描述

模拟多次随机漫步

现在每次启动程序运行的结果都不相同。

还真是随机漫步!不过要想只运行一次程序就有多次随机漫步的效果的话,我们可以加入 while 循环。

rw_visual.py

import matplotlib.pyplot as plt
from random_walk import RandomWalk

#在程序处于活动状态,就不断地模拟随机漫步
while True:
    rw = RandomWalk()
    rw.fill_walk()
    plt.scatter(rw.x_values,rw.y_values,s=15)
    plt.show()

    keep_ruuning = input("你要要继续运行随机漫步吗? (y/n):")
    if keep_ruuning == 'n':
         break

现在随机漫步终于可以在不关闭的情况下继续漫步了。
在这里插入图片描述

设置随机漫步的样式

现在为了可以让我们可通过视觉观察出随机漫步的路程,突出漫步的起点,终点和经过的路径。

给点着色

使用颜色映射指出漫步中各点颜色、删除每个点的黑色轮廓,使其颜色更明显。

传递参数 c,将其设置为列表,其中包含各点先后顺序。(因为各点是按照顺序绘制,所以参数c指定的列表只包含数字 1~5000):

rw_visual.py

import matplotlib.pyplot as plt
from random_walk import RandomWalk

#在程序处于活动状态,就不断地模拟随机漫步
while True:
    rw = RandomWalk()
    rw.fill_walk()

    point_numbers = list(range(rw.num_points))
    plt.scatter(rw.x_values,rw.y_values,c=point_numbers,cmap=plt.cm.Blues,
                edgecolors='none',s=15)
    plt.show()

    keep_ruuning = input("你要要继续运行随机漫步吗? (y/n):")
    if keep_ruuning == 'n':
         break

这里,我们使用 range 生成一个数字列表,其中包含的数字个数与漫步包含的点数相同。接下来,将这个列表存储在point_numbers 中,以便后面使用它来设置每个漫步点的颜色。

在这里插入图片描述

重新绘制起点和终点

除了上述给随机漫步各个点着色(便于指出先后顺序),还可以呈现随机漫步的起点和终点,编码如下:

    point_numbers = list(range(rw.num_points))
    plt.scatter(0,0,c='green',edgecolors='none',s=100)
    plt.scatter(rw.x_values[-1],rw.y_values[-1],c='red',
                edgecolors='none',s=100)
    plt.scatter(rw.x_values,rw.y_values,c=point_numbers,cmap=plt.cm.Blues,
                edgecolors='none',s=15)
    plt.show()
隐藏坐标轴
while True:
    rw = RandomWalk()
    rw.fill_walk()

    point_numbers = list(range(rw.num_points))
    plt.scatter(rw.x_values, rw.y_values, c=point_numbers, cmap=plt.cm.Blues,
                edgecolors='none', s=15)
    plt.scatter(0,0,c='green',edgecolors='none',s=100)
    plt.scatter(rw.x_values[-1],rw.y_values[-1],c='red',
                edgecolors='none',s=100)

	#plt.axes().get_xaxis().set_visible(False)
	#plt.axes().get_yaxis().set_visible(False)
    current_axes = plt.axes()
    current_axes.xaxis.set_visible(False)
    current_axes.yaxis.set_visible(False)

    plt.show()

    keep_ruuning = input("你要要继续运行随机漫步吗? (y/n):")
    if keep_ruuning == 'n':
         break
增加点数

增加点数,以提供更多的数据:

import matplotlib.pyplot as plt
from random_walk import RandomWalk

#在程序处于活动状态,就不断地模拟随机漫步
while True:
    rw = RandomWalk(50000)
    rw.fill_walk()

    point_numbers = list(range(rw.num_points))
    plt.scatter(rw.x_values, rw.y_values, c=point_numbers, cmap=plt.cm.Blues,
                edgecolors='none', s=1)
    plt.scatter(0,0,c='green',edgecolors='none',s=100)
    plt.scatter(rw.x_values[-1],rw.y_values[-1],c='red',
                edgecolors='none',s=100)

    plt.xticks([])
    plt.yticks([])

    plt.show()

    keep_ruuning = input("你要要继续运行随机漫步吗? (y/n):")
    if keep_ruuning == 'n':
         break

在这里插入图片描述

调整尺寸
import matplotlib.pyplot as plt
from random_walk import RandomWalk

#在程序处于活动状态,就不断地模拟随机漫步
while True:
    rw = RandomWalk(50000)
    rw.fill_walk()

    plt.figure(dpi=128,figsize=(10,6))

    point_numbers = list(range(rw.num_points))
    plt.scatter(rw.x_values, rw.y_values, c=point_numbers, cmap=plt.cm.Blues,
                edgecolors='none', s=1)
    plt.scatter(0,0,c='green',edgecolors='none',s=100)
    plt.scatter(rw.x_values[-1],rw.y_values[-1],c='red',
                edgecolors='none',s=100)

    plt.xticks([])
    plt.yticks([])

    plt.show()

    keep_ruuning = input("你要要继续运行随机漫步吗? (y/n):")
    if keep_ruuning == 'n':
         break

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/tianlei_/article/details/130536157