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的基础上来了解一张图都包含哪些内容。

图片说明

可以把图形包含的内容分为三个层面:

  1. 描述层面:图标题、横坐标标题、纵坐标标题、图例
  2. 度量层面:横坐标主、次刻度,纵坐标主、次刻度,以及基于主次刻度衍生出的横纵坐标网格线
  3. 图形层面:也就是图形的主体部分,散点图的点、柱形图的柱等

以上均需通过代码进行运行。在介绍下述的各种图形时,均是对如何设置各种图形的元素进行讲解。

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%内容,订阅专栏后可继续查看/也可单篇购买

数据分析入门技术篇

全部评论

相关推荐

04-03 11:37
武汉大学 Java
高斯林的信徒:武大简历挂?我勒个骚岗
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客企业服务