从上篇文章,我们开始为大家介绍Python应用之数据可视化篇,上篇文章给大家介绍数据可视化需要的重要工具——matplotlib的安装与使用;主要包括本项目背景的介绍、安装matplotlib的教程、以及通过matplotlib绘制简单的折线图。本文将给大家介绍数据可视化的一个新的概念——随机漫步;首先给大家介绍随机漫步的相关概念。
在本文中,我们将用Python来实现随机漫步的数据。再使用matplotlib以引人注目的方式将这些数据呈现出来。随机漫步是这样行走得到的路径:每次行走都是随机的,没有明确的方向,结果是由一系列随机决策决定的。我们当然也可以这样认为,随机漫步就是蚂蚁在晕头转向的情况下,每次都沿着随机的方向前行所经过的路径。
在自然界、物理学、生物学、化学和经济领域,随机漫步都有其实际用途。例如,漂浮在水滴上的花粉因不断受到水分子的挤压而在水上面移动。水滴中的分子运动是随机的,因此,花粉在水面上的运动路径犹如随机漫步。
RandomWalk()
类 为模拟随机漫步,我们将创建一个名为RandomWalk
的类,它随机地选择前进的方向。这个类需要三个属性,其中一个是存储随机漫步次数的变量,其他两个是列表,分别是存储随机漫步经过的每个点的x和y坐标。其项目结构主要如下图所示:
RandomWalk
类只包含两个方法:__init__()
和fill_walk()
,其中后者计算随机漫步经过的所有点。首先让我们实现__init__()
方法:
from random import choice
class RandomWalk():
"""一个生成随机漫步数据的类"""
def __init__(self, num_points=5000):
"""初始化随机漫步的属性"""
self.num_points = num_points
# 所有随机漫步都始于(0,0)
self.x_values = [0]
self.y_values = [0]
为做出随机决策,我们将所有可能的选择都存储在一个列表中,并在每次做决策时都使用choice()
来决定使用哪种选择。接下来,我们将随机漫步包含的默认点数设置为5000,这大到足以生成有趣的模式,同时又足够小,可确保能够快速地模拟随机漫步。然后,我们创建了两个用于存储x和y值的列表,并让每次漫步都从点(0,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)
首先,我们建立了一个循环,这个循环在不断地运行,直到漫步包含所需数量的点。这个方法的主要部分告诉Python如何模拟四种漫步决定:向右走还是向左走?沿指定方向走多远?向上走还是向下走?沿选定方向走多远?
我们使用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均为零,则意味着原地踏步,我们不能够允许这样的情况存在。因此,需要continue结束本次循环,进入下次循环之中。
为了获取漫步中下一个点的x值,我们将x_step与x_values中的最后一个值相加,对于y值也做相同的处理。获得下一个点的x值和y值后,我们将它们分别添加到列表x_values、y_values的末尾。
接下来,我们将创建一个rw_visual.py
,相应的代码结构如下:
接下来我们将用代码实现随机漫步的所有点都绘制出来:
import matplotlib.pyplot as plt
from random_walk import RandomWalk
# 创建一个RandomWalk实例,并将其包含的点都绘制出来
rw = RandomWalk()
rw.fill_walk()
plt.scatter(rw.x_values, rw.y_values, s=15)
plt.show()
我们在本代码中首先就是导入了模块pyplot
和RandomWalk
类,然后创建了一个RandomWalk
实例,并将其存储到rw
中,在调用fill_walk()
。另外,我们将随机漫步包含的x值和y值传递给scatter()
,并选择了合适的点尺寸。接下来就是显示了包含5000个点的随机漫步图,具体效果如下:
不过,这里需要我们注意的是:既然是随机漫步,那就每次的运行,其结果是不一样的;当我们生成图形都是不一样的;我们第二次运行的效果如下:
每次随机漫步都不同,因此探索可能生成的各种模式很有趣。要在不多次运行程序的情况下使用前面的代码模拟多次随机漫步,一种办法是 将这些代码放在一个while
循环中,如下所示:
import matplotlib.pyplot as plt
from random_walk import RandomWalk
# 只要程序处于活动状态,更不断地模拟随机漫步
while True:
# 创建一个RandomWalk实例,就不断地模拟随机漫步
rw = RandomWalk()
rw.fill_walk()
plt.scatter(rw.x_values, rw.y_values, s=15)
plt.show()
keep_running = input("Make another walk?(y/n):")
if keep_running == 'n':
break
这些代码模拟一次随机漫步,在matplotlib查看器中显示结果。再在不关闭查看器的情况下暂停。如果我们关闭查看器,程序将询问我们是否在模拟一次随机漫步。如果我们输入y
表示可以模拟多次随机漫步:这些随机漫步都在起点附近进行的,大多沿特定方向偏离起点,漫步点分布不均匀等。当我们想要结束该程序运行的时候,我们只需要输入n
即可;具体效果如下:
在本小部分,我们将制定图表,以突出每次漫步的重要特点,并让分散注意力的元素不那么明显。为此,我们要确定突出的元素,如果漫步的起点、终点和经过的路径。接下来,确定要使其不那么显眼的元素,如刻度、标记和标签。最终的结果是简单的可视化表示,清楚地指出了每次漫步经过的路径。
我们将使用颜色映射来指出漫步中各点的先后顺序,并删除每个点的黑色轮廓,让他们的颜色更明显。为根据漫步中各点的先后顺序进行着色,我们传递参数c,并将其设置为一个列表,其中包含各点的先后顺序。由于这些点是按顺序绘制的,因此,给参数c指定的列表只包含数字1~5000,具体实现如下:
import matplotlib.pyplot as plt
from random_walk import RandomWalk
# 只要程序处于活动状态,更不断地模拟随机漫步
while True:
# 创建一个RandomWalk实例,就不断地模拟随机漫步
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_running = input("Make another walk?(y/n):")
if keep_running == 'n':
break
在此代码中,我们首先使用了range()
生成了一个数字列表,其中包含的数字个数与漫步包含的点数相同;接下来,我们将这个列表存储在point_numbers
中,以便后面使用它来设置每个漫步点的颜色。我们将参数c设置为point_numbers
,指定使用颜色映射Blues
,并传递实参edgecolor=none
以删除每个点周围的轮廓。最终的随机漫步图从浅蓝色渐变为深蓝色。具体效果如下:
除了给随机漫步的各个点着色,以指出它们的先后顺序外,如果还能呈现随机漫步的起点和终点就更好了。为此,可在绘制随机漫步图后重新绘制起点和终点。我们让起点和终点变得更大,并显示不同的颜色,以突出它们,具体实现如下:
import matplotlib.pyplot as plt
from random_walk import RandomWalk
# 只要程序处于活动状态,更不断地模拟随机漫步
while True:
# 创建一个RandomWalk实例,就不断地模拟随机漫步
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.show()
keep_running = input("Make another walk?(y/n):")
if keep_running == 'n':
break
在此代码中,我们为了突出起点和终点,我们使用绿色绘制点(0,0),并使其比其他点大(s=100)。为了突出终点,我们在漫步包含的最后一个x和y值处绘制一个点,将其颜色设置为红色,并将尺寸设置为100.请务必将这些代码放在调用plt.show()
的代码前面,确保在其他点的上面绘制起点和终点。
我们现在运行代码,将能准确地知道每次随机漫步的起点和终点。
这里需要我们注意的是:该点的颜色与我们编译器的界面颜色有直接的关系,如果你在运行代码的时候,你发现效果图的起点和终点图的效果不是很明显,那么你应该调整代码中的颜色个大小,直到自己能够很明显的区分出来即可。
接下来,我们来隐藏坐标轴,以免大家注意的是坐标轴的信息而忽略随机漫步的路径,具体隐藏坐标轴的实现如下:
import matplotlib.pyplot as plt
from random_walk import RandomWalk
# 只要程序处于活动状态,更不断地模拟随机漫步
while True:
# 创建一个RandomWalk实例,就不断地模拟随机漫步
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)
plt.show()
keep_running = input("Make another walk?(y/n):")
if keep_running == 'n':
break
为修改坐标轴,我们使用了函数plt.axes()
可将每条坐标轴的可见性设置为False
。随着我们越来越多地进行数据可视化,我们以后会经常看到这种串接方法的方式。
我们现在运行rw_visual.py
,我们将会看到一些列没有坐标轴的图形,具体效果如下:
接下来,我们通过增加点数以提供更多的数据。为此,我们在创建RandomWalk
实例时增大num_points
的值,并在绘图时调整每个点的大小,具体实现如下:
import matplotlib.pyplot as plt
from random_walk import RandomWalk
# 只要程序处于活动状态,更不断地模拟随机漫步
while True:
# 创建一个RandomWalk实例,就不断地模拟随机漫步
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.axes().get_xaxis().set_visible(False)
plt.axes().get_yaxis().set_visible(False)
plt.show()
keep_running = input("Make another walk?(y/n):")
if keep_running == 'n':
break
以上代码模拟了一次包含50000个点的随机漫步,并将其每个点的大小都设置为1.最终的随机漫步图更纤细,犹如一幅美丽的风景画,具体效果图所下:
我们将随机漫步的点数从之前的5000调到了50000,本人在运行的时候,就会感觉Python运行稍微有点慢,这是与我们点数的规模有关,同时也与我们计算机的性能有关。 这里给大家留一个小问题希望大家自己动手实践:我们可以不断提高这个随机漫步的点数,每当我们提高一个量级,它就会变慢一点,大家调这个点数,看看当点数达到多少之后,Python的运行速度就会及其的慢了。
图表适合屏幕大小时,更能有效地将数据中的规律呈现出来。为让绘图窗口更适合屏幕的大小,我们可以通过调整matplotlib的尺寸来将其实现:
import matplotlib.pyplot as plt
from random_walk import RandomWalk
# 只要程序处于活动状态,更不断地模拟随机漫步
while True:
# 创建一个RandomWalk实例,就不断地模拟随机漫步
rw = RandomWalk(50000)
rw.fill_walk()
plt.figure(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.axes().get_xaxis().set_visible(False)
plt.axes().get_yaxis().set_visible(False)
plt.show()
keep_running = input("Make another walk?(y/n):")
if keep_running == 'n':
break
函数figure()
用于指出图表的宽度和高度、分辨率和背景色。我们需要给形参figsize
指定一个元组,向matplotlib指出了绘制窗口的尺寸,这里的单位是英寸,具体效果图如下:
但这里需要我们注意的是:我们Python默认屏幕的分辨率是80像素/英寸,如果大家用上述代码运行的效果并不很明显,我们可以根据需要酌情调整其数字。但是,如果我们知道自己电脑的分辨率,可使用形参dpi
向figure()
传递该分辨率,以便我们有效的利用可用的屏幕空间,届时我们只需将上面的那一行代码添加dpi即可,具体实现如下:
plt.scatter(rw.x_values, rw.y_values, c=point_numbers,
cmap=plt.cm.Blues, edgecolors='none', s=1)
从上篇文章,我们开始为大家介绍Python应用之数据可视化篇,上篇文章给大家介绍数据可视化需要的重要工具——matplotlib的安装与使用;主要包括本项目背景的介绍、安装matplotlib的教程、以及通过matplotlib绘制简单的折线图。本文给大家介绍了随机漫步的详细使用方式,包括创建类、选择方向、绘制随机漫步图、模拟多次随机漫步、绘点着色以及标记终点和起点和增加点数、隐藏坐标轴等相关小功能的实现。Python是一门注重实际操作的语言,它是众多编程语言中最简单,也是最好入门的。当你把这门语言学会了,再去学习java、go以及C语言就比较简单了。当然,Python也是一门热门语言,对于人工智能的实现有着很大的帮助,因此,值得大家花时间去学习。生命不息,奋斗不止,我们每天努力,好好学习,不断提高自己的能力,相信自己一定会学有所获。加油!!!