matplotlib
绘图架构
学习目标
- 目标
- 知道Matplotlib的绘图架构
- 应用
- 无
一、什么是Matplotlib
- 是专门用于开发2D图表(包括3D图表)
- 使用起来及其简单
- 以渐进、交互式方式实现数据可视化
二、为什么要学习Matplotlib
可视化是在整个数据挖掘的关键辅助工具,可以清晰的理解数据,从而调整我们的分析方法。
- 能将数据进行可视化,更直观的呈现
- 使数据更加客观、更具说服力
例如下面两个图为数字展示和图形展示:
我们先来简单画一个图看下效果
plt.figure(figsize=(20, 8), dpi = 100)
plt.plot([1,2,3], [4,5,6])
plt.show()
四、Matplotlib框架构成
matplotlib框架分为三层,这三层构成了一个栈,上层可以调用下层。
1、后端层
matplotlib的底层,实现了大量的抽象接口类,这些API用来在底层实现图形元素的一个个类
- FigureCanvas对象实现了绘图区域这一概念
- Renderer对象在FigureCanvas上绘图
2、美工层
图形中所有能看到的元素都属于Artist对象,即标题、轴标签、刻度等组成图形的所有元素都是Artist对象的实例
- Figure:指整个图形(包括所有的元素,比如标题、线等)
- Axes(坐标系):数据的绘图区域
- Axis(坐标轴):坐标系中的一条轴,包含大小限制、刻度和刻度标签
特点为:
- 一个figure(图)可以包含多个axes(坐标系),但是一个axes只能属于一个figure。
- 一个axes(坐标系)可以包含多个axis(坐标轴),包含两个即为2d坐标系,3个即为3d坐标系
3、脚本层
主要用于可视化编程,pytplot模块可以提供给我们一个与matplotlib打交道的接口。可以只通过调用pyplot模块的函数从而操作整个程序包,来绘制图形。
- 操作或者改动Figure对象,例如创建Figure对象
- 大部分工作是处理样本文件的图形与坐标的生成
折线图与基础绘图功能
学习目标
- 目标
- 知道如何解决中文显示问题
- 知道matplotlib的图结构
- 应用figure实现创建绘图区域大小
- 应用plot实现折线图的绘制
- 应用title,xlabel,ylabel实现标题以及x,y轴名设置
- 应用xticks,yticks实现axes的刻度设置和标注
- 应用savefig实现图形的本地保存
- 应用grid实现显示网格应用axis实现图像形状修改
- 应用legend实现图形标注信息显示
- 应用plt.subplots实现多坐标系的创建
- 知道如何设置多个axes的标题、刻度
- 知道折线图的应用场景
- 应用
- 天气的温度变化显示
一、Parts of a Figure
二、折线图绘制与保存图片
为了更好的去理解所有基础绘图功能,我们通过天气温度变化的绘图来融合所有的基础API使用
1、matplotlib.pyplot模块
matplotlib.pytplot包含了一系列类似于matlab的画图函数。 它的函数作用于当前图形(figure)的当前坐标系(axes)。
import matplotlib.pyplot as plt
2、折线图绘制与显示
展现上海一周的天气,比如从星期一到星期日的天气温度如下
plt.figure(figsize=(10, 10))
plt.plot([1, 2, 3, 4, 5, 6 ,7], [17,17,18,15,11,11,13])
plt.show()
可以看到这样去显示效果并不好,图形的大小等等,所以我们可以通过加入更多的功能。
3、修改图形大小与图片保存
plt.figure(figsize=(), dpi=)
figsize:指定图的长宽
dpi:图像的清晰度
返回fig对象
plt.savefig(path)
plt.figure(figsize=(20, 8), dpi=80)
plt.savefig("test.png")
会将图片保存到当前路径下
三、温度变化显示
需求:画出某城市11点到12点1小时内每分钟的温度变化折线图,温度范围在15度~18度
效果:
1、构造数据、显示
# 画出温度变化图
# 创建一个figure
plt.figure(figsize=(20, 8), dpi=80)
# 准备x, y坐标的数据
x = range(60)
y_shanghai = [random.uniform(15, 18) for i in x]
# 画折线图
plt.plot(x, y_shanghai, label="上海")
plt.show()
2、自定义x,y刻度以及中文显示
-
plt.xticks(x, **kwargs)
x:要显示的刻度值
-
plt.yticks(y, **kwargs)
y:要显示的刻度值
# 增加以下两行代码
# 构造中文列表的字符串
x_ch = ["11点{}分".format(i) for i in x]
y_ticks = range(40)
# 修改x,y坐标的刻度
plt.xticks(x[::5], x_ch[::5])
plt.yticks(y_ticks[::5])
如果没有解决过中文问题的话,会显示这个样子:
2.1 中文显示问题解决
下载中文字体(黑体,看准系统版本)
-
下载 arial unicode ms 字体到 /home 目录
-
拷贝字体到 usr/share/fonts 下:
sudo cp ~/arial\ unicode\ ms.ttf /usr/share/fonts/arial\ unicode\ ms.ttf
-
修改配置文件matplotlibrc 并且在~/.matplotlib/matplotlibrc也进行修改
在安装的地方找到虚拟环境ai/lib/python3.6/site-packages/matplotlib/mpl-data目录下面,修改下面三项配置
font.family : sans-serif font.sans-serif : arial unicode ms, Bitstream Vera Sans, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
-
删除matplotlib字体缓存:
rm -rf ~/matplotlib/fontList.json
3、增加标题、x轴y轴描述信息
plt.xlabel("时间")
plt.ylabel("温度")
plt.title("中午11点0分到12点之间的温度变化图示")
4、再添加一个城市的温度变化
收集到北京当天温度变化情况,温度在1度到3度。怎么去添加另一个在同一坐标系当中的不同图形,其实很简单只需要再次plot即可,但是需要区分线条,如下显示
# 生成北京的温度
y_beijing = [random.uniform(1, 3) for i in x]
# 画折线图
plt.plot(x, y_shanghai, label="上海")
# 使用plot可以多次画多个折线
plt.plot(x, y_beijing, color='r', linestyle='--', label="北京")
# 添加图形注释
plt.legend(loc="best")
我们仔细观察,用到了两个新的地方,一个是对于不同的折线展示效果,一个是添加注释
4.1自定一个图形风格
颜色字符 | 风格字符 |
---|---|
r 红色 | - 实线 |
g 绿色 | - - 虚线 |
b 蓝色 | -. 点划线 |
w 白色 | : 点虚线 |
c 青色 | ' ' 留空、空格 |
m 洋红 | |
y 黄色 | |
k 黑色 |
4.2添加注释
plt.legend(loc="best")
5、多个坐标系显示-plt.subplots
如果我们想要将上海和北京的天气图显示在同一个图的不同坐标系当中,效果如下:
可以通过subplots函数实现(旧的版本中有subplot,使用起来不方便),推荐subplots函数
-
matplotlib.pyplot.subplots(nrows=1, ncols=1, **fig_kw) 创建一个带有多个坐标系的图
Parameters: nrows, ncols : int, optional, default: 1, Number of rows/columns of the subplot grid. **fig_kw : All additional keyword arguments are passed to the figure() call. Returns: fig : 图对象 ax : 设置标题等方法不同: set_xticks set_yticks set_xlabel set_ylabel
关于axes子坐标系的更多方法:参考https://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes
# 画出温度变化图,展现在不同axes里面
# 创建一个figure
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 8), dpi=80)
# 准备x, y坐标的数据
x = range(60)
# y的刻度范围
y_ticks = range(40)
y_shanghai = [random.uniform(15, 18) for i in x]
# 生成北京的温度
y_beijing = [random.uniform(1, 3) for i in x]
# 构造中文列表的字符串
x_ch = ["11点{}分".format(i) for i in x]
# 画折线图
axes[0].plot(x, y_shanghai, label="上海")
# 使用plot可以多次画多个折线
axes[1].plot(x, y_beijing, color='r', linestyle='--', label="北京")
# 美化x,y的刻度值
# 第一个参数必须是刻度数字类型,第二个是对应着第一个数字的中文描述
axes[0].set_xticks(x[::5], x_ch[::5])
axes[0].set_yticks(y_ticks[::5])
axes[1].set_xticks(x[::5], x_ch[::5])
axes[1].set_yticks(y_ticks[::5])
# 增加x,y描述信息和标题信息
axes[0].set_xlabel("时间")
axes[0].set_ylabel("温度")
axes[1].set_xlabel("时间")
axes[1].set_ylabel("温度")
axes[0].set_title("中午11点0分到12点之间的温度变化图示")
axes[1].set_title("中午11点0分到12点之间的温度变化图示")
axes[0].legend(loc="best")
axes[1].legend(loc="best")
plt.show()
四、折线图的应用场景
- 呈现公司产品(不同区域)每天活跃用户数
- 呈现app每天下载数量
- 呈现产品新功能上线后,用户点击次数随时间的变化
小结
开头的这几个目标应用全都很重要
- 知道如何解决中文显示问题
- 知道matplotlib的图结构
- 应用figure实现创建绘图区域大小
- 应用plot实现折线图的绘制
- 应用title,xlabel,ylabel实现标题以及x,y轴名设置
- 应用xticks,yticks实现axes的刻度设置和标注
- 应用savefig实现图形的本地保存
- 应用grid实现显示网格应用axis实现图像形状修改
- 应用legend实现图形标注信息显示
- 应用plt.subplots实现多坐标系的创建
- 知道如何设置多个axes的标题、刻度
柱状图
学习目标
- 目标
- 应用bar实现柱状图的绘制
- 知道柱状图的应用场景
- 应用
- 电影票房收入绘制
matplotlib能够绘制折线图、柱状图、饼图、直方图、散点图、热力图、K线图等,但是,我们需要知道不同的统计图到底能够表示出什么,以此来决定选择哪种统计图来更直观的呈现我们的数据
一、常见图形种类及意义
-
折线图:以折线的上升或下降来表示统计数量的增减变化的统计图
特点:能够显示数据的变化趋势,反映事物的变化情况。(变化)
-
直方图:由一系列高度不等的纵向条纹或线段表示数据分布的情况。 一般用横轴表示数据范围,纵轴表示分布情况。
特点:绘制,连续性的数据展示一组或者多组数据的分布状况(统计)
-
柱状图:排列在工作表的列或行中的数据可以绘制到柱状图中。
特点:绘制连离散的数据,能够一眼看出各个数据的大小,比较数据之间的差别。(统计)
-
散点图:用两组数据构成多个坐标点,考察坐标点的分布,判断两变量之间是否存在某种关联或总结坐标点的分布模式。
特点:判断变量之间是否存在数量关联趋势,展示离群点(分布规律)
二、柱状图图绘制
需求:每部电影的票房收入对比?
1、画出每部电影的票房收入对比,效果如下:
电影数据如下图所示:
['雷神3:诸神黄昏','正义联盟','东方快车谋杀案','寻梦环游记','全球风暴', '降魔传','追捕','七十七天','密战','狂兽','其它']
[73853,57767,22354,15969,14839,8725,8716,8318,7916,6764,52222]
2、绘制
- matplotlib.pyplot.bar(x, width, align='center', **kwargs)
绘制柱状图
Parameters:
x : sequence of scalars.
width : scalar or array-like, optional
柱状图的宽度
align : {‘center’, ‘edge’}, optional, default: ‘center’
Alignment of the bars to the x coordinates:
‘center’: Center the base on the x positions.
‘edge’: Align the left edges of the bars with the x positions.
每个柱状图的位置对齐方式
**kwargs :
color:选择柱状图的颜色
Returns:
`.BarContainer`
Container with all the bars and optionally errorbars.
代码:
# 完成简单的条形图展现不同的电影票房之间的对比
plt.figure(figsize=(20, 8), dpi=80)
# 准备电影的名字以及电影的票房数据
movie_name = ['雷神3:诸神黄昏','正义联盟','东方快车谋杀案','寻梦环游记','全球风暴','降魔传','追捕','七十七天','密战','狂兽','其它']
y = [73853,57767,22354,15969,14839,8725,8716,8318,7916,6764,52222]
# 放进横坐标的数字列表
x = range(len(movie_name))
# 画出条形图
plt.bar(x, y, width=0.5, color=['b','r','g','y','c','m','y','k','c','g','g'])
# 修改刻度名称
plt.xticks(x, movie_name)
plt.show()
如何对比电影票房收入才更能加有说服力?
3、比较相同天数的票房
有时候为了公平起见,我们需要对比不同电影首日和首周的票房
3.1数据如下
movie_name = ['雷神3:诸神黄昏','正义联盟','寻梦环游记']
first_day = [10587.6,10062.5,1275.7]
first_weekend=[36224.9,34479.6,11830]
数据来源: https://piaofang.maoyan.com/?ver=normal
效果如下:
3.2 分析
- 添加首日首周两部分的柱状图
- x轴中文坐标位置调整
代码:
# 三部电影的首日和首周票房对比
plt.figure(figsize=(20, 8), dpi=80)
movie_name = ['雷神3:诸神黄昏','正义联盟','寻梦环游记']
first_day = [10587.6,10062.5,1275.7]
first_weekend=[36224.9,34479.6,11830]
x = range(len(movie_name))
# 画出柱状图
plt.bar(x, first_day, width=0.2, label="首日票房")
# 首周柱状图显示的位置在首日的位置右边
plt.bar([i+0.2 for i in x], first_weekend, width=0.2, label="首周票房")
# 显示X轴中文,固定在首日和首周的中间位置
plt.xticks([i+0.1 for i in x], movie_name)
plt.legend(loc='best')
plt.show()
三、柱状图应用场景
适合用在分类数据对比场景上
- 数量统计
- 用户数量对比分析
直方图
学习目标
- 目标
- 应用hist实现直方图的绘制
- 知道直方图图的应用场景
-
应用
电影时长分布
一、直方图(Histogram)介绍
直方图,形状类似柱状图却有着与柱状图完全不同的含义。直方图牵涉统计学的概念,首先要对数据进行分组,然后统计每个分组内数据元的数量。 在坐标系中,横轴标出每个组的端点,纵轴表示频数,每个矩形的高代表对应的频数,称这样的统计图为频数分布直方图。
相关概念:
- 组数:在统计数据时,我们把数据按照不同的范围分成几个组,分成的组的个数称为组数
- 组距:每一组两个端点的差
二、电影时长分布绘制
现有250部电影的时长,希望统计出这些电影时长的分布状态(比如时长为100分钟到120分钟电影的数量,出现的频率)等信息,你应该如何呈现这些数据?
数据:
time =[131, 98, 125, 131, 124, 139, 131, 117, 128, 108, 135, 138, 131, 102, 107, 114, 119, 128, 121, 142, 127, 130, 124, 101, 110, 116, 117, 110, 128, 128, 115, 99, 136, 126, 134, 95, 138, 117, 111,78, 132, 124, 113, 150, 110, 117, 86, 95, 144, 105, 126, 130,126, 130, 126, 116, 123, 106, 112, 138, 123, 86, 101, 99, 136,123, 117, 119, 105, 137, 123, 128, 125, 104, 109, 134, 125, 127,105, 120, 107, 129, 116, 108, 132, 103, 136, 118, 102, 120, 114,105, 115, 132, 145, 119, 121, 112, 139, 125, 138, 109, 132, 134,156, 106, 117, 127, 144, 139, 139, 119, 140, 83, 110, 102,123,107, 143, 115, 136, 118, 139, 123, 112, 118, 125, 109, 119, 133,112, 114, 122, 109, 106, 123, 116, 131, 127, 115, 118, 112, 135,115, 146, 137, 116, 103, 144, 83, 123, 111, 110, 111, 100, 154,136, 100, 118, 119, 133, 134, 106, 129, 126, 110, 111, 109, 141,120, 117, 106, 149, 122, 122, 110, 118, 127, 121, 114, 125, 126,114, 140, 103, 130, 141, 117, 106, 114, 121, 114, 133, 137, 92,121, 112, 146, 97, 137, 105, 98, 117, 112, 81, 97, 139, 113,134, 106, 144, 110, 137, 137, 111, 104, 117, 100, 111, 101, 110,105, 129, 137, 112, 120, 113, 133, 112, 83, 94, 146, 133, 101,131, 116, 111, 84, 137, 115, 122, 106, 144, 109, 123, 116, 111,111, 133, 150]
效果:
1、matplotlib.pyplot.hist(x, bins=None, normed=None, **kwargs)
直方图绘制
Parameters:
x : (n,) array or sequence of (n,) arrays
bins : integer or sequence or ‘auto’, optional
组距
normed : bool, optional
以频率显示或者以頻数显示,默认頻数,值1为频率
2、分析
- 设置组距
- 设置组数(通常对于数据较少的情况,分为5~12组,数据较多,更换图形显示方式)
- 通常设置组数会有相应公式:组数 = 极差/组距= (max-min)/bins
代码:
# 展现不同电影的时长分布状态
plt.figure(figsize=(20, 8), dpi=100)
# 准备时长数据
time =[131, 98, 125, 131, 124, 139, 131, 117, 128, 108, 135, 138, 131, 102, 107, 114, 119, 128, 121, 142, 127, 130, 124, 101, 110, 116, 117, 110, 128, 128, 115, 99, 136, 126, 134, 95, 138, 117, 111,78, 132, 124, 113, 150, 110, 117, 86, 95, 144, 105, 126, 130,126, 130, 126, 116, 123, 106, 112, 138, 123, 86, 101, 99, 136,123, 117, 119, 105, 137, 123, 128, 125, 104, 109, 134, 125, 127,105, 120, 107, 129, 116, 108, 132, 103, 136, 118, 102, 120, 114,105, 115, 132, 145, 119, 121, 112, 139, 125, 138, 109, 132, 134,156, 106, 117, 127, 144, 139, 139, 119, 140, 83, 110, 102,123,107, 143, 115, 136, 118, 139, 123, 112, 118, 125, 109, 119, 133,112, 114, 122, 109, 106, 123, 116, 131, 127, 115, 118, 112, 135,115, 146, 137, 116, 103, 144, 83, 123, 111, 110, 111, 100, 154,136, 100, 118, 119, 133, 134, 106, 129, 126, 110, 111, 109, 141,120, 117, 106, 149, 122, 122, 110, 118, 127, 121, 114, 125, 126,114, 140, 103, 130, 141, 117, 106, 114, 121, 114, 133, 137, 92,121, 112, 146, 97, 137, 105, 98, 117, 112, 81, 97, 139, 113,134, 106, 144, 110, 137, 137, 111, 104, 117, 100, 111, 101, 110,105, 129, 137, 112, 120, 113, 133, 112, 83, 94, 146, 133, 101,131, 116, 111, 84, 137,