接着上节继续学习,在本节中,我们将使用 Python 来生成随机漫步数据,再使用 matplotlib 以引人瞩目的方式将这些数据呈现出来。随机漫步是这样行走得到的路径:每次行走都完全是随机的,没有明确的方向,结果是由一系列随机决策决定的。你可以这样认为,随机漫步就是蚂蚁在晕头转向的情况下,每次都沿随机的方向前行所经过的路径。
为模拟随机漫步,我们将创建一个名为 RandomWalk 的类,它随机地选择前进方向。这个类需要三个属性,其中一个是存储随机漫步次数的变量,其他两个是列表,分别存储随机漫步经过的每个点的 x 和 y 坐标。代码如下:
- from random import choice
- class RandomWalk() :
- '''一个生成随机漫步数的类'''
- def __init__(self,num_points=50000):
- '''初始化随机漫步的属性'''
- self.num_points = num_points
- #所有随机漫步都始于(0,0)
- self.x_values = [0]
- self.y_values =[0]
我们将使用 fill_walk() 来生成漫步包含的点,并决定每次漫步的方向,如下所示。请将这个方法添加到 random_walk.py 中:
- 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)
代码注释的很清楚了,我再强调几点:
(1)我们建立了一个循环,这个循环不断运行,直到漫步包含所需数量的点。
(2)如何模拟四种漫步决定:向右走还是向左走?沿指定的方向走多远?向上走还是向下走?沿选定的方向走多远?
- import matplotlib.pyplot as plt
- from random_walk import RandomWalk
- while True :
- random_walk = RandomWalk()
- random_walk.fill_walk()
- plt.figure(figsize=(10,6))
- point_numbers = list(range(random_walk.num_points))
- plt.scatter(random_walk.x_values,random_walk.y_values,c=point_numbers,cmap=plt.cm.Blues,edgecolor="none",s=1)
- # 突出起点和终点
- plt.scatter(0, 0, c='green', edgecolors='none', s=100)
- plt.scatter(random_walk.x_values[-1], random_walk.y_values[-1], c='red', edgecolors='none',
- s=100)
- #隐藏坐标轴
- plt.axes().get_xaxis().set_visible(False)
- plt.axes().get_yaxis().set_visible(False)
- plt.show()
- input_flag = input("是否结束?(Y/N)")
- if input_flag == "Y" :
- break
运行效果图如下:
注意几点:
(1)模拟多次随机漫步:每次随机漫步都不同,因此探索可能生成的各种模式很有趣。要在不多次运行程序的情况下使用前面的代码模拟多次随机漫步,一种办法是将这些代码放在一个 while 循环中。
(2)给点着色:我们将使用颜色映射来指出漫步中各点的先后顺序,并删除每个点的黑色轮廓,让它们的颜色更明显。为根据漫步中各点的先后顺序进行着色。
(3)重新绘制起点和终点:,可在绘制随机漫步图后重新绘制起点和终点。我们让起点和终点变得更大,并显示为不同的颜色,以突出它们。
(4)隐藏坐标轴:为修改坐标轴,使用了函数 plt.axes() 来将每条坐标轴的可见性都设置为 False。随着你越来越多地进行数据可视化,经常会看到这种串接方法的方式。
(5)增加点数:增大 num_points 的值,并在绘图时调整每个点的大小。
(6)调整尺寸以适合屏幕:函数 figure() 用于指定图表的宽度、高度、分辨率和背景色。你需要给形参 figsize 指定一个元组,向 matplotlib 指出绘图窗口的尺寸,单位为英寸。
在本节中,我们将使用 Python 可视化包 Pygal 来生成可缩放的矢量图形文件。对于需要在尺寸不同的屏幕上显示的图表,这很有用,因为它们将自动缩放,以适合观看者的屏幕。如果你打算以在线方式使用图表,请考虑使用 Pygal 来生成它们,这样它们在任何设备上显示时都会很美观。
在这个项目中,我们将对掷骰子的结果进行分析。掷 6 面的常规骰子时,可能出现的结果为 1~6 点,且出现每种结果的可能性相同。然而,如果同时掷两个骰子,某些点数出现的可能性将比其他点数大。为确定哪些点数出现的可能性最大,我们将生成一个表示掷骰子结果的数据集,并根据结果绘制出一个图形。
python -m pip install --user pygal
- from random import randint
- class Die():
- '''表示一个骰子的类'''
- def __init__(self,num_sides=6):
- '''骰子默认6个面'''
- self.num_sides=num_sides
- def roll(self):
- #返回一个1-面数之间的随机值
- return randint(1,self.num_sides)
使用这个类来创建图表前,先来掷 D6 骰子,将结果打印出来,并检查结果是否合理:
- from die import Die
- die=Die()
- results=[]
- for roll_num in range(100) :
- result=die.roll()
- results.append(result)
- print(results)
结果如下:
为分析掷一个 D6 骰子的结果,我们计算每个点数出现的次数:
- from die import Die
- die=Die()
- results=[]
- for roll_num in range(1000) :
- result=die.roll()
- results.append(result)
- #分析结果
- frequencies=[]
- for value in range(1,die.num_sides+1) :
- frequency=results.count(value)
- frequencies.append(frequency)
- print(frequencies)
结果如下:[156, 171, 151, 173, 181, 168]
结果看起来是合理的:我们看到了 6 个值——掷 D6 骰子时可能出现的每个点数对应一个;我们还发现,没有任何点数出现的频率比其他点数高很多。下面来可视化这些结果。
- from die import Die
- import pygal
- die=Die()
- results=[]
- for roll_num in range(1000) :
- result=die.roll()
- results.append(result)
- #分析结果
- frequencies=[]
- for value in range(1,die.num_sides+1) :
- frequency=results.count(value)
- frequencies.append(frequency)
- #print(frequencies)
- #对结果进行可视化
- hist = pygal.Bar()
- hist.title= "Results of rolling one D6 1000 times."
- hist.x_labels=['1','2','3','4','5','6']
- hist.x_title = "Result"
- hist.y_title = "Frequency of Result"
- hist.add("D6",frequencies)
- hist.render_to_file("die_visual.svg")
为创建条形图,我们创建了一个 pygal.Bar() 实例,并将其存储在 hist 中, 我们设置 hist 的属性 title(用于标示直方图的字符串),将掷 D6 骰子的可能结果用作 x 轴的标签,并给每个轴都添加了标题, 我们使用 add() 将一系列值添加到图表中(向它传递要给添加的值指定的标签,还有一个列表,其中包含将出现在图表中的值)。最后,我们将这个图表渲染为一个 SVG 文件,这种文件的扩展名必须为. svg。
要查看生成的直方图,最简单的方式是使用 web 浏览器。如下图:
每次掷两个骰子时,我们都将两个骰子的点数相加,并将结果存储在 results 中。请复制 die_visual.py 并将其保存为 dice_visual.py,再做如下修改:
- from die import Die
- import pygal
- die_1=Die()
- die_2=Die()
- results=[]
- for roll_num in range(1000) :
- result=die_1.roll() + die_2.roll()
- results.append(result)
- #分析结果
- frequencies=[]
- max_result = die_1.num_sides + die_2.num_sides
- for value in range(2,max_result+1) :
- frequency=results.count(value)
- frequencies.append(frequency)
- #print(frequencies)
- #对结果进行可视化
- hist = pygal.Bar()
- hist.title= "Results of rolling two D6 1000 times."
- hist.x_labels=['1','2','3','4','5','6''7','8','9','10','11','12']
- hist.x_title = "Result"
- hist.y_title = "Frequency of Result"
- hist.add("D6+D6",frequencies)
- hist.render_to_file("die_visual.svg")
结果如下:
也可以掷不同的骰子,就不在详解了!未完待续!
来源: https://www.cnblogs.com/majianchao/p/8143647.html