데이터 분석-04: Matplotlib
一、Matplotlib介绍与安装
1、Matplotlib的介绍
1.什么是Matplotlib
- Matplotlib是一个Python的基础绘图库,它可与 NumPy 一起使用,代替Matlab使用。
2.为什么学习Matplotlib
- 将数据进行可视化,使数据更直观
- 使数据更加更具有说服力
2、Matplotlib安装
- 由于Matplotlib是第三方库,所以我们需要安装它才可以使用。注意,Matplotlib3.0要求python3版本才可安装使用。
- 安装命令:pip install matplotlib
- 安装参考官网:https://matplotlib.org/users/installing.html
二、Matplotlib绘图
1、图片与子图
- Matplotlib所绘制的图位于图片(Figure)对象中。我们可以通过plt.figure生成一个新的图片:
from matplotlib import pyplot as plt
fig = plt.figure()
注意:在IPython中,执行该代码一个空白的绘图窗口就会出现,但在Jupyter中则没有任何显示
但是可以通过plt.subplot创建一个或多个子图。
如:带有四个子图的Matplotlib图片
除此之外,Matplotlib包含一个便捷方法plt.subplots创建一个新的图片,然后返回包含了已生成子图对象的Numpy数组。
plt.subplots(nrows, ncols, sharex, sharey)
nrows
子图的行数ncols
子图的列数sharex
所有子图使用相同的x轴刻度sharey
所有子图使用相同的y轴刻度
那实际上,当我们不需要使用子图时,可以通过plt对象直接绘制图形。
2、Matplotlib绘制图形
- matplotlib能够绘制折线图,散点图,条形图,直方图,饼图等等。
- 具体可参考:https://matplotlib.org/gallery/index.html
1.折线图
1.折线图介绍
- 折线图以折线的上升或下降来表示统计数量的增减变化的统计图
- 特点:
- 能够显示数据的变化趋势,反应食物的变化情况。
- 能够显示数据的变化趋势,反应食物的变化情况。
2.折线图绘制
折线图可以通过plot()函数来绘制
plt.plot(x, y)
# 使用默认的线样式及颜色绘制x,y构建的图形
演示代码一
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# -实线
# --虚线
# .点
# 0圆点
# ^上三角
# >右三角
#
plt.plot(range(10), [np.random.randint(0, 10) for i in range(10)])
plt.plot(range(10), [np.random.randint(0, 10) for i in range(10)], 'r--')
plt.plot(range(10), [np.random.randint(0, 10) for i in range(10)], color=(0,0,0))
plt.plot(range(10), [np.random.randint(0, 10) for i in range(10)], color='#000000')
plt.show()
演示代码二
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 加载字体.................................................................................................
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
# 显示负号
plt.rcParams['axes.unicode_minus'] = False
# 设置图表标题
plt.title('标题')
# 设置轴标题
plt.plot(range(10), [np.random.randint(0, 10) for i in range(10)], 'r-')
# plt.xlabel('X轴', fontdict={'family': 'SimHei', 'size': 16})
plt.xlabel('X轴')
plt.ylabel('Y轴')
# 自定义刻度
_xticks = ['%d点'%i for i in range(10)]
plt.xticks(range(10), _xticks)
plt.show()
演示代码三
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 加载字体.................................................................................................
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
# 显示负号
plt.rcParams['axes.unicode_minus'] = False
avenger = [17974.4,50918.4,30033.0,40329.1,52330.2,19833.3,11902.0,24322.6,47521.8,32262.0,22841.9,12938.7,4835.1,3118.1,2570.9,2267.9,1902.8,2548.9,5046.6,3600.8]
plt.figure(figsize=(15,5))
plt.plot(avenger,marker="*",markerfacecolor='k',markersize=20)
plt.xticks(range(20),["第%d天"%x for x in range(1,21)],fontproperties='SimHei',size=16,rotation=45)
plt.xlabel('天数',fontdict={'family':'SimHei','size':16})
plt.ylabel('票房数(万)',fontdict={'family':'SimHei','size':16})
plt.grid() # 网格背景
plt.show()
演示代码四
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 加载字体.................................................................................................
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
# 显示负号
plt.rcParams['axes.unicode_minus'] = False
avenger = [17974.4,50918.4,30033.0,40329.1,52330.2,19833.3,11902.0,24322.6,47521.8,32262.0,22841.9,12938.7,4835.1,3118.1,2570.9,2267.9,1902.8,2548.9,5046.6,3600.8]
plt.figure(figsize=(15,5))
plt.plot(avenger,marker="*",markerfacecolor='k',markersize=20)
plt.xticks(range(20),["第%d天"%x for x in range(1,21)],fontproperties='SimHei',size=16,rotation=45)
plt.xlabel('天数',fontdict={'family':'SimHei','size':16})
plt.ylabel('票房数(万)',fontdict={'family':'SimHei','size':16})
plt.grid() # 网格背景
plt.show()
3.实例
数据如下,绘制折线图形
- x = [1,2,3,4]
- y = [2,3,1,2]
import matplotlib.pyplot as plt
x = [1,2,3,4]
y = [2,3,1,2]
plt.plot(x,y)
plt.show()
以上实例,x数组对应图形x轴的值,y数组对应图形y轴的值,并且通过plt.plot()
绘制之后,通过plt.show()
展示图片,释放内存。
并且,plt.plot()函数除了传入制图数据,还可以设置线的颜色等。
- color 设置线的颜色
- linestyle 设置线的样式
- marker 标记样式
代码如下:
import matplotlib.pyplot as plt
x = [1,2,3,4]
y = [2,3,1,2]
plt.plot(x,y,color="g",linestyle="--")
plt.show()
效果如下
plt.plot()参数使用具体可参考:
https://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.plot.html#matplotlib.axes.Axes.plot
4.图形组成
- 实际上,图形的组成除了x、y轴。还有很多组件。
方法 | 描述 |
---|---|
plt.figure(figsize=None,dpi=None) | 生成新的图片,figsize:图片大小,dpi:透明度 |
plt.savefig(fname) | 保存图片 |
plt.xticks(ticks=None) | 设置x轴刻度的值 |
plt.yticks(ticks=None) | 设置y轴刻度的值 |
plt.xlabel(xlabel) | 设置x轴标签 |
plt.ylabel(ylabel) | 设置y轴标签 |
plt.title() | 设置图标题 |
plt.grid() | 根据x轴和y轴的数值展示轴网格 |
5.中文显示问题
当我们需要设置标签、标题等,通常会使用到中文。但是,matplotlib默认不显示中文,如图:
方法一
import matplotlib
font = {
'family':'SimHei',
'weight':'bold',
'size':12
}
matplotlib.rc("font", **font)
方法二
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 步骤一(替换sans-serif字体)
plt.rcParams['axes.unicode_minus'] = False # 步骤二(解决坐标轴负数的负号显示问题)
方法三
from matplotlib import pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=14)
x = [1,2,3,4]
y = [3,2,1,3]
plt.plot(x,y)
plt.xlabel("x轴标签",fontproperties=font)
plt.show()
方法五(MacOS系统)
import matplotlib.pyplot as plt
# 更改字体 macOS系统专用
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
6.添加注释文本
plt.annotate()
基本使用text
是注释的文本xy
是需要注释的点的坐标xytext
是注释文本的坐标arrowprops
是箭头的样式属性
2.散点图
1.散点图介绍
- 散点图用两组数据构成多个坐标点,考察坐标点的分布,判断两变量之间是否存在某种关系或总结坐标点的分布模式。
- 特点:判断变量之间是否存在数量关联趋势,表示离群点(分布规律)。
4.散点图绘制
- 散点图通过
plt.scatter()
函数绘制 plt.scatter(x,y)
# 以默认的形状颜色等绘制散点图
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 加载字体.................................................................................................
plt.rcParams['font.sans-serif'] = ['S imHei'] # 指定默认字体
# 显示负号
plt.rcParams['axes.unicode_minus'] = False
x = np.random.rand(20)
y = np.random.rand(20)
# 随机的大小
# s = (30*np.random.rand(10))**2
x1 = np.random.rand(10)
y1 = np.random.rand(10)
plt.scatter(x,y,alpha=0.5,marker='^',c='r',label="三角")
plt.scatter(x1,y1,alpha=0.5,marker='*',c='b',label="五角")
# 图例
plt.legend()
plt.show()
3.条形图
1.条形图介绍
- 条形图是用宽度相同的天性的高度或长短来表示数据多少的图形。条形图可以横置或纵置,纵置时也成为柱形图。
特点:
1.能够使人们一眼看出各个数据的大小。
2.易于比较数据之间的差别。
2.条形图绘制
条形图通过bar()
函数绘制
plt.bar(x, height)
# 绘制以x为x轴位置,height为y轴位置的竖条形图
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 加载字体.................................................................................................
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
# 显示负号
plt.rcParams['axes.unicode_minus'] = False
# 条形图
# 构造数据
GDP = [12406.8, 13908.57, 9386.87, 8143.64]
# 绘图
plt.bar(range(4), GDP, width=0.5, alpha=0.5)
# width=0.5表示柱子的宽度
# alpha=0.5表示透明度
# 标签
plt.xlabel('城市')
plt.ylabel('GDP')
# 刻度设置
plt.xticks(range(4), ['北京', '上海', '深圳', '广州'])
# 设置Y轴刻度范围
plt.ylim([5000, 15000])
# # 表格标题
plt.title('四个城市的GDP比拼')
# # 为每个条形添加对应的数据
for x, y in enumerate(GDP):
print(x, y)
plt.text(x, y+200, '%s'%(y), ha='center')
plt.show()
3.水平条形图绘制
水平条形图通过barh()
函数绘制
plt.barh(y, width)
# 绘制以y为y轴位置,width为y轴位置的水平条形图
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 加载字体.................................................................................................
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
# 显示负号
plt.rcParams['axes.unicode_minus'] = False
# 横向条形图
# 构造数据
GDP = [12406.8, 13908.57, 9386.87, 8143.64]
# 绘图
plt.barh(range(4), GDP, height=0.5, alpha=0.5)
# width=0.5表示柱子的宽度
# alpha=0.5表示透明度
# 标签
plt.ylabel('城市')
plt.xlabel('GDP')
# 刻度设置
plt.yticks(range(4), ['北京', '上海', '深圳', '广州'])
# 设置Y轴刻度范围
plt.xlim([5000, 15000])
# 表格标题
plt.title('四个城市的GDP比拼')
for x, y in enumerate(GDP):
print(x, y)
plt.text(y+1,x, '%s'%(y))
plt.show()
4.直方图
1.直方图介绍
- 直方图由一系列高度不等的纵向条纹或线段表示数据分布的情况,一般用横轴表示数据范围,纵轴表示分布情况
特点:绘制连续性的数据,展示一组或者多组数据的分布情况(统计)
2.直方图绘制
- 直方图通过hist()函数绘制
plt.hist(x, bins=None)
# 绘制以x为数值,bins为组数- 组数 = 极差/组距
练习1
某地区连续50年中四月份平均气温数据如下:
temp_li= [6.9,4.1,6.6,5.2,6.4,7.9,8.6,3.0,4.4,6.7,7.1,4.7,9.1,6.8,8.6,5.2,5.8,7.9,5.6,8.8,8.1,5.7,8.4,4.1,6.4,6.2,5.2,6.8,5.6,5.6,6.8,8.2,6.4,4.8,6.9,7.1,9.7,6.4,7.3,6.8,7.1,4.8,5.8,6.5,5.9,7.3,5.5,7.4,6.2,7.7]
根据以上数据,推断该地区四月份平均气温的分布类型。
解析:样本中最小值a=3.0,最大值b=9.7。则分布区间[3,10]等分为7个小区间,区间长度为1,以下为样本值在各小区间的频数与评率。
练习2
绘制班级的身高分布图形
height = [160,163,175,180,176,177,168,189,188,177,174,170,173,181]
5.扇形图
1.扇形图介绍
- 扇形图,用整个圆表示总数,用圆内各个扇形的大小表示各部分数量占总数的百分数。
2.扇形图绘制
扇形图通过pie()函数绘制
-
plt.pie(x, explode=None, labels=None)
- x 扇形数据
- explode 设置某几个分块是否要分离饼图
- labels 每块扇形标签
- autopct 百分比数据标签
- shadow 是否显示阴影
-
plt.pie()
有3个返回值- patches 绘制饼图每一块的对象
- texts 文本的列表
- autotexts 百分比的文本列表
练习
将以下frac数据绘制扇形图,并且设置其扇形标签为label
frac = [1/50,6/50,11/50,15/50,9/50,6/50,2/50]
label = [’[3,4]’,’(4,5]’,’(5,6]’,’(6,7]’,’(7,8]’,’(8,9]’,’(9,10]’]
6.雷达图
1.雷达图介绍
- 雷达图(Radar Chart)又被叫做蜘蛛网图,适用于显示三个或更多的维度的变量的强弱情况。比如某个企业在哪些业务方面的投入等,都可以用雷达图方便的表示。
2.绘制雷达图
- 雷达图(Radar Chart)又被叫做蜘蛛网图,适用于显示三个或更多的维度的变量的强弱情况。比如某个企业在哪些业务方面的投入等,都可以用雷达图方便的表示。
实例
如下数据,进行绘制雷达图
quaters = ['Q1','Q2','Q3','Q4','Q5','Q6','Q7']
sales = [40,91,44,90,20,54,80]
注意:
- 因为polar并不会完成线条的闭合绘制,所以我们在绘制的时候需要在theta中和values中在最后多重复添加第0个位置的值,然后在绘制的时候就可以和第1个点进行闭合了。
- polar只是绘制线条,所以如果想要把里面进行颜色填充,那么需要调用fill函数来实现。
- polar默认的圆圈的坐标是角度,如果我们想要改成文字显示,那么可以通过xticks来设置。
7.箱型图
1.箱型图介绍
箱线图是一种直观简洁的方式去呈现一组数据的分布。 箱线图广泛用于各个数据分析领域,它能非常简单明了地显示一组数据中5个重要数值,并且还能发现一组数据中的存在的异常值。
- 最大值
- 最小值
- 中位数
- 下四分位数(Q1)
- 上四分位数(Q3)
2.箱型图绘制
Python当中可以使用Matplotlib当中的boxplot()绘制箱型图,绘制效果如下。
plt.boxplot()
- x:需要绘制的箱型图的数据
- notch:是否展示置信区间 默认为False
- sym:代表异常点的符号表示 默认为圆点
- vert:是否是垂直的 默认是True
- whis:上下限系数 默认为1.5
- positions:设置每个盒子的位置
- widths:设置每个盒子的宽度
- labels:每个盒子的label
- meanline和showmean:都为True的时候 会展示平均线
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
data = np.random.randint(1,100,size=100)
data = np.append(data,np.array([-100,300])) # 添加两个异常值
plt.boxplot(data,sym="^",widths=0.2,meanline=True,showmeans=True)
plt.show()
三、Matplotlib配置
1、Axes容器
1.Axes介绍
- Axes容器是用来创建具体的图形的。比如画曲线,柱状图,都是画在上面。所以之前我们学的使用plt.xx绘制各种图形(比如条形图,直方图,散点图等)都是对Axes的封装。
- 参考链接:https://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes
2.设置x轴与y轴的最大值与最小值
设置完刻度后,我们还可以设置x轴和y轴的最大值和最小值。可以通过set_xlim/set_ylim来实现:
from matplotlib import pyplot as plt
fig = plt.figure()
ax1 = plt.subplot(111)
ax1.plot(range(10),range(10))
ax1.set_xlim(-2,12)
ax1.set_xticks(range(10))
plt.show()
3.添加文本
之前添加文本我们用的是annotate,但是如果不是需要做注释,其实还有另外一种更加简单的方式,那就是使用text方法:
fig = plt.figure()
ax1 = plt.subplot(111)
ax1.plot(range(10),range(10),marker="o")
# 想在(0,0)的位置显示文本
ax1.text(0,0,"(0,0)")
plt.show()
4.绘制双y轴
- 绘制图1为: ax1
- 通过 ax2 = ax1.twinx() 克隆 ax1
- 绘制图2位: ax2
2、Axis容器
1.Axis介绍
- Axis代表的是x轴或者y轴的对象。包含Tick(刻度)对象,TickLabel刻度文本对象,以及AxisLabel坐标轴文本对象。axis对象有一些方法可以操作刻度和文本等。
- 参考链接:https://matplotlib.org/api/axis_api.html#matplotlib.axis.Axis
2.设置x轴与y轴label的位置
ax1.yaxis.set_label_coords(x,y)
3.设置刻度上的刻度格式
from matplotlib import ticker
formatter = ticker.FormatStrFormatter("自定义格式")
ax1.yaxis.set_major_formatter(formatter)
4.显示子刻度
ax1.minorticks_on()
5.多图布局
import matplotlib.pyplot as plt
fig,axes = plt.subplots(2,2)
axes[0,0].plot([1,2],[1,2])
axes[0,1].plot([1,2],[1,2])
axes[1,0].plot([1,2],[1,2])
axes[1,1].plot([1,2],[1,2])
axes[0,0].set_xlabel("x-label")
axes[0,0].set_ylabel("y-label")
axes[0,0].set_title("title")
axes[0,1].set_xlabel("x-label")
axes[0,1].set_ylabel("y-label")
axes[0,1].set_title("title")
axes[1,0].set_xlabel("x-label")
axes[1,0].set_ylabel("y-label")
axes[1,0].set_title("title")
axes[1,1].set_xlabel("x-label")
axes[1,1].set_ylabel("y-label")
axes[1,1].set_title("title")
plt.show()
6.调整子图间距
- 使用
fig.subplots_adjust(left=None,bottom=None,right=None,top=None, wspace=None,hspace=None)
- 使用
fig.tight_layout(h_pad=None,w_pad=None)
7.自定义布局
实现如下:
plt.figure()
ax1 = plt.subplot(221)
ax2 = plt.subplot(223)
ax3 = plt.subplot(122)
但是比较复杂的布局需要借助到 GridSpec对象,通过 fig.add_gridspec(2,2)
创建栅栏模式,再使用 fig.add_subplot 添加子图。
实现如下:
实际上,当我们需要调整子图比例时,仍然是使用
fig.add_gridspec(2,2,width_ratios=width,height_ratios=height)
四、Matplotlib绘制3D图
1、3D立体图形
- 之前,我们已经了解了如果使用 Matplotlib 中的 pyplot 模块绘制简单的 2D 图像。其实,Matplotlib 也可以绘制 3D 图像,与二维图像不同的是,绘制三维图像主要通过 mplot3d 模块实现。但是,使用 Matplotlib 绘制三维图像实际上是在二维画布上展示,所以一般绘制三维图像时,同样需要载入 pyplot 模块。
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
2、3D曲线图
from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
zline = np.linspace(0,15,1000)
xline = np.sin(zline)
yline = np.cos(zline)
fig = plt.figure()
ax = Axes3D(fig)
ax.plot(xline,yline,zline)
plt.show()
3、3D散点图
from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
x = np.random.rand(100)
y = np.random.rand(100)
z = np.random.rand(100)
fig = plt.figure()
ax = Axes3D(fig)
ax.scatter(x,y,z,s=10,color="r",marker='o')
plt.show()
4、3D平面图
x = [1,2,3,4]
y = [1,2,3,4]
X, Y = np.meshgrid(x, y)
# 创建画布
fig = plt.figure()
# 创建3D坐标系
ax = Axes3D(fig)
ax.plot_surface(X,
Y,
Z=X+Y
)
理解:np.meshgrid(x,y)