3.3 绘制其他类型的散点图和折线图
除了在本章前面介绍的散点图和折线图外,还可以使用Python绘制功能更加强大的散点图和折线图。在本节的内容中,将详细讲解绘制其他类型的散点图和折线图的知识。
3.3.1 绘制随机漫步图
随机漫步(random walk)是一种数学统计模型,它由一连串轨迹所组成。其中每一次都是随机的,它能用来表示不规则的变动形式。气体或液体中分子活动的轨迹等可作为随机漫步的模型。如同一个人酒后乱步所形成的随机记录。在1903年由卡尔·皮尔逊首次提出随机漫步这一概念,目前已经被广泛应用于生态学、经济学、心理学、计算科学、物理学、化学和生物学等领域,用来说明这些领域内观察到的行为和过程,因而是记录随机活动的基本模型。
1. 在Python程序中生成随机漫步数据
在Python程序中生成随机漫步数据后,可以使用Matplotlib以灵活方便的方式将这些数据展现出来。随机漫步的行走路径很有自己的特色,每次行走动作都完全是随机的,没有任何明确的方向,漫步结果是由一系列随机决策决定的。例如,漂浮在水滴上的花粉因不断受到水分子的挤压而在水面上移动。水滴中的分子运动是随机的,因此花粉在水面上的运动路径犹如随机漫步。
为了在Python程序中模拟随机漫步的过程,在下面的实例文件random_walk.py中创建一个名为RandomA的类,此类可以随机地选择前进方向。类RandomA需要用到3个属性,其中一个是存储随机漫步次数的变量,其他两个是列表,分别用于存储随机漫步经过的每个点的x坐标和y坐标。
源码路径:codes\3\3-3\random_walk.py
from random import choice
class RandomA():
"""能够随机生成漫步数据的类"""
def __init__(self, num_points=5100):
"""初始化随机漫步属性"""
self.num_points = num_points
# 所有的随机漫步开始于 (0, 0).
self.x_values = [0]
self.y_values = [0]
def shibai(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)
在上述代码中,类RandomA包含两个函数:__init__ ()和shibai(),其中后者用于计算随机漫步经过的所有点。
(1)函数__init__ ():实现初始化处理。
- 为了能够做出随机决策,首先将所有可能的选择都存储在一个列表中。在每次做出具体决策时,通过“from random import choice”代码使用函数choice()来决定使用哪种选择。
- 接下来将随机漫步包含的默认点数设置为5100,这个数值能够确保足以生成有趣的模式,同时也能够确保快速地模拟随机漫步。
- 然后,在第8行和第9行代码中创建了两个用于存储x和y值的列表,并设置每次漫步都从点(0,0)开始出发。
(2)函数shibai():功能是生成漫步包含的点,并决定每次漫步的方向。
- 第13行:使用while语句建立了一个循环,这个循环可以不断运行,直到漫步包含所需数量的点为止。这个函数的主要功能是告知Python应该如何模拟四种漫步决定:向右走还是向左走?沿指定的方向走多远?向上走还是向下走?沿选定的方向走多远?
- 第15行:使用choice([1, −1])给x_direction设置一个值,在漫步时要么表示向右走的1,要么表示向左走的−1。
- 第16行:使用choice([0, 1, 2, 3, 4])随机地选择一个0~4之间的整数,告诉Python沿指定的方向走的距离(x_distance)。通过包含0,不但可以沿两个轴进行移动,而且还可以沿着y轴进行移动。
- 第17行到第20行,将移动方向乘以移动距离,以确定沿x轴移动的距离。如果x_step为正则向右移动,如果为负则向左移动,如果为0则垂直移动;如果y_step为正则向上移动,如果为负则向下移动,如果为零则水平移动。
- 第22行和第23行:开始执行下一次循环。如果x_step和y_step都为零则原地踏步,在我们的程序中必须杜绝这种原地踏步的情况发生。
- 第25到第28行:为了获取漫步中下一个点的x值,将x_step与x_values中的最后一个值相加,对y值进行相同的处理。获得下一个点的x值和y值之后,将它们分别附加到列表x_values和y_values的末尾。
2. 在Python程序中绘制随机漫步图
在前面的实例文件random_walk.py中,已经创建了一个名为RandomA的类。在下面的实例文件yun.py中,将借助于 matplotlib 将类 RandomA 中生成的漫步数据绘制出来,最终生成一个随机漫步图。
源码路径:codes\3\3-3\yun.py
import matplotlib.pyplot as plt
from random_walk import RandomA
#只要当前程序是活动的,就要不断模拟随机漫步过程
while True:
#创建一个随机漫步实例,将包含的点都绘制出来
rw = RandomA(51000)
rw.shibai()
# 设置绘图窗口的尺寸大小
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.axes().get_xaxis().set_visible(False)
plt.axes().get_yaxis().set_visible(False)
plt.show()
keep_running = input("哥,还继续漫步吗? (y/n): ")
if keep_running == 'n':
break
(1)第1行和第2行:分别导入模块pyplot和前面编写的类RandomA。
(2)第5行:创建一个RandomA实例,并将其存储到rw中。
(3)第6行:设置点数的数目。
(4)第7行:调用函数shibai()。
(5)第9行:使用函数figure()设置图表的宽度、高度、分辨率。
(6)第10行:使用颜色映射来指出漫步中各点的先后顺序,并删除每个点的黑色轮廓,这样可以让它们的颜色显示更加明显。为了根据漫步中各点的先后顺序进行着色,需要传递参数 c,并将其设置为一个列表,其中包含各点的先后顺序。由于这些点是按顺序绘制的,因此给参数c指定的列表只需包含数字1~51000即可。使用函数range()生成一个数字列表,其中包含的数字个数与漫步包含的点数相同。接下来,我们将这个列表存储在point_numbers中,以便后面使用它来设置每个漫步点的颜色。
(7)第11行到第12行:将随机漫步包含的x和y值传递给函数scatter(),并选择了合适的点尺寸。将参数c设置为在第10行中创建的point_numbers,用于设置使用颜色映射Blues,并传递实参edgecolors='none'删除每个点周围的轮廓。
(8)第14到第16行:在绘制随机漫步图后重新绘制起点和终点,目的是突出显示随机漫步过程中的起点和终点。在程序中让起点和终点变得更大,并用不同的颜色显示。为了实现突出显示的功能,使用绿色绘制点(0,0),设置这个点比其他的点都粗大(设置为s=100)。在突出显示终点时,在漫步包含的最后一个坐标的x值和y值的位置绘制一个点,并设置它的颜色是红色,并将其粗大值s设置为100。
(9)第18行和第19行:隐藏图表中的坐标轴,使用函数plt.axes()将每条坐标轴的可见性都设置为False。
(10)第21行到第23行:实现模拟多次随机漫步功能,因为每次随机漫步都不同,要想在不多次运行程序的情况下使用前面的代码实现模拟多次随机漫步的功能,最简单的办法是将这些代码放在一个while循环中。这样通过本实例模拟一次随机漫步后,在matplotlib查看器中可以浏览漫步结果,接下来可以在不关闭查看器的情况下暂停程序的执行,并询问你是否要再模拟一次随机漫步。如果输入y则可以模拟多次随机漫步。这些随机漫步都在起点附近进行,大多数是沿着特定方向偏离起点,漫步点分布不均匀等。要结束程序的运行,只需输入n即可。
本实例最终执行后的效果如图3-26所示。
图3-26 执行效果
3.3.2 大数据可视化分析某地的天气情况
假设存在一个CSV文件“death_valley_2014.csv”,在里面保存了2014年某地全年每一天各个时段的温度,下面开始可视化分析这个CSV文件。
(1)可视化展示2014年4月的温度
编写Python文件4month.py,使用库Matplotlib绘制统计折线图,可视化显示2014年4月的温度。文件4month.py的具体实现代码如下所示。
import csv
from datetime import datetime
from matplotlib import pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
filename='./csv/death_valley_2014.csv'
with open(filename,'r')as file:
#1.创建阅读器对象
reader=csv.reader(file)
#2.读取文件头信息
header_row=next(reader)
#3.保存最高气温数据
dates,hights=[],[]
for row in reader:
current_date=datetime.strptime(row[0],"%Y-%m-%d")
dates.append(current_date)
#4.将字符串转换为整型数据
hights.append(row[1])
#5.根据数据绘制图形
fig=plt.figure(dpi=128,figsize=(10,6))
#6.将列表hights传个plot()方法
plt.plot(dates,hights,c='red')
#7.设置图形的格式
plt.title('2014年4月份的温度',fontsize=24)
plt.xlabel('',fontsize=26)
# 8.绘制斜线日期标签
fig.autofmt_xdate()
plt.ylabel('华摄氏度F',fontsize=16)
plt.tick_params(axis='both',which='major',labelsize=16)
plt.show()
本实例的执行效果如图3-27所示。
图3-27 执行效果
(2)可视化展示全年天气数据
编写Python文件year.py,使用库Matplotlib绘制统计折线图,可视化显示2014年全年的温度。文件year.py的具体实现代码如下所示。
import csv
from datetime import datetime
from matplotlib import pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
filename='./csv/death_valley_2014.csv'
with open(filename,'r')as file:
#1.创建阅读器对象
reader=csv.reader(file)
#2.读取文件头信息
header_row=next(reader)
#3.保存最高气温数据
dates,hights=[],[]
for row in reader:
current_date=datetime.strptime(row[0],"%Y-%m-%d")
dates.append(current_date)
#4.将字符串转换为整型数据
hights.append(row[1])
#5.根据数据绘制图形
fig=plt.figure(dpi=128,figsize=(10,6))
#6.将列表hights传个plot()方法
plt.plot(dates,hights,c='red')
#7.设置图形的格式
plt.title('2014全年的温度',fontsize=24)
plt.xlabel('',fontsize=26)
# 8.绘制斜线日期标签
fig.autofmt_xdate()
plt.ylabel('华摄氏度F',fontsize=16)
plt.tick_params(axis='both',which='major',labelsize=16)
plt.show()
本实例的执行效果如图3-28所示。
图3-28 执行效果
(3)可视化展示某年最高温度和最低温度
编写Python文件high_lows.py,使用库Matplotlib绘制统计折线图,统计出2014年的最高温度和最低温度。文件high_lows.py的具体实现代码如下所示。
源码路径:codes\3\3-3\high_lows.py
import csv
from matplotlib import pyplot as plt
from datetime import datetime
file = './csv/death_valley_2014.csv'
with open(file) as f:
reader = csv.reader(f)
header_row = next(reader)
# 从文件中获取最高气温
highs,dates,lows = [], [], []
for row in reader:
try:
date = datetime.strptime(row[0],"%Y-%m-%d")
high = int(row[1])
low = int(row[3])
except ValueError:
print(date,'missing data')
else:
highs.append(high)
dates.append(date)
lows.append(low)
# 根据数据绘制图形
fig = plt.figure(figsize=(10,6))
plt.plot(dates,highs,c='r',alpha=0.5)
plt.plot(dates,lows,c='b',alpha=0.5)
plt.fill_between(dates,highs,lows,facecolor='b',alpha=0.2)
# # 设置图形的格式
plt.title('Daily high and low temperatures-2014',fontsize=16)
plt.xlabel('',fontsize=12)
fig.autofmt_xdate()
plt.ylabel('Temperature(F)',fontsize=12)
plt.tick_params(axis='both',which='major',labelsize=20)
plt.show()
执行后的效果如图3-29所示。
图3-29 执行效果