Python学习笔记(11-1):matplotlib绘图——图形语法
文章导读
- 课程难度:★★☆☆☆
- 重要度:★★★★★
- 预计学习时间:40分钟
- 简介:本节主要讲解了使用matplotlib绘图的基本图形语法,包括:(1)使用简单的例子展示基础绘图的步骤;(2)设置图像的基础参数和属性,如图例、x轴、y轴和图像的名称等;(3)基于定义画布、绘制子图和figure、axes对象的画布与子图的设置;(4)使用函数plt.savefig()保存图像。
- 重点涉及的函数和内容:plt.show()、plt.savefig()、plt.figure()、plt.subplot()、plt.subplots()、plt.xlabel()、plt.ylabel()、plt.title()、plt.legend()。
前言
这部分我们只讲解一个最基础的
matplotlib
库,但这就足够了。因为另外一些应用广泛的包,例如
seaborn
也是基于
matplotlib
进行封装的,而
plotly
虽然能绘制动态图,但是它的应用则受到诸多限制。
我们首先用最基本的图形描述其在
matplotlib
下的基础图形语法,接着讲解其通用的一些参数。然后,我们会延伸一些例子,面向各种需要实现常用图表的绘制。
在此,先导入包和我们这边会用到的一些数据集:
import matplotlib.pyplot as plt
import matplotlib
import numpy as np
import pandas as pd
一、matplotlib图形语法
对于一个图而言,它的绘制遵循着如下的步骤。这些步骤实际上可看做执行一批设置绘图参数的指令,但这种执行指令的过程都是利用函数而不是传递参数而实现的:
(1)声明一个即将绘制的画布(可选) –
Figure
对象,在绘制子图时讲解。
(2)声明当前即将绘制的子图(可选) –
Axe
对象,在绘制子图时讲解。
(3)在当前的子图下声明即将绘制的图的类型,以及待用的数据。
(4)在当前绘图的类型下,声明绘图的各类参数(可选)。
(5)定义好各个参数后,将当前的绘图对象输出或保存。
1、基础绘图
实现一个最基础的绘图可以说轻而易举,我们只需要三步:定义待绘制数据、调用绘图函数、将图输出:
x = np.linspace(0, 2, 10) # 生成一个自0到2的等差数列,包含100个元素
plt.plot(x, x)
# 声明当前绘图的类型,一般的折线图(plot),即连续的各点间的连线图。
plt.show() # 将曲线输出
绘图效果如下。这里先补充讲解一下,如果传入的是
plot(x)
,那么绘制曲线x时横坐标设置为
range(len(x))
,而传入
plot(x,y)
时曲线的横坐标为x,纵坐标为y。
matplotlib的整套基础语法知识:
(1)`plt`作为一个函数库,实际上管理着我们的图形对象,我们在此是直接用类方法管理着图形属性,也可以用当前画布和子图对象来管理(之后会讲)。
(2)在绘图前需要定义画布和子图,但步骤可省。如果当前没有定义二者而直接调用了绘图函数,就会默认定义一个画布,这张画布包含唯一一个子图。
(3)对于细节参数,例如X、Y轴的名称标度、曲线的颜色等等,可以不予定义,将会默认值进行输出。
(4)作为程序的最后一步,当`plt.show()`被调用后,会将当前已经定义好的图形全部输出,同时清空已经当前的图形对象。
2、图形属性参数
接下来,我们为数据补充两个部分,一是绘制多根曲线并指定一些图形参数,二是增加一些图形属性。我们还是手工定义待绘制的数据:
x = np.linspace(0, 2, 10)
我们同时绘制一次、二次和三次曲线,同时设置曲线的图例(label)。而且,不仅绘制对应数据列的曲线图,也同时在当前图像上绘制数据的散点图:
plt.plot(x, x, label='linear') # 用plt.plot()绘制数据的连线图
plt.plot(x, x**2, label='quadratic') # label是曲线的名称
plt.plot(x, x**3, label='cubic')
plt.scatter(x, x, label='linear') # 用plt.scatter()绘制数据的散点图
plt.scatter(x, x**2, label='quadratic') # label是曲线的名称
plt.scatter(x, x**3, label='cubic')
接着,在定义曲线之后设置图形参数,此处设置x轴和y轴的名字、图的名字以及显示图例。在定义了上述参数好,我们将图形输出:
plt.xlabel('x label') # 设置x轴名称
plt.ylabel('y label') # 设置y轴名称
plt.title("Simple Plot") # 设置图像标题
plt.legend() # 设置图例,会显示之前绘图时的label
plt.show()
输出图像如下:
我们可就刚刚画图的代码进行仔细地观察,并提炼如下知识点:
(5)设置对于一类数据图的数据本身的描述属性,例如曲线的颜色、散点图的点的形状等等,一般而言在定义图的函数内进行设置。
(6)设置整个图的属性,例如x和y轴的名称、图的名称等,一般而言利用类方法(也即这里的plt,即pyplot)定义。
(7)在没有额外定义的情况下,所有绘制的对象都绘制在同一张图上,且共用一套坐标轴(当然后续我们有办法在一张图里应用多个坐标轴)。
3、 画布与子图
定义画布一般而言用的方式是
plt.figure()
。在定义一张画布之后,我们可以利用
plt.subplot()
或
plt.subplots()
为这张画布的不同区域绘制不同的图,也即绘制子图,如果不经过这一步而直接画图,我们就默认我们在这张画布上只绘制一张图。
(1)定义画布:plt.figure()
plt.figure()
是定义画布的一个声明。在调用这个函数、传递不同的参数时,传递给了系统两个信息:
第一,我们对某个特定的画布进行了新定义或再定义。
第二,我们将当前的正在绘制的对象移动到了当前指定的画布上。
如下是三个最常见的可用参数,这些参数都是可选的:
x = np.linspace(0, 2, 10)
plt.figure(figsize = (8, 8),
dpi = 200,
facecolor = 'gray', # 指定画布的填充颜色,默认为白色
# 尚有edgecolor参数表示边框颜色,但使用无效
)
三个参数的含义如下:
figsize:画布的尺寸,默认为rcParams["figure.figsize"] = [6.4, 4.8]
dpi:画布的精度,默认为rcParams["figure.dpi"] = 100
facecolor:画布内部颜色,默认为rcParams["figure.facecolor"] = 'w'(白色)
然后输出图形:
plt.plot(x, x)
plt.show()
输出图像如下:
第一个参数时
figsize
,它接收一个包含两个值得元组或列表,第一个参数是图像的宽,第二个参数是高,其默认值是[6.4, 4.8]。可以看到此时图明显地变大了,这就是它的效果。
第二个参数是
dpi
,这个参数指示
figsize
里面的一个单位代表多少像素,例如这里
dpi
为200,指示这个
figsize
为(8, 8)的图实际上有1600 * 1600的分辨率(将图保存后可观察尺寸,不要直接保存输出的结果观察)。
第三个参数是
facecolor
,它指示整个画布的背景色,即底色。可以传递颜色名称的字符串,例如
'white'
,也可以传递十六进制的颜色字符串,如’#FFDAB9’这个六位数分成三组,先后指示红绿蓝的255色(00-FF)。但此时设置的背景色直接做保存时会失效,需要另外调整。
(2)绘制子图:plt.subplot()
子图的绘制有两个可用的函数,一个是
plt.subplot()
,另一个是
plt.subplots()
。
plt.subplot()
函数要求我们先通过
plt.figure()
指定一个大的画布,当然在未指定的情况下就只当做默认创建一张新画布并进行绘制。之后,当它被调用时,表示当前绘制的是当前画布的当前子图,而这个函数描述一个画布的子图位置通过两种方式:
第一种,传入一个三位数,第一位是描述行数目,第二位描述列数目,第三位描述这个图片具体的位置的数值。
第二种,传入三个值,第一个是描述行数目,第二个描述列数目,第三个描述这个图片具体的位置的数值。
两者的效果很接近,例如
plt.subplot(234)
代表一张画布分为了2行3列,这个子图为第2行第1个(位置为4),此时它等同于
plt.subplot(2, 3, 4)
具体示例如下:
x = np.linspace(0, 2, 10)
plt.figure(1)
plt.subplot(221) # 2行2列的子图区间,占第1个格子
plt.plot(x, x)
plt.subplot(223) # 2行2列的子图区间,占第3个格子
plt.plot(x, x ** 0.5)
plt.subplot(122) # 这里指示了一个1行2列的子图区间
# 占第2个格子,即占据了右边一竖列,因为不相重叠可以绘制
plt.plot(x, x ** 2)
figure = plt.figure(2) # 画布对象,将构建的结果赋值给figure
plt.subplot(3, 4, 1) # 3行4列的子图区间,占第1个格子
plt.plot(x, x)
plt.subplot(3, 4, 12) # 3行4列的子图区间,占第12个格子
plt.plot(x, x ** 2)
plt.show()
输出图像如下:
用这个例子我们也可以发现一个子图绘制的新特性,即一张画布只会画图片定义的绘画部分,其余的没定义的部分是置空的。
(3)绘制子图:plt.subplots()
在
plt.subplot()
里面,我们先定义一个画布,再先后定义画布上的各个子图。而在
plt.subplots()
里,则直接通过一个函数设置子图的分隔形状,定义好了当前画布和所有附属子图。它的返回值就是画布的
figure
对象和所有子图的
axe
对象数组,这个数组的形状为
[rows, cols]
。我们对各个子图进行分别绘制就是通过这些
axe
对象,其绘图的过程和此前直接用类方法进行绘图的过程相同
画布大小需要在
plt.subplots()
中定义,返回值分别是画布对象和所属子图的对象列表,二者会在下一节进行介绍:
x = np.linspace(0, 2, 10)
figure, ax_list = plt.subplots(nrows = 2, ncols = 2, figsize = (8, 6))
接下来,根据
ax_list
中的各个
axe
对象,进行子图的绘制:
ax_list[0][0].plot(x, x) # ax1是第一个axe对象,画y = x的折线图
ax_list[0][1].plot(x, x ** 2) # ax2是第二个axe对象,画y = x**2的折线图
ax_list[1][0].plot(x, x ** 3) # ax3是第二个axe对象,画y = x**3的折线图
ax_list[1][1].plot(x, x ** 0.5) # ax3是第二个axe对象,画y = x**0.5的折线图
plt.show()
输出图像如下:
(4)figure对象及axes对象
figure
实际上就是我们的画布对象,而
axe
就是我们的图(图、子图)对象。例如我们把在
plt.subplot()
讲解时应用到的例子拿过来稍加修改,调用
axe
对象的成员方法绘图:
figure = plt.figure(1) # 画布对象,将构建的结果赋值给figure
ax1 = plt.subplot(4, 3, 12) # 图像对象,ax1是第一个axe对象,画y = x的折线图
ax1.plot(x, x)
ax2 = plt.subplot(4, 3, 1) # 图像对象,ax2是第二个axe对象,画y = x**x的折线图
ax2.plot(x, x ** 2)
plt.show()
输出图像如下:
4、图片的保存:plt.savefig()
保存图片就用
plt.savefig()
即可。其重要参数如下:
fname:存储文件的路径,需要补充其扩展名如.png。
dpi :画布的精度,默认为100。
facecolor:画布内部颜色,默认为 'w'(白色)。
transparent:图像是否透明,默认为False。
bbox_inches:画布的留白空间,当设置为'tight'时表示尽量缩减留白空间
在本例中,我们将绘制两个图形,仅修改
transparent
参数和
bbox_inches
参数,并观察参数的效果:
x = np.linspace(0, 2, 10)
plt.figure(figsize = [12, 12], dpi = 100) # 1200 * 1200的子图
plt.subplot(221)
plt.plot(x, x)
plt.subplot(223)
plt.plot(x, x ** 0.5)
plt.subplot(122)
plt.plot(x, x ** 2)
plt.savefig('lesson11/plot1.jpg', transparent =False)
plt.show()
plt.figure(figsize = [12, 12], dpi = 100) # 1200 * 1200的子图
plt.subplot(221)
plt.plot(x, x)
plt.subplot(223)
plt.plot(x, x ** 0.5)
plt.subplot(122)
plt.plot(x, x ** 2)
plt.savefig('lesson11/plot2.jpg', transparent = True, bbox_inches = 'tight')
plt.show()
输出图像如下:
我们可发现plot2留白比plot1少一些,这就是
bbox_inches
的效果。
接着讲述
transparent
参数的效果。直接修改参数
transparent
并没有发生特别的效果。这是因为我们还没明确
transparent
的参数的含义。它的具体含义是指整个图像的图片区域(即框框中的部分、
axe
的部分)是否透明。如果设置为透明,图片区域的颜色会是画布的颜色,如果不透明,则为自己图像区域的背景色。这个透明不是指图片保存后的某个区域透明,请务必注意。我们将在后续观察
transparent
参数的效果。
至此,对于matplotlib基础的图形语法进行了一定讲解,接下来将讲解各种实际绘图函数的应用,在这个过程中相信会顺带对图形语法部分逐渐熟悉和掌握。
对于缺乏Python基础的同仁,可以通过免费专栏?
《Python学习笔记(基础)》
从零开始学习Python
结语
请始终相信
“Done is better than perfect”
,不要过分追求完美,即刻行动就是最好的开始, 一个模块一个模块地积累和练习,必将有所收获。
还有其他的问题欢迎在评论区留言?!
[版权申明] 非商业目的注明出处可自由转载,转载请标明出处!!!
博客:
butterfly_701c