《Python编程:从入门到实践》笔记。
从本篇起将用三篇的篇幅介绍如何用Python进行数据可视化。
1. 前言
从本篇开始,我们将用三篇的篇幅来初步介绍如何使用Python来进行数据可视化操作。本篇的内容包括:
- 绘制简单的折线图;
- 随机漫步;
- 使用
Pygal
模拟掷骰子。
在正式开始之前,需要安装两个扩展包:matplotlib
和pygal
。Python中安装第三方库的方式已在上一个项目中介绍过了,这里不再赘述。
2. 绘制简单的折线图
2.1 简单的折线图
首先我们绘制一个简单的折线图,代码保存到mpl_squares.py
文件中:
import matplotlib.pyplot as plt
# 输入数据, x轴
input_values = [1, 2, 3, 4, 5]
# 输出数据, y轴
squares = [1, 4, 9, 16, 25]
# linewidth表示线条的粗细
plt.plot(input_values, squares, linewidth=5)
# 设置图标标题,并给坐标轴加上标签
plt.title("Square Numbers", fontsize=24)
plt.xlabel("Value", fontsize=14)
plt.ylabel("Square of Value", fontsize=14)
# 设置刻度标记的大小
plt.tick_params(axis="both", labelsize=14)
plt.show()
matplotlib.pyplot.plot()
函数可以只传入一个squares
参数,表示y
轴的值,此时将从x
轴0点处开始一一对应。有时这样很简便,但在此例中图标将不正确,所以我们传入了input_values
列表,将其与squares
列表一一对应。
代码从第10行到15行都可以省了,这些代码只是让图表的信息更全。最终的结果如下:
2.2 生成散点图
我们使用matplotlib.pyplot
中的scatter()
函数来生成散点图,将代码保存到scatter_squares.py
文件中:
import matplotlib.pyplot as plt
x_values = list(range(1, 1001))
y_values = [x ** 2 for x in x_values]
# s表示点的大小,edgecolor表示点的轮廓的颜色,c表示数据点的颜色(可以使用RGB颜色)
# plt.scatter(x_values, y_values, s=4, edgecolor="none", c="red")
# 使用渐变色, 给c赋值了一个y值列表,并使用参数cmap告诉pylot使用哪个颜色来映射
plt.scatter(x_values, y_values, s=40, edgecolor="none", c=y_values, cmap=plt.cm.Blues)
# 设置图表标题并给坐标轴加上标签
plt.title("Square Number", fontsize=24)
plt.xlabel("Value", fontsize=14)
plt.ylabel("Square of Value", fontsize=14)
# 设置刻度的大小
plt.tick_params(axis="both", which="major", labelsize=14)
# 每个坐标轴的取值范围
plt.axis([0, 1100, 0, 1100000])
# 第一个参数是路径名,第二个参数指定将图表多余的空白区域裁减掉。
plt.savefig("squares.png", bbox_inches="tight")
plt.show()
我们使用了列表生成式来生成y轴的数据,并使用渐变色来绘制图像,matplotlib.pyplot.cm.Blues
是matplotlib
自带的渐变色,它和c
的每一个值对应。通过pyplot
的axis()
函数来设置每个轴的取值范围。最后将图像保存到本地。生成的图像如下:
3. 随机漫步
随机漫步指的是:每次行走都完全随机,没有明确的方向,结果是由一系列随机决策决定的。在自然界、物理学、生物学、化学和经济领域,随机漫步都有其实际用途。
使用Python生成随机漫步数据,再使用matplotlib
将这些数据绘制出来。首先创建RandomWalk
类,代码保存到random_walk.py
文件中:
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]
def fill_walk(self):
"""计算随机漫步包含的所有点"""
# 不断漫步,直到列表到达指定的长度
while len(self.x_values) < self.num_points:
# 决定前进方向以及沿这个方向前进的距离
# 通过choice从给定值中随机选取
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
# 计算下一个点的坐标
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)
下面的代码用于生成随机漫步图像,代码保存到rw_visual.py
文件中:
import matplotlib.pyplot as plt
from random_walk import RandomWalk
while True:
rw = RandomWalk(50000)
rw.fill_walk()
# 设置绘图窗口的尺寸
plt.figure(figsize=(10, 6))
# 绘制随机漫步的图像
point_number = list(range(rw.num_points))
plt.scatter(rw.x_values, rw.y_values, s=1, c=point_number,
edgecolors="none", cmap=plt.cm.Blues)
# 突出起点和终点
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()
if input("Make another walk?(y/n)") == "n":
break
程序通过一个循环类多次绘制随机漫步图;通过pyplot
的figure()
函数来设置图像的尺寸,figsize
的单位是英寸;通过渐变色来绘制图像的路径,颜色由浅到深,并且我们将起点(绿色)和终点(红色)显著标出;最后隐藏坐标轴。最终的图像如下(每次运行的效果都不同):
4. 使用Pygal模拟掷骰子
首先我们需要创建一个骰子类Dice
,将其保存到dice.py
中:
from random import randint
class Dice:
"""表示一个骰子类"""
def __init__(self, num_sides=6):
"""骰子默认为6面"""
self.num_sides = num_sides
def roll(self):
"""返回一个位于1和骰子面数之间的随机值"""
return randint(1, self.num_sides)
可以自行设定骰子的面数。下面是掷两个骰子50000次,统计俩骰子点数之和的分布的模拟,最后生成了一个矢量文件.svg
文件,它能在浏览器中打开,代码如下:
import pygal
from dice import Dice
dice_1 = Dice()
dice_2 = Dice(10)
# 掷骰子多次,并将结果存储在一个列表中
results = []
for roll_num in range(50000):
results.append(dice_1.roll() + dice_2.roll())
# 分析结果
frequences = []
# 能够模拟掷任何双骰子的情况,不管这些骰子有多少面
max_result = dice_1.num_sides + dice_2.num_sides
for value in range(2, max_result + 1):
# 统计每个结果的频数
frequences.append(results.count(value))
# 对结果进行可视化
# 创建条形图
hist = pygal.Bar()
hist.title = "Result of rolling a D6 and a D10 50000 times."
# 创建x轴上的刻度
hist.x_labels = [str(value) for value in range(2, max_result + 1)]
hist.x_title = "Result"
hist.y_title = "Frequency of Result"
# 给这组数据起个名字,并加到图表中
hist.add("D6 + D10", frequences)
# 将图像渲染为svg文件,矢量图
hist.render_to_file("dice_visual.svg")
注意,frequences
中的数据依次与hist.x_labels
对应。下面是最终结果:
Pygal
让这个图表具有交互性:如果你将鼠标指向该图中的任何数据条,将看到它的具体数据。
5. 小结
本篇主要讲述了:
- 如何生成数据集以及如何对其进行可视化;
- 如何使用
matplotlib
创建简单的图表; - 如果使用散点图来探索随机漫步过程;
- 如何使用
Pygal
创建直方图,以及如何使用直方图来探索同时掷两个面数不同的骰子的结果。
迎大家关注我的微信公众号”代码港” & 个人网站
www.vpointer.net ~