前沿
Python 提供了很多模块用于数据可视化, 其中有 matplotlib,pygal. 我参考网上热门书籍Python 编程从入门到实战, 在测试与学习过程中遇到的些许问题加以解决, 才写下这一项目实战的心得, 对于 Python 基础部分就不细讲, 主要是项目核心要点和解决方案的描述. 本小节先讲述 pyplot 模块的基本使用.
新手的建议
针对新手, 真心觉得不要直接使用 Python 下载来的 IDLE 来开发, 因为功能太少了, 也不好使用. 我的建议是对于 Python 初学者, 先安装 Anaconda, 这是一个基于 Python 的数据处理和科学计算平台, 它已经内置了许多非常有用的第三方库, 我们装上 Anaconda, 就相当于把数十个第三方模块自动安装好了, 非常简单易用, 在安装界面添加 Anaconda 到 PATH 环境变量中勾上, 这样就会自动添加环境变量了. Anaconda 自带了一个编辑器 - Spyder, 可以使用 Spyder 编写代码, 知道有这个编辑器就好. 然后再安装一个 PyCharm, 它是一种 Python IDE, 带有一整套可以帮助用户在使用 Python 语言开发时提高其效率的工具.
Anaconda 和 PyCharm 安装过程和方法文档链接, 我是摘抄网上有用的资料再总结出来的: 链接: https://pan.baidu.com/s/10KcfLLvI9omIRSJ6JMK9Uw 密码: cgf8
利用 pyplot 模块的 plot 函数绘制折线图
我们先导入模块 pyplot, 然后使用该模块的 plot 函数来绘制折线图, 接着调用该模块的相关函数来调整, 设置图表的标题, 横纵标签, 刻度标记内容或大小. 注意, pyplot 模块的 plot 函数可以接收输入参数和输出参数, 还有线条粗细等参数, 但是若 plot 函数只指定输出参数(列表), 那么输入参数默认由 0 开始.
(1)plot 函数指定输出参数(1,2,3,4,5 的平方数列表)
- import matplotlib.pyplot as plt
- # pyplot 模块的 plot 函数可以接收输入参数和输出参数, 还有线条粗细等参数,, 例如下方的示例
- squares = [1, 4, 9, 16, 25]
- plt.plot(squares, linewidth=5) # 这里只指定了一个列表, 那么就当作是输出参数, 输入参数从 0 开始, 就会发现没有正确绘制数据
- plt.title("Square Numbers", fontsize=24) # 指定标题, 并设置标题字体大小
- plt.xlabel("Value", fontsize=14) # 指定 X 坐标轴的标签, 并设置标签字体大小
- plt.ylabel("Square of Value", fontsize=14) # 指定 Y 坐标轴的标签, 并设置标签字体大小
- plt.tick_params(axis='both', labelsize=14) # 参数 axis 值为 both, 代表要设置横纵的刻度标记, 标记大小为 14
- plt.show() # 打开 matplotlib 查看器, 并显示绘制的图形
运行结果如下:
(2)plot 函数指定输入参数和输出参数
我们知道, 上面并没有按照我们的意愿来绘制图形, Y 轴指定为 [1,4,9,16,25], 上面采用默认输入参数处理 X 轴变成[0,1,2,3,4].X 轴应该对应值为[1,2,3,4,5] 才是我们的目的, 所以我们必须同时指定输入参数和输出参数才行. 观察运行结果图的 X 轴变化了.
- import matplotlib.pyplot as plt
- # 我也可以指定输入参数和输出参数, 这样就能按照我的意愿绘制图形了
- input_values = [1, 2, 3, 4, 5] # 指定输入参数
- squares = [1, 4, 9, 16, 25] # 指定输出参数
- plt.plot(input_values, squares, linewidth=5) # 调用绘制函数, 传入输入参数和输出参数
- plt.title("Square Numbers", fontsize=24) # 指定标题, 并设置标题字体大小
- plt.xlabel("Value", fontsize=14) # 指定 X 坐标轴的标签, 并设置标签字体大小
- plt.ylabel("Square of Value", fontsize=14) # 指定 Y 坐标轴的标签, 并设置标签字体大小
- plt.tick_params(axis='both', labelsize=14) # 参数 axis 值为 both, 代表要设置横纵的刻度标记, 标记大小为 14
- plt.show() # 打开 matplotlib 查看器, 并显示绘制的图形
运行结果如下:
利用 pyplot 模块的 scatter 函数绘制散点图
绘制散点图只不过是绘制函数不同, 从上面的 plot 变为 scatter, 其他设置标题, 横纵标签等的方式一样.
(1)scatter 函数绘制单个点
- import matplotlib.pyplot as plt
- plt.scatter(2, 4, s=200) # 传递一对 x 和 y 坐标. 它将在指定位置绘制一个点, 参数 s 是设置绘制图形时使用的点的尺寸
- plt.title("Square Numbers", fontsize=24) # 指定标题, 并设置标题字体大小
- plt.xlabel("Value", fontsize=14) # 指定 X 坐标轴的标签, 并设置标签字体大小
- plt.ylabel("Square of Value", fontsize=14) # 指定 Y 坐标轴的标签, 并设置标签字体大小
- plt.tick_params(axis='both', labelsize=14) # 参数 axis 值为 both, 代表要设置横纵的刻度标记, 标记大小为 14
- plt.show() # 打开 matplotlib 查看器, 并显示绘制的图形
运行结果如下:
(2)scatter 函数绘制一系列点
- import matplotlib.pyplot as plt
- x_values = [1, 2, 3, 4, 5]
- y_values = [1, 4, 9, 16, 25]
- plt.scatter(x_values, y_values, s=100) # 传入两个列表, 列表 x_values 的元素作为 x 坐标, 列表 y_values 的元素作为 y 坐标, 两个组合成一个点的坐标, 所以一共有 5 个点
- plt.title("Square Numbers", fontsize=24) # 指定标题, 并设置标题字体大小
- plt.xlabel("Value", fontsize=14) # 指定 X 坐标轴的标签, 并设置标签字体大小
- plt.ylabel("Square of Value", fontsize=14) # 指定 Y 坐标轴的标签, 并设置标签字体大小
- plt.tick_params(axis='both', labelsize=14) # 参数 axis 值为 both, 代表要设置横纵的刻度标记, 标记大小为 14
- plt.show() # 打开 matplotlib 查看器, 并显示绘制的图形
运行结果如下:
(3)自动计算 Y 轴的数据
前面个两个实例挺简单, 但也只是我们自己定义的短列表, 如果要绘制的点有很多, 那么还手动写当然不实际, 所以我们写一个根据我们指定的 X 轴的数据, 自动计算 Y 轴的数据就省事很多了.
- import matplotlib.pyplot as plt
- x_values = list(range(1, 1001)) # 我们是利用 range 函数生成一个从 1 到 1000 的可迭代对象(不包括 1001), 然后强制转换为列表
- y_values = [x ** 2 for x in x_values] # 这个语法是列表推导式, 将 x_values 每个元素的值进行平方再逐一放入列表, 最后这个列表推导式返回整个列表
- plt.scatter(x_values, y_values, s=40) # 在 2.0.0 版本后的 matplotlib 中, scatter()函数的实参 edgecolor(数据点的轮廓)默认为'none', 则删除轮廓.
- plt.title("Square Numbers", fontsize=24) # 指定标题, 并设置标题字体大小
- plt.xlabel("Value", fontsize=14) # 指定 X 坐标轴的标签, 并设置标签字体大小
- plt.ylabel("Square of Value", fontsize=14) # 指定 Y 坐标轴的标签, 并设置标签字体大小
- plt.axis([0, 1100, 0, 1100000]) # 设置每个坐标轴的取值范围. 其实最右侧就是 1100, 但是没有显示标签而已
- plt.show() # 打开 matplotlib 查看器, 并显示绘制的图形
运行结果如下:
注意, 在 2.0.0 版本后的 matplotlib 中 scatter()函数的实参 edgecolor(数据点的轮廓)不写则默认为'none', 代表删除轮廓. 也可以通过以下修改代码:
plt.scatter(x_values, y_values, s=40, edgecolor='red')
上述修改后的代码指定数据点轮廓的颜色为红色, 由于默认点的颜色为蓝色, 所以你将会看到下面这样, 只有右上角是蓝色, 其他都是红色, 这是因为绘制很多点, 红色轮廓都粘连在一起了, 所以看不出来.
修改代码后运行结果如下:
上面说了默认数据点的颜色为蓝色, 我们也可以通过参数 c 修改数据点的颜色, 至于颜色值可以采用直接写颜色英文如'red','black'等, 或者使用 RGB 颜色模式自定义颜色, 这个自定义颜色设置为一个元组, 其中包含三个 0~1 之间的小数值, 它们分别表示红色, 绿色和蓝色分量, 如(0,0,0.8). 可以通过下面这样修改代码:
- import matplotlib.pyplot as plt
- x_values = list(range(1, 1001))
- y_values = [x ** 2 for x in x_values]
- plt.scatter(x_values, y_values, c=(0, 0.8, 0), s=40) # 指定了 c 参数, 使用的是 RGB 颜色值方式
- plt.title("Square Numbers", fontsize=24) # 指定标题, 并设置标题字体大小
- plt.xlabel("Value", fontsize=14) # 指定 X 坐标轴的标签, 并设置标签字体大小
- plt.ylabel("Square of Value", fontsize=14) # 指定 Y 坐标轴的标签, 并设置标签字体大小
- plt.axis([0, 1100, 0, 1100000]) # 设置每个坐标轴的取值范围. 其实最右侧就是 1100, 但是没有显示标签而已
- plt.show() # 打开 matplotlib 查看器, 并显示绘制的图形
运行结果如下:
(4)使用颜色映射和自动保存图表
照书上 P294 页的使用颜色映射小节的描述对于初学者可能有点模棱两可, 这里采用我自己的代码来理解什么是颜色映射, 原理是什么.
测试代码如下:
- import matplotlib.pyplot as plt
- x_values = [1, 2, 3, 4, 5] # 含 x 值的列表
- y_values = [1, 4, 2, 6, 5] # 含 y 值的列表
- # 我们知道根据上面两个列表, 我们调用 scatter 可以绘制一系列的点
- # 模块 pyplot 内置了一组颜色映射, 通过设置 c 参数为 y 列表的值 (这个 y 列表的是[1,2,3,4,5]) 然后利用参数 cmap 根据 y 列表的大小映射到由 x_values 和 y_values 组成的五个点从浅到深的颜色, 可以看出 y 列表 [1,2,3,4,5] 分别映射到 (1,1),(2,4),(3,2),(4,6),(5,5) 五个点, 其中 (1,1) 点颜色最浅,(5,5)点颜色最深.
- plt.scatter(x_values, y_values, c=[1, 2, 3, 4, 5], cmap=plt.cm.Blues, s=100)
- plt.title("Square Numbers", fontsize=24) # 指定标题, 并设置标题字体大小
- plt.xlabel("Value", fontsize=14) # 指定 X 坐标轴的标签, 并设置标签字体大小
- plt.ylabel("Square of Value", fontsize=14) # 指定 Y 坐标轴的标签, 并设置标签字体大小
- plt.savefig("3.png", bbox_inches='tight') # 打开 matplotlib 查看器, 并显示绘制的图形
- # 值的注意的是, 要让程序自动将图表保存到文件中, 可将对 plt.show()的调用替换为对 plt.savefig()的调用.
- # 如果指定了 bbox_inches='tight'将图表多余的空白区域裁剪掉, 明显更符合用户需求, 如果没指定, 生成的图片显示不出 Y 轴的标签.
运行结果如下 (需要注意, 其实(1,1) 点的位置还有一个非常浅蓝色的点, 只是浅到看不到而已):
如果还不理解, 那么你就修改以下测试代码来运行观察:
plt.scatter(x_values, y_values, c=[1, 5, 3, 4, 5], cmap=plt.cm.Blues, s=100)
运行结果如下 (可以发现(2,4) 点的颜色也变成深蓝色了哦):
有了上面的理解基础, 我们可以修改为书本源代码, 来观察一下蓝色彗星的残影, 哈哈 O(_)O
书本源代码:
- import matplotlib.pyplot as plt
- x_values = list(range(1,1001)) # 含 x 值的列表
- y_values = [x ** 2 for x in x_values] # 含 y 值的列表
- # 我们知道根据上面两个列表, 我们调用 scatter 可以绘制一系列的点
- # 根据 y 列表的值大小进行颜色映射的, 值大的颜色深, 值小的颜色浅. 如果 y 列表的值按顺序, 并且映射到按顺序的点, 那么自然颜色也是从浅到深.
- # 模块 pyplot 内置了一组颜色映射, 通过设置 c 参数为 y 列表的值 (这个 y 列表的是[1,2,3,4,5]) 然后利用参数 cmap 根据 y 列表的大小映射到由 x_values 和 y_values 组成的五个点从浅到深的颜色, 可以看出 y 列表 [1,2,3,4,5] 分别映射到 (1,1),(2,4),(3,2),(4,6),(5,5) 五个点, 其中 (1,1) 点颜色最浅,(5,5)点颜色最深.
- plt.scatter(x_values, y_values, c=y_values, cmap=plt.cm.Blues, s=40)
- plt.title("Square Numbers", fontsize=24) # 指定标题, 并设置标题字体大小
- plt.xlabel("Value", fontsize=14) # 指定 X 坐标轴的标签, 并设置标签字体大小
- plt.ylabel("Square of Value", fontsize=14) # 指定 Y 坐标轴的标签, 并设置标签字体大小
- plt.savefig("3.png", bbox_inches='tight') # 打开 matplotlib 查看器, 并显示绘制的图形
运行结果图如下(蓝色彗星残影):
利用 pyplot 模块的 scatter 函数绘制随机漫步图
套用书本原话来说, 随机漫步: 每次行走都完全是随机的, 没有明确的方向, 结果是由一系列随机决策决定的.
为了实现随机漫步, 需要做以下几步就可以完成:
1. 创建 RandomWalk 类来生成随机漫步数据
2. 利用获取的随机漫步数据绘制随机漫步图
3. 模拟多次随机漫步
4. 设置随机漫步图的样式
(1)创建 RandomWalk 类来生成随机漫步数据
在项目里创建一个 random_walk.py 文件, 该文件代码如下:
- from random import choice
- # 一个生成随机漫步数据的类
- class RandomWalk:
- # 默认为 5000 个点, 代表 5000 步
- def __init__(self, num_points=5000):
- self.num_points = num_points
- self.x_values = [0]
- self.y_values = [0]
- # 获取随机方向和步数的乘积
- def get_step(self):
- return choice([1, -1]) * choice([0, 1, 2, 3, 4])
- def fill_walk(self):
- while len(self.x_values) < self.num_points:
- # 获取往哪个方向走几步
- x_step = self.get_step()
- y_step = self.get_step()
- # 如果原地踏步则 continue 处理
- 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)
(2)利用获取的随机漫步数据绘制随机漫步图
在项目里创建一个 rw_visual.py 文件, 该文件代码如下:
- import matplotlib.pyplot as plt
- from random_walk import RandomWalk
- # 创建一个 RandomWalk 实例, 并指定走 5000 步
- rw = RandomWalk(5000)
- rw.fill_walk() # 开始获取随机漫步数据, 其实获取的是两个包含 x 和 y 值的数据点列表
- plt.scatter(rw.x_values, rw.y_values, s=15)
- plt.show()
运行结果如下:
(3)模拟多次随机漫步
在 rw_visual.py 文件代码上加以修改, 修改代码如下:
- import matplotlib.pyplot as plt
- from random_walk import RandomWalk
- while True:
- rw = RandomWalk(5000)
- 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
运行结果如下(你点击右上角关闭按钮, 在 PyCharm 下方会弹出询问是否继续漫步):
(4)设置随机漫步图的样式
我们将设置随机漫步图的样式, 定制一个好看的随机漫步图, 有给点着色, 重新绘制起点和终点, 隐藏坐标轴, 调整尺寸以适合屏幕.
- import matplotlib.pyplot as plt
- from random_walk import RandomWalk
- while True:
- rw = RandomWalk(5000)
- rw.fill_walk()
- plt.figure(figsize=(20, 6))
- # 颜色映射就是用列表赋值给 c, 而这个列表的值可以随意, 大的代表颜色深, 小的代表颜色浅.
- point_number = list(range(rw.num_points)) # [0-4999]
- plt.scatter(rw.x_values, rw.y_values, c=point_number, cmap=plt.cm.Blues, s=4)
- # 突出起点和终点, 点变大, 用不同颜色来显示起点和终点
- plt.scatter(0, 0, c='green', s=100)
- plt.scatter(rw.x_values[-1], rw.y_values[-1], c='red', 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
运行结果如下:
来源: http://blog.51cto.com/12731497/2154195