Python常用库——matplotlib
matplotlib是Python中的一个非常便捷的绘图包。在这一部分,将介绍三个方面的内容帮助大家入门学习:
- matplotlib绘图基础知识
- 常用图形的绘制方法
- 绘制图形的优化
由于图形的优化具有通用性,所以会在前面几种常用图形中展开介绍,不再单独讲解。
知识框架如下
1 matplotlib绘图的基础知识
1.1 库介绍
matplotlib库中有两个绘图包:pyplot和pylab。两种绘图方式的区别在于在import pylab时相当于同时import pyplot和numpy,从matplotlib官方文档看,pylab已被强烈劝退,而且由于是绘图工具包,掌握其中一种即可。在此也按照官方建议,仅介绍pyplot的内容。加载pyplot包的方法也比较简单
from matplotlib import pyplot as plt
1.2 绘图方式
在pyplot中也有着两种绘图方式:
- 创建图对象,并调用对象的方法进行绘图,可以理解为先告诉python要绘图了(创建图对象),然后把图表的元素补充进去
- 通过调用相应的函数直接绘图,可以理解为直接把图表元素告诉python,由python直接绘制成图表
两种绘图方法基本上是一致的,在日常的工作中掌握其中一种方法即可。在这里推荐第一种方法,因为第一种方法更灵活。举个例子,如果所画的图像中有多个图表,在前面绘制后发现有些子图需要调整的地方,则可以直接调用对应子图对象进行调整,而第二种方法,则需要先激活相应的图表,然后再修改,所以第一种方***更灵活。
在这里演示下两者的区别
from matplotlib import pyplot as plt import numpy as np import pandas as pd
使用创建图对象的方式进行绘图
fig,ax = plt.subplots() #创建一个figure图对象,并在图对象中设置一个绘图的区域 ax.plot([1,2,3,4],[5,6,7,8]) #绘图 plt.show() #展示相应的图形
绘制结果如下
使用plot函数直接绘图
plt.plot([1,2,3,4],[5,6,7,8]) #绘图 plt.show() #展示
绘图结果如下
可以发现两者的绘图结果是一样的。
1.3 绘图的数据
pyplot支持的数据格式有numpy中的数组,对于类似数组格式的输入数据(列表、元组、Series、DataFrame等)也可以接受。但是建议大家在绘图时将非数组格式的数据转换成数组进行绘图,避免出现意想不到的结果。
a_a = np.array([1,2,3,4]) a_l = [1,2,3,4] a_t = (1,2,3,4) a_s = pd.Series(a_a) a_d = pd.DataFrame(a_a)
在这里创建了5种数据类型,并对其进行绘图,可以发现,在前四种直接调用相应的绘图即可,不会出现什么问题,但是在对DataFrame直接进行绘图时就会报错,需要对DataFrame中的数据进行引用才可以绘图成功。
fig,ax = plt.subplots() ax.plot(a_s,a_s) plt.show()
可以自行尝试将上述ax.plot(a_s,a_s)中的变量替换为所定义的a_a,a_l,a_t,会发现绘图结果一致,但是如若使用a_d,则会报错,需要使用如下方法(借助索引获取该列数据)进行绘图:
fig,ax = plt.subplots() ax.plot(a_d.loc[:,0],a_d.loc[:,0]) plt.show() #或者使用如下方法 fig,ax = plt.subplots() ax.plot(a_d.values,a_d.values) plt.show()
上面两种操作,第一种是把DataFrame中的数据转换成Series进行绘图,第二种方法是把DataFrame转换成Array进行绘图。
由于python是一种非常灵活的语言,针对DataFrame还可以使用如下方式进行绘图
a_d = pd.DataFrame(a_a,columns = ['aa']) fig,ax = plt.subplots() ax.plot('aa','aa',data = a_d) plt.show()
通过给data参数赋值相应的变量,进而可以调用该DataFrame中的列进行绘图。
1.4 图的构成★
由于是使用代码绘制相应的图形,即图形中的所有元素均需使用代码进行设置,因此需要对图中的元素进行梳理,方便未来的绘图。
在讲解图的构成时,首先来解释两个对象:figure和axes。在使用plt.subplots()时创建的两个对象,在上述代码中将两个对象分别赋值给fig和ax。figure可以理解为绘图的画布,即一个可以画任何内容的画布;axes可以理解为画布上的一个区域,是画布的一部分,是整个图的一个子图。需要强调的一点是axes尽管是单词axis的复数形式,在这里并不能够直译,可以理解为一个坐标轴体系。
上面整个图是一个figure,每一套坐标轴体系(二维图形中的x轴和y轴)都是一个axes。在明确figure和axes的基础上来了解一张图都包含哪些内容。
可以把图形包含的内容分为三个层面:
- 描述层面:图标题、横坐标标题、纵坐标标题、图例
- 度量层面:横坐标主、次刻度,纵坐标主、次刻度,以及基于主次刻度衍生出的横纵坐标网格线
- 图形层面:也就是图形的主体部分,散点图的点、柱形图的柱等
以上均需通过代码进行运行。在介绍下述的各种图形时,均是对如何设置各种图形的元素进行讲解。
2 常用图形的绘制方法★★
在这里一部分主要介绍常用图形的绘制方法,同时包括相应的图形元素的设置。
2.1 折线图★★★
2.1.1 绘制折线图
折线图是matplotlib比较方便使用的图形。在matplotlib中使用plot函数进行绘制。
首先建立需要绘制的数据集
t = np.array([1,2,3,4,5]) s_a = np.array([1,2,3,4,5]) s_b = np.array([2,4,6,8,10]) s_c = np.array([3,6,8,12,15])
构建数据集后,绘制相应的折线图
首先绘制一个非常简单的折线图
fig,ax = plt.subplots() ax.plot(t,s_a) ax.plot(t,s_b) ax.plot(t,s_c) plt.show()
绘制图形如下
在这里解释下plot的参数,当前的参数就两个,第一个参数是x,第二个参数是y,其中参数x不是必需的,如果不输入该参数值,输出的结果保持一致(可自主验证)。
2.1.2 折线图的优化
不做任何设置的基本的图像都是比较丑的,所以需要对折线图进行优化,让阅读的人更容易看懂。matplotlib中优化的内容在各种图形之间基本是通用的,所以虽然在折线图部分进行介绍,相应的内容可以应用到多种图形中去。
优化描述层面
主要是添加标题、横纵坐标标题和图例。
在matplotlib中使用ax.set_title("This is a title")对标题进行设置;使用ax.set_xlabel('x label')和ax.set_ylabel('y label')设置横纵坐标标题;关于图例的设置,稍微有点复杂,图例的作用是用于提示图形中的线各代表的含义,因此需要首先在图形中标注该线的信息(使用字段label),然后再使用ax.legend()显示图例即可。现在把相应的代码进行改进,并重新展示图形。
修改后代码如下
fig,ax = plt.subplots(dpi=150) #参数dpi定义图形的像素,dpi越高,图形越清晰,在这里设置为150 ax.plot(t,s_a,label = 'store A') #添加label参数,支持后续图例的调用 ax.plot(t,s_b,label = 'store B') ax.plot(t,s_c,label = 'store C') ax.set_title("Sales of different stores") #设置图标题 ax.set_xlabel("month") #设置横坐标标题 ax.set_ylabel("sales volume") #设置纵坐标标题 ax.legend() #显示图例 plt.show()
显示图形如下:
通过设置标题,现在大体能看懂这张图,是不同店铺A、B、C在不同月份的销售额的趋势图,其中横轴表示月份,纵轴表示销售额,不同颜色的折线表示不同的店铺(分别对应ABC)。
图例的设置在某些图中由于图中空间的影响,使用默认设置方法可能出现对图片的遮挡,因此需要使用图例的大小参数和位置参数对图例进行优化。图例的位置调整使用参数loc,大小的调整使用fontsize。
loc的参数取值如下
取值 | 含义 |
---|---|
upper right | 右上角 |
upper left | 左上角 |
lower right | 右下角 |
lower left | 左下角 |
center left | 中间偏左 |
center | 正中间 |
center right | 中间偏右 |
lower center | 下边的中间位置 |
upper center | 上边的中间位置 |
大家可以自行尝试相应的位置,除了上面的选项外,还有一种就是不设置相应的参数,图形会自动选择最优的放置位置。在上述代码中并未设定位置,所以python自动选定了某一位置进行放置。
除了需要调整位置外,还需要设置图例的大小,在图例过大并且遮挡了图表的信息时,可以使用fontsize设置即可,fontsize的参数有两种,一种是直接使用数字设置,一种通过相对的大小进行设置。数字型的设定,在这里就不过多解释,自行尝试即可,直到尝试到一个合适的数值为止。相对大小的设置,就是通过字符串参数进行设置,可以的取值包括'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large',选择一个设置即可,逐步调整直到不影响图表的展示。
在这里将图例位置调整为lower right,并调整图例大小为“x-small”。
fig,ax = plt.subplots(dpi=150) ax.plot(t,s_a,label = 'store A') #添加label参数,支持后续图例的调用 ax.plot(t,s_b,label = 'store B') ax.plot(t,s_c,label = 'store C') ax.set_title("Sales of different stores") #设置图标题 ax.set_xlabel("month") #设置横坐标标题 ax.set_ylabel("sales volume") #设置纵坐标标题 ax.legend(loc="lower right",fontsize='x-small') # 显示图例 plt.show()
绘制结果如下:
优化度量层面
通过对描述层面的优化,可以了解整幅图要表达的含义,但是仍然存在不太合理的地方,月份中一般不会使用半个月的数据,所以需要修改横坐标的主刻度。而且因为缺少网格线,所以对应的具体数据并不明显,所以在这里调整横纵坐标的主次刻度,并添加网格线。
设置横纵坐标的主次刻度,需要借助matplotlib中的包ticker中的MultipleLocator。使用这一包中的函数设置主次坐标
from matplotlib.ticker import MultipleLocator xmajorLocator = MultipleLocator(1) #将x主刻度标签设置为1的倍数 ymajorLocator = MultipleLocator(2) #将y轴主刻度标签设置为2的倍数 yminorLocator = MultipleLocator(1) #将此y轴次刻度标签设置为1的倍数 #设置主刻度标签的位置 ax.xaxis.set_major_locator(xmajorLocator) ax.yaxis.set_major_locator(ymajorLocator) #显示次刻度标签的位置,次坐标无文本显示 ax.yaxis.set_minor_locator(yminorLocator)
将上段代码融合至经过描述层面优化的代码,如下:
fig,ax = plt.subplots(dpi=150) ax.plot(t,s_a,label = 'store A') #添加label参数,支持后续图例的调用 ax.plot(t,s_b,label = 'store B') ax.plot(t,s_c,label = 'store C') ax.set_title("Sales of different stores") #设置图标题 ax.set_xlabel("month") #设置横坐标标题 ax.set_ylabel("sales volume") #设置纵坐标标题 ax.legend() # 显示图例 xmajorLocator = MultipleLocator(1) #将x主刻度标签设置为1的倍数 ymajorLocator = MultipleLocator(2) #将y轴主刻度标签设置为2的倍数 yminorLocator = MultipleLocator(1) #将此y轴次刻度标签设置为1的倍数 #设置主刻度标签的位置 ax.xaxis.set_major_locator(xmajorLocator) ax.yaxis.set_major_locator(ymajorLocator) #显示次刻度标签的位置,次坐标无文本显示 ax.yaxis.set_minor_locator(yminorLocator) plt.show()
图像输出如下
通过设置坐标轴,使得当前的显示更加直观。
但是仍然存在的问题是横坐标不是从1开始的,而纵坐标也不是从0开始的,所以需要设置坐标轴的最大值和最小值,可以使用ax.set_xlim((min,max))和ax.set_ylim((min,max))进行设置。
fig,ax = plt.subplots(dpi=150) ax.plot(t,s_a,label = 'store A') #添加label参数,支持后续图例的调用 ax.plot(t,s_b,label = 'store B') ax.plot(t,s_c,label = 'store C') ax.set_title("Sales of different stores") #设置图标题 ax.set_xlabel("month") #设置横坐标标题 ax.set_ylabel("sales volume") #设置纵坐标标题 ax.legend() # 显示图例 xmajorLocator = MultipleLocator(1) #将x主刻度标签设置为1的倍数 ymajorLocator = MultipleLocator(2) #将y轴主刻度标签设置为2的倍数 yminorLocator = MultipleLocator(1) #将此y轴次刻度标签设置为1的倍数 #设置主刻度标签的位置 ax.xaxis.set_major_locator(xmajorLocator) ax.yaxis.set_major_locator(ymajorLocator) #显示次刻度标签的位置,次坐标无文本显示 ax.yaxis.set_minor_locator(yminorLocator) ax.set_xlim((1,5)) #设置横坐标的范围 ax.set_ylim((0.16)) #设置纵坐标的范围 plt.show()
输出图形如下
在这一层面,再介绍网格线的设置,网格线的设置有两种方法,一种是直接使用ax.grid(True)即可,则图像会自动添加横纵坐标的主刻度的网格线。除该方法外,还可以对横纵坐标依次进行设置。
关于线型的设置,主要参数包括(b,which,color,linestyle,linewidth)
其中b参数有True和False两种值,表示是否显示横纵坐标的网格线;which参数有‘major’和‘minor’和‘both’三种参数,表示显示主刻度网格线,次刻度网格线和两种都显示;color设置颜色;linestyle设置线型;linewidth设置线的宽度。关于线型的选项如下:
线性参数 | 代表含义 |
---|---|
- | 实线 |
-- | 虚线 |
-. | 点线 |
: | 点 |
None或' '或'' | 空白 |
#方案一 ax.grid(True) #显示网格线 #方案二 ax.xaxis.grid(True, which='major',c='g',linestyle = '-.') #x坐标轴的网格使用主刻度 ax.yaxis.grid(True, which = 'both',linestyle=':') #y坐标轴的网格使用次刻度
使用方案二显示的图形如下
优化图形层面
经过上述设置,图形更加清晰,接下来将主要优化图形部分。图形部分主要是对线条的设置和标记的设置。其中线条的设置包括:颜色(参数color)、线型(参数linestyle)、线的宽度(参数linewidth);标记的设置包括:标记的类型(参数marker)和标记的大小(参数markersize)。
fig,ax = plt.subplots(dpi=150) ax.plot(t,s_a,color='b',linestyle = '--',linewidth = 2,marker='.',markersize=12,label = 'store A') #添加label参数,支持后续图例的调用 ax.plot(t,s_b,label = 'store B') ax.plot(t,s_c,label = 'store C') ax.set_title("Sales of different stores") #设置图标题 ax.set_xlabel("month") #设置横坐标标题 ax.set_ylabel("sales volume") #设置纵坐标标题 ax.legend() # 显示图例 xmajorLocator = MultipleLocator(1) #将x主刻度标签设置为1的倍数 ymajorLocator = MultipleLocator(2) #将y轴主刻度标签设置为2的倍数 yminorLocator = MultipleLocator(1) #将此y轴次刻度标签设置为1的倍数 #设置主刻度标签的位置 ax.xaxis.set_major_locator(xmajorLocator) ax.yaxis.set_major_locator(ymajorLocator) #显示次刻度标签的位置,次坐标无文本显示 ax.yaxis.set_minor_locator(yminorLocator) ax.set_xlim((1,5)) #设置横坐标的范围 ax.set_ylim((0.16)) #设置纵坐标的范围 #ax.grid(True) #显示网格线 ax.xaxis.grid(True, which='major',c='g',linestyle = '-.') #x坐标轴的网格使用主刻度 ax.yaxis.grid(True, which = 'both',linestyle=':') #y坐标轴的网格使用次刻度 plt.show()
图形显示如下,在这里只对店铺A的图形进行优化,大家可自行尝试其他店铺的图形设置。
需要补充的一点是marker的参数,其表示标记的类型,常用的参数值包括
参数 | 图形 |
---|---|
'.' | 实点 |
',' | 像素标记 |
'o' | 实心圆 |
'v' | 下三角形 |
'^' | 上三角形 |
'<' | 左三角形 |
'>' | 右三角形 |
'1' | 上三叉戟 |
'2' | 下三叉戟 |
'3' | 左三叉戟 |
'4' | 右三叉戟 |
's' | 正方形 |
'p' | 正五边形 |
'*' | 星形 |
'h' | 正六边形1 |
'H' | 正六边形2 |
'+' | 加号 |
'x' | X符号 |
'D' | 菱形 |
'd' | 瘦菱形 |
'|' | 竖线形 |
'_' | 横线形 |
可自主尝试不同标记的形状。
2.1.3 面积图
折线图的堆叠图,也就是面积图,可以使用stackplot进行绘制。
fig,ax = plt.subplots(dpi=150) ax.stackplot(t,s_a,s_b,s_c
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
数据分析入门技术篇