数据可视化何其多,除了Tableau,ECharts,Matplotlib也是神器之一,将枯燥无味的数据形象直观地展示出来,是很有成就感的事情。Matplotlib作为数据科学的的必备库,算得上是python可视化领域的元老,更是很多高级可视化库的底层基础,其重要性不言而喻。本文主要学习的是matplotlib.pyplot的可视化应用
matplotlib.pyplot是一个命令型函数集合,它可以让人们像使用MATLAB一样使用matplotlib。在matplotlib.pyplot库中有plt子库,该子库提供了7个用于读取和显示的函数,17个用于绘制基础图表的函数、3个区域填充函数、9个坐标轴设置函数以及11个标签与文本设置函数,具体如下表1-1~1-5所示:
函数名称 | 函数作用 |
---|---|
plt.legend( ) | 在绘图区域放置绘图标签 |
plt.show( ) | 显示绘制的图像 |
plt.matshow( ) | 在窗口中显示数组矩阵 |
plt.imshow( ) | 在axes上显示图像 |
plt.imsave( ) | 保存数组为图像 |
plt.savefig( ) | 设置图像保存的格式 |
plt.imread( ) | 从图像文件中读取数组 |
函数名称 函数作用 | |
---|---|
plt. plot(x,y,label,color,width) | 根据(x,y)数组绘制直、曲线 |
plt. box(data,notch,position) | 绘制一个箱型图 |
plt. bar(left,height,width,bottom) | 绘制一个条形图 |
plt. barh(bottom,width,height,left) | 绘制一个横向条形图 |
plt. polar(theta,r) | 绘制极坐标图 |
plt. pie(data,exxplode) | 绘制饼图 |
plt. psd(x,NFFT=256,pad_to,F) | 绘制功率谱密度图 |
plt. specgram(x,NFFT=256,Fs) | 绘制谱图 |
plt. cohere(x,y,NFFT=256,Fs) | 绘制X-Y的相关性函数 |
plt. scatter( ) | 绘制散点图 |
plt. step(x,y,where) | 绘制步阶图 |
plt. hist(x,bins,normed) | 绘制直方图 |
plt. contour(X,Y,Z,N) | 绘制等值线 |
plt. clines( ) | 就只垂直线 |
plt. stem(x,y,linefmt,markerfmt,basefmt) | 绘制曲线中每个点到水平轴线的垂线 |
plt. plot_date( ) | 绘制数据日期 |
plt. plotfile( ) | 绘制数据后写入文件 |
函数名称 | 函数作用 |
---|---|
fill(x,y,c,color) | 填充多边形 |
fill_between(x,y1,y2,where,color) | 填充曲线围成的多边形 |
fill_betweenx(y,x1,x2,where,hold) | 填充水平线之间的区域 |
函数名称 | 函数作用 |
---|---|
plt. axis( ) | 获取设置轴属性的快捷键 |
plt. xlim( ) | 设置X轴的取值范围 |
plt. ylim( ) | 设置Y轴的取值范围 |
plt. xscale( ) | 设置X轴缩放 |
plt. yscale( ) | 设置Y轴缩放 |
plt. autoscale( ) | 自动缩放轴视图 |
plt. text( ) | 为axes图添加注释 |
plt. thetagrids( ) | 设置极坐标网络 |
plt. grid( ) | 网格显示 |
函数名称 | 函数作用 |
---|---|
plt. figlegend( ) | 为全局绘图区域放置图注 |
plt. xlabel( ) | 设置当前X轴的文字 |
plt. ylabel( ) | 设置当前Y轴的文字 |
plt. xticks( ) | 设置当前X轴刻度位置的文字和值 |
plt. yticks( ) | 设置当前Y轴刻度位置的文字和值 |
plt. clabel( ) | 设置等高线数据 |
plt. get_figlabels( ) | 返回当前绘图区域的标签列表 |
plt. figtext( ) | 为全局绘图区域添加文本信息 |
plt. title( ) | 设置标题 |
plt. suptitle( ) | 设置总标题 |
plt. annotate( ) | 为文本添加注释 |
注意:均可通过help()命令查看API,用到什么查什么。
补充:
绘图接口有2种形式,分别是面向"当前"图的plt接口和面向对象接口,在这2种方式的相应接口中,多数接口名是一致的,例如:plt.plot()和axes.plot()、plt.legend()和axes.legend(),但也有一些不一致的接口:
plt.axes()——fig.add_axes()
plt.subplot()——fig.add_subplot()
plt.GridSped()——fig.add_gridspec()
plt.xlabel()——axes.set_xlabel()
plt.ylabel()——axes.set_ylabel()
plt.xlim()——axes.set_xlim()
plt.ylim()——axes.set_ylim()
plt.title()——axes.set_title()
对此,一方面两类接口虽然略有区别,但也还算有规律;另一方面,在面向对象绘图配置图例时,有更为便捷的设置图例接口axes.set(),其可以接收多种参数一次性完成所有配置,这也正是面向对象绘图的强大之处。
1、解决中文乱码,防止方块化
plt.rcParams["font.sans-serif"]="SimHei"
2、解决负号不能正常显示的问题
plt.rcParams["axes.unicode_minus"]=False
3、在jupyter notebook上面显示图片
%matplotlib inline
4、作图使用svg格式显示更为清晰
%config InlineBackend.figure_format="svg"
5、设置画布
plt.figure() 创建一个全局绘图区域
参数:
num:设置图像编号
figsize:设置图像的宽度和高度,单位为英寸
facecolor:设置图像的背景颜色
dpi:设置绘图对象的分辨率
edgecplor:设置图像的边框颜色
6、创建子图
fig=plt.figure()
fig.add_subplot(3,2,2) #3X2的第2个图形
或者plt.subplot(3,2,2) #3X2的第2个图形
下面将介绍几种较为常用的图表:柱状图、饼图、折线图、散点图、气泡图/云图、雷达图。
柱状图也叫条形图,是一种以长方形的长度为变量来表达图形的统计报告图,它由一系列高度不等的纵向条纹表示数据分布的情况,用来比较两个或两个以上的数值。
它适用于二维数据集,并且该数据集只需要(或者说“只能”更准确一些)比较其中一个维度。实现比较的手段就是利用柱状体之间的高度差来反映数据差异,因为人的肉眼对于高度的辨识度是较高的。但是,当数据集的规模太过庞大时,柱状体太多也会在所难免的没有那么方便地进行比较了,所以柱状图一般只适用于中小规模的数据集。
柱状图实际上是用来表示分组(或离散)变量的可视化
API:
bar(x, height, width=0.8, bottom=None, *, align='center', data=None, **kwargs)
参数 | 说明 | 类型 |
---|---|---|
x | x坐标 | int,float |
height | 条形的高度 | int,float |
width | 宽度 | 0~1,默认0.8 |
botton | 条形的起始位置 | 也是y轴的起始坐标 |
align | 条形的中心位置 | “center”,"edge"边缘 |
color | 条形的颜色 | “r",“b”,“g”,"#123465",默认“b" |
edgecolor | 边框的颜色 | 同上 |
linewidth | 边框的宽度 | 像素,默认无,int |
tick_label | 下标的标签 | 可以是元组类型的字符组合 |
log | y轴使用科学计算法表示 | bool |
orientation | 是竖直条还是水平条 | 竖直:“vertical”,水平条:“horizontal” |
示例:
import numpy as np
import matplotlib.pyplot as plt
size = 5
a = np.random.random(size)
b = np.random.random(size)
c = np.random.random(size)
d = np.random.random(size)
x = np.arange(size)
total_width, n = 0.8, 3 # 有多少个类型,只需更改n即可
width = total_width / n
x = x - (total_width - width) / 2
plt.bar(x, a, width=width, label='a')
plt.bar(x + width, b, width=width, label='b')
plt.bar(x + 2 * width, c, width=width, label='c')
plt.legend()
plt.show()
结果展示:
水平条形图
绘制方法一:使用plt.bar()
还用上的数据,参数orientation默认是’vertical’垂直,改为"horizontal"(水平)。
注意:
1、x的起始位置,水平条底部,以及长度的取值变化
2、添加标签的时候enumerate()函数遍历出的结果(自动加序号),以及text()函数的参数。
示例:
import numpy as np
import matplotlib.pyplot as plt
size = 5
a = np.random.random(size)
b = np.random.random(size)
c = np.random.random(size)
d = np.random.random(size)
x = np.arange(size)
total_width, n = 0.8, 3 # 有多少个类型,只需更改n即可
width = total_width / n
x = x - (total_width - width) / 2
plt.bar(0,bottom=x,height=width,width=a, label='a',orientation="horizontal")
plt.bar(0,bottom=x+width,height=width,width=b,label='b',orientation="horizontal")
plt.bar(0,bottom=x+2*width,height=width,width=c,label='c',orientation="horizontal")
plt.legend()
plt.show()
结果展示:
绘制方法二:使用plt.barh()
barh(y, width, height=0.8, left=None, *, align='center', **kwargs)
还用上的数据,参数orientation为"horizontal"(水平)。
示例:
import numpy as np
import matplotlib.pyplot as plt
size = 5
a = np.random.random(size)
b = np.random.random(size)
c = np.random.random(size)
d = np.random.random(size)
x = np.arange(size)
total_width, n = 0.8, 3 # 有多少个类型,只需更改n即可
width = total_width / n
x = x - (total_width - width) / 2
plt.barh(x, left=0,height=width,width=a,orientation="horizontal",alpha = 0.8)
plt.barh(x+width, left=0,height=width,width=b,orientation="horizontal",alpha = 0.8)
plt.barh(x+2*width, left=0,height=width,width=c,orientation="horizontal",alpha = 0.8)
plt.legend()
plt.show()
结果展示:
在折线图中,我们通常更关注于每条折线的走势(或者说“更能看出数据的走向”,所以它适用于整体趋势比单个数据点更重要的二维数据集。而正因为它关心的是整体而非个别的点,所以当数据集的规模越大时,折线图所呈现的整体会更加的准确。每个数据集在折线图中仅表现为一条折线,这使得它可以同时承载多个数据集并提供比较。
API:
plt.plot(x,y,linestyle,linewidth,color,marker,markersize,markeredgecolor,markerfactcolor,label,alpha)
参数:
x,y:指定折线图的x轴/y轴的数据;
linestyle:指定折线的类型,可以是实线、虚线、点虚线等,默认文实线;
linewidth:指定折线的宽度
marker:设置点的形状
markersize:设置点的大小
markeredgecolor:设置点的边框色
markerfactcolor:设置点的填充色
label:为折线图添加标签
常用的marker风格:
“+”:十字 “O”:圆圈
“*”:星型 “s”:正方形
“p”:五边形 “h”:六边形
“d”:小菱形 “D”:钻石
常用的color风格:
“b”:blue蓝色 “g”:green绿色
“k”:黑色 “w”:white白色
“r”:red红色 “y”:yellow黄色
“c”:cyan青色 “m”:magenta品红
示例:
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(10,6))
x = np.arange(-2*np.pi,2*np.pi,0.01)
#x = np.arange(-2*np.pi,2*np.pi,0.01)
x1 = np.arange(-2*np.pi,2*np.pi,0.2)
y1 = np.sin(3*x1)/x1
y2 = np.sin(2*x)/x
y3 = np.sin(x)/x
plt.plot(x1,y1,c='b',linestyle='--',marker='^',label="y1=sin(3*x1)/x1")#linestyle设置线的风格,marker设置点的风格
plt.plot(x,y2,c='r',linestyle='-.',label="y2=sin(2*x)/x")
plt.plot(x,y3,c='g',label="y3=sin(x)/x")
plt.legend()
plt.show()
结果展示:
饼图是一种经常被人们避免使用的图表,因为人眼对面积的辨识度没有像对高度那样那么高,所以利用面积去反映数据起不到很好的作用。但是,存在即合理,当我们想要去强调某个部分占整体的比重时,用饼图是再适合不过了。
饼图用于表示不同分类的占比情况,通过弧度大小来对比各种分类。饼图将一个圆饼按照分类的占比划分成多个区块,整个圆饼代表数据的总量,每个区块(圆弧)表示该分类占总体的比例大小。
API:
pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=None, radius=None, counterclock=True, wedgeprops=None, textprops=None, center=(0, 0), frame=False, rotatelabels=False, *, data=None)
参数:
x:指定绘图的数据;
explode:指定饼图某些部分的突出显示,即呈现爆炸式;
labels:为饼图添加标签说明,类似于图例说明;
colors:指定饼图的填充色;
autopct:自动添加百分比显示,可以采用格式化的方法显示;
pctdistance:设置百分比标签与圆心的距离;
shadow:是否添加饼图的阴影效果;
labeldistance:设置各扇形标签(图例)与圆心的距离;
startangle:设置饼图的初始摆放角度;
radius:设置饼图的半径大小;
counterclock:是否让饼图按逆时针顺序呈现;
wedgeprops:设置饼图内外边界的属性,如边界线的粗细、颜色等;
textprops:设置饼图中文本的属性,如字体大小、颜色等;
center:指定饼图的中心点位置,默认为原点
frame:是否要显示饼图背后的图框,如果设置为True的话,需要同时控制图框x轴、y轴的范围和饼图的中心位置;
示例:
import matplotlib.pyplot as plt
labels = 'A', 'B', 'C', 'D'
fracs = [15, 30.55, 44.44, 10]
color = 'blue','red','yellow','green'
explode = [0, 0.1, 0, 0] # 0.1 凸出这部分,
plt.pie(x=fracs,explode=explode, # 突出分裂的部分
labels=labels, # 添加分类标签
colors=color, # 设置饼图的自定义填充色
autopct='%.1f%%', # 设置百分比的格式,这里保留一位小数
pctdistance=0.6, # 设置百分比标签与圆心的距离
labeldistance = 1.15, # 设置各标签与圆心的距离
startangle = 180, # 设置饼图的初始角度
radius = 1, # 设置饼图的半径
counterclock = False, # 是否逆时针,这里设置为顺时针方向
wedgeprops = {
'linewidth': 1.3, 'edgecolor':'green'},# 设置饼图内外边界的属性值
textprops = {
'fontsize':15, 'color':'k'}, # 设置文本标签的属性值
center = (0.5,0.5), # 设置饼图的原点
frame = 0 )# 是否显示饼图的图框,这里设置显示
plt.show()
结果展示:
散点图在回归分析中的使用较多,他将序列显示为一组点。值点在图标表中的位置表示,类别由图表中的不同标记表示,所以散点图通常用于比较跨类别的聚合数据。
散点图正是用来寻找数据集维度间的相互关系的。如果数据集规模足够大并且维度间可能并不存在关系,我们依然可以通过散点图来总结数据点的分布模式,得到有用的信息。
API:
scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, verts=None, edgecolors=None, *, data=None, **kwargs)
常用参数解释:
x,y:表示即将绘制散点图的数据点
s:是一个可选的参数。
c:表示的是颜色,也是一个可选项。
marker:表示的是标记的样式,默认的是'o'。
alpha:实数,0-1之间。
示例:
#导入必要的模块
import numpy as np
import matplotlib.pyplot as plt
#产生测试数据
x = np.arange(1,10)
y = x
fig = plt.figure()
ax1 = fig.add_subplot(111)
#设置标题
ax1.set_title('Scatter Plot')
#设置X轴标签
plt.xlabel('X')
#设置Y轴标签
plt.ylabel('Y')
#画散点图
ax1.scatter(x,y,c = 'r',marker = 'o')
#设置图标
plt.legend('x1')
#显示所画的图
plt.show()
结果展示:
气泡图是二维图表展示三维(或者四维)数据集的典范,通常被看做散点图的变种。它利用点的面积来表示第三维的数值。但是,前面提到过,人眼对面积的辨识度并不高,所以气泡图只能用于对第三维的展现不做精确要求的场景。
示例:
import numpy as np
import matplotlib.pyplot as plt
x=np.random.rand(50)
y=np.random.rand(50)
colors=np.random.rand(50) #颜色随机
area=(50*np.random.rand(50))**2 #散点的大小随机
fig=plt.figure(figsize=(10,5))
plt.subplot(1,1,1)
plt.scatter(x,y,s=area,marker="o",c=colors)
#设置标题
plt.title("plot of scatter for x to y",fontdict={
'fontsize':20,'color':'blue'},loc='center')
# 设置x轴和y轴的轴标题
plt.xlabel("x for x in range(50)",fontdict={
'fontsize':10,'color':'blue'})
plt.ylabel("y for y in range(50)",fontdict={
'fontsize':10,'color':'blue'})
# 添加图例
# plt.legend('xfory')
# 添加数字标签
for a,b in zip(x,y):
plt.text(round(a,2),round(b,2),round(b,2),ha="center",va='top',fontdict={
'fontsize':7,'color':'black'})
plt.xlim(0,1) #x轴的坐标轴取值范围
# 给坐标A添加标注A(x10,y10)
plt.annotate("A(x,y)",xy=(x[10],y[10]),fontsize=15)
plt.show()
结果展示:
直方图又称质量分布图,是一种统计报告图。它由一系列高度不等的纵向条纹或线段表示数据分布的情况,一般用横轴表示数据类型,用纵轴表示分布情况。
API:
hist(x, bins=None, range=None, density=None, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, color=None, label=None, stacked=False)
参数:
x:指定要绘制直方图的数据;
bins:指定直方图条形的个数;
range:指定直方图数据的上下界,默认包含绘图数据的最大值和最小值;
normed:是否将直方图的频数转换成频率;
weights:该参数可为每一个数据点设置权重;
cumulative:是否需要计算累计频数或频率;
bottom:可以为直方图的每个条形添加基准线,默认为0;
histtype:指定直方图的类型,默认为bar,除此还有’barstacked’,‘step’, ‘stepfilled’;
align:设置条形边界值的对其方式,默认为mid,除此还有’left’和’right’;
orientation:设置直方图的摆放方向,默认为垂直方向;
rwidth:设置直方图条形宽度的百分比;
log:是否需要对绘图数据进行log变换;
color:设置直方图的填充色;
label:设置直方图的标签,可通过legend展示其图例;
stacked:当有多个数据时,是否需要将直方图呈堆叠摆放,默认水平摆放;
示例:
#电影时长分布分析(直方图)
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
import matplotlib
plt.rcParams['font.sans-serif'] = ['KaiTi'] # 显示中文
x = [194,110,109,104,48,60,127,41,196,74,116,123,169,60,86,87,60,60,60,105,60,112,60,120,60,60,60,238,128,7,280,180,87,122,18,60,60,60,12,92,60,
127,115,60,121,115,60,60,60,119]
plt.figure()
plt.hist(x,50,histtype='bar',label='电影时长',facecolor='red',alpha=0.75)
plt.title('电影时长分布分析')
plt.legend()
plt.show()
雷达图可以用来表示多维(四维以上)的数据集,并且数据集的每个维度都必须是可以排序的。但它所能承载的数据点是非常有限的,当数据点过多时,并不利用数据点之间的比较。
示例:
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['KaiTi'] # 显示中文
results = [{
"大学英语": 87, "高等数学": 79, "体育": 95, "计算机基础": 92, "程序设计": 85},
{
"大学英语": 80, "高等数学": 90, "体育": 91, "计算机基础": 85, "程序设计": 88}]
data_length = len(results[0])
# 将极坐标根据数据长度进行等分
angles = np.linspace(0, 2*np.pi, data_length, endpoint=False)
labels = [key for key in results[0].keys()]
score = [[v for v in result.values()] for result in results]
#为了使雷达图一圈封闭起来,需要下面的步骤
# 使雷达图数据封闭
score_a = np.concatenate((score[0], [score[0][0]]))
score_b = np.concatenate((score[1], [score[1][0]]))
angles = np.concatenate((angles, [angles[0]]))
labels = np.concatenate((labels, [labels[0]]))
# 设置图形的大小
fig = plt.figure(figsize=(8, 6), dpi=100)
# 新建一个子图 这里一定要设置为极坐标格式
ax = plt.subplot(111, polar=True)
# 绘制折线图 /绘制雷达图
ax.plot(angles, score_a, color='g')
ax.plot(angles, score_b, color='b')
# 添加每个特征的标签
ax.set_thetagrids(angles*180/np.pi, labels)
# 设置雷达图的0度起始位置
ax.set_theta_zero_location('N')
# 设置雷达图的坐标刻度范围
ax.set_rlim(0, 100)
# 设置雷达图的坐标值显示角度,相对于起始角度的偏移量
ax.set_rlabel_position(270)
ax.set_title("成绩情况分析")
plt.legend(["小明", "小红"], loc='best')
plt.show()
结果展示: