大家好,这篇文章是我整理的 Matplotlib 绘制图象,所用到的基本配置,涵盖了大部分的使用场景(万字长文,请不要嫌我啰嗦哦,只为了大家能更好的理解),是绘制直方图、热力图等图象的基础。
大家好,我是向阳花,数据科学路上,与你同行。
博主的Python数据分析专栏正在火热更新中,不要错过呀 ~
matplotlib是一个
python 2D
绘图库,同时也提供了一部分3D
绘图的接口,利用它可以画出许多高质量的图像。只需几行代码即可生成直方图,条形图,饼图,散点图等。它的官网这样描述它:Matplotlib: Visualization with Python
(用 Python 进行可视化)。
在数据分析与机器学习中,我们经常要用到大量的可视化操作,制作一张精美的图片,可以直观展示数据。大家记住一句话:字不如表,表不如图,一图胜千言。
自带 matplotlib ,无需另外安装。
pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple
安装后同时导入数据分析三剑客(numpy,pandas,matplotlib):
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
执行后可能出现警告,再次执行就会消失。
使用 matplotlib 绘图默认不会显示中文和负号,需要添加以下代码配置。
# 当浏览器不显示绘图图片时,加上这一行
%matplotlib inline
# 让图片可以显示中文
plt.rcParams['font.sans-serif'] = 'SimHei'
# 让图片可以显示负号
plt.rcParams['axes.unicode_minus'] = False
# 支持svg矢量图
%config InlineBackend.figure_format = 'svg'
通过以下代码,可以查看自己电脑上的可用字体库。
from matplotlib.font_manager import FontManager
fm = FontManager()
my_fonts = set(f.name for f in fm.ttflist)
my_fonts
运行结果显示的字体,都可以设置到上面中文的代码中,将 'SimHei'
替换掉。
matplotlib 使用 plot() 函数绘制折线图。
在后面,我们会看到这样调用的:plt.plot()
,也会看到这样调用的:ax.plot()
。使用这两种方式画图,可视化结果是一样的。
# =======第一种方式=======
fig=plt.figure(figsize=(4,4))
plt.plot([1,2,3,4],[1,2,3,4])
# =======第二种方式=======
fig=plt.figure(figsize=(4,4))
ax=fig.add_subplot(111)
ax.plot([1,2,3,4],[1,2,3,4])
其实,第一种方法是先创建了一个画布(figure),然后在画布上绘图;第二种方法是也是先创建了一个画布,然后在画布上创建了一个子图区域,在子图区域上作图。
也就是说,通过子图的方式,一个画布上可以绘制多个子图,如果直接在画布上画,那么我们只能画出重叠图和嵌套图(在下面会讲到这两种图)。
使用 matplotlib 绘图的基本流程:
(第一次使用 mermaid
绘制流程图,绘制的有些复杂难以理解了,还望见谅。)
绘制下面二次函数的图象:
y = x 2 y = \def\sqr#1{#1^2} \sqr{x} y=x2
# 创建一个等差数列数组(-5至5,100个数据,差值相同)
x = np.linspace(-5,5,100)
# 绘制 y = x**2 的函数图象
plt.plot(x,x**2)
plot() 函数通过两个属性
color
和linestyle
设置线段颜色和线段样式。它们的简写形式是 c 和 ls,也可以将它们写到一起(写在一起的例子在下文给出),但是不建议。
就上面的抛物线代码进行改编:
# 绘制 y = x**2 的函数图象
plt.plot(x,x**2,color='g',linestyle='-.')
plt.plot(x,x**2,c='g',ls='-.')
# not suggest,make people look at it and do not understand
plt.plot(x,x**2,'g-.')
那么 color 和 linestyle 的取值有哪些呢?这里我罗列了官方文档给出的一些。
**Colors**
The supported color abbreviations are the single letter codes
============= ===============================
character color
============= ===============================
``'b'`` blue
``'g'`` green
``'r'`` red
``'c'`` cyan
``'m'`` magenta
``'y'`` yellow
``'k'`` black
``'w'`` white
============= ===============================
and the ``'CN'`` colors that index into the default property cycle.
If the color is the only part of the format string, you can
additionally use any `matplotlib.colors` spec, e.g. full names
(``'green'``) or hex strings (``'#008000'``).
通俗来讲,意思就是 color 可以有三种写法,单个字母简写,英文单词,十六进制(不可以缩写为井号加3个字符)。
**Line Styles**
============= ===============================
character description
============= ===============================
- solid line style
-- dashed line style
-. dash-dot line style
: dotted line style
============= ===============================
画布配置是 Matplotlib 中非常重要的一块,后面绘制许多图形,都建立在画布配置基础之上,需要深刻掌握记忆。
基本配置写在 plt.figure() 函数参数上。
参数 | 配置 |
---|---|
figsize | 画布宽高 |
dpi | 分辨率 |
facecolor | 画布背景颜色 |
此外,还可以通过 plt.grid()
函数为画布添加网格。
# 画布配置
plt.figure(figsize=(5,3),dpi=100,facecolor='g')
# 画正弦曲线
x = np.linspace(0,2*np.pi,100)
y = np.sin(x)
plt.plot(x,y)
# 配置网格
plt.grid()
在同一个画布上绘制多个图象,只需要多次调用 plt.plot()
函数即可。
plt.figure(figsize=(5,4)) # 画布大小
x = np.linspace(0,2*np.pi,100)
y1 = np.sin(x) # 正弦函数
y2 = np.cos(x) # 余弦函数
# 绘制多个图象
plt.plot(x,y1,ls='--')
plt.plot(x,y2,ls='-.')
通过 plt.show() 方法立即显示图片,即可出现多个画布。在调用了这个方法之后,后面调用 plt 对象绘制图象,将是初始配置,figsize,dpi等配置没有了。
在上面的代码基础上,只添加一行:
# 绘制多个图象
plt.plot(x,y1,ls='--')
plt.show() # 添加的行
plt.plot(x,y2,ls='-.')
通过 plt.subplot(),plt.subplots()
函数可以进行子图配置。这两个函数只相差了一个 s
,它们的区别就是,前者是调用它返回一个子图对象,后者是调用它返回多个子图对象。
# 创建画布对象
fig = plt.figure(figsize=(4,3))
x = np.linspace(-2,2,100)
y1 = x # 一次函数
y2 = np.sin(x) # 正弦函数
y3 = 1/x # 反比例函数
y4 = x**2 # 二次函数
# 子图1
ax1 = plt.subplot(221) # 221表示2行2列中的第一个图
ax1.set_title('子图1')
ax1.plot(x,y1)
# 子图2
ax2 = plt.subplot(222) # 221表示2行2列中的第一个图
ax2.set_title('子图2')
ax2.plot(x,y2)
# 子图3
ax3 = plt.subplot(223) # 221表示2行2列中的第一个图
ax3.set_title('子图3')
ax3.plot(x,y3)
# 子图4
ax4 = plt.subplot(224) # 221表示2行2列中的第一个图
ax4.set_title('子图4')
ax4.plot(x,y4)
# 设置自动调整布局
fig.tight_layout()
从官方文档我们得知,Function : Create a figure and a set of subplots.它会返回一个画布对象和一个子图集合,因此等下我们使用两个变量来接收返回值。
fig,axes = plt.subplots(2,2)
x = np.linspace(-2,2,100)
y1 = x # 一次函数
y2 = np.sin(x) # 正弦函数
y3 = 1/x # 反比例函数
y4 = x**2 # 二次函数
# 得到第一维
ax0,ax1 = axes[0],axes[1]
# 第二维
ax00,ax01 = ax0[0],ax0[1]
ax10,ax11 = ax1[0],ax1[1]
# 利用这四个子图对象画图
ax00.plot(x,y1)
ax01.plot(x,y2)
ax10.plot(x,y3)
ax11.plot(x,y4)
# 自动调整布局
fig.tight_layout()
图形嵌套是指在一个图形中再嵌套一个或多个图象,它不同于第一种情况(多图绘制 | 同一画布(重叠))。有三个函数 add_subplot(),axes(),add_axes()
可以实现图象重叠,下面请看代码示例。
fig = plt.figure(figsize=(4,3))
# 图象1
axes1 = fig.add_subplot(1,1,1) # 1,1,1表示它在第一行,第一列,占一个
# 绘制一条直线
axes1.plot([0,1],[1,3])
# 嵌套图象2
axes2 = fig.add_subplot(2,2,1,facecolor='g') # 2,2,1表示它在第二行,第二列,第一个
axes2.plot([0,1],[1,3])
fig = plt.figure(figsize=(4,3))
x = np.linspace(-2,2,100)
# 图1
y1 = x
plt.plot(x,y1)
# 嵌套图2
y2 = x**2
axes1 = plt.axes([0.55,0.55,0.3,0.3]) # [left, bottom, width, height]
axes1.plot(x,y2,color='g')
在上一个代码的基础上,只改变最后两行,改为:
axes1 = fig.add_axes([0.18,0.18,0.3,0.3])
axes1.plot(x,y2,color='r')
双轴显示是指,两个或多个图象共用 X 轴,但是它们的 Y 轴不一样,使用的是左边的 Y 轴或者是右边的 Y 轴。
plt.figure(figsize=(4,3))
x = np.linspace(0,10,100)
# image one
# 得到当前轴域
axes1 = plt.gca()
axes1.plot(x,np.exp(x),color='r') # 指数函数
# 为轴设置标签
axes1.set_xlabel('time')
axes1.set_ylabel('exp',c='r')
# 设置刻度的颜色
axes1.tick_params(axis='y',labelcolor='red')
# image two
axes2 = axes1.twinx() # 和 image one 共享X轴
axes2.plot(x,np.sin(x),c='b') # sinx图象
axes2.set_ylabel('sin',c='b')
axes2.tick_params(axis='y',labelcolor='blue')
# auto adjust layout
plt.tight_layout()
图例(legend),是图象中用于标记哪个图象是表示什么的指示,一般是正方形。图例的设置有两种方法,一种是先设置标签(label)之后直接显示,另外一种是最后设置标签。
plt.figure(figsize=(4,3))
x = np.linspace(0,2*np.pi,100)
plt.plot(x,np.sin(x),label='sin')
plt.plot(x,np.cos(x),label='cos')
# 显示图例,默认在空白处显示
plt.legend()
plt.legend(loc='upper left',fontsize=10)
plt.figure(figsize=(4,3))
x = np.linspace(0,2*np.pi,100)
plt.plot(x,np.sin(x))
plt.plot(x,np.cos(x))
plt.legend(
labels=['sin','cos'], # 按照图片显示顺序对应
fontsize=10,
loc='center',
ncol=2, # 显示成2列
# 图例的具体位置[x,y,width,height]
bbox_to_anchor=[0,1,1,0.2]
)
线条属性在 plot() 方法中使用(前面讲到 plot 方法可以由画布对象调用,也可以由子图对象调用,如果忘记了往上面翻复习一下),线条属性主要有以下这些(前两个在之前也已经提到过)。
属性 | 作用 |
---|---|
color | 线条颜色 |
linestyle | 线条样式 |
linewidth | 线宽 |
alpha | 透明度 |
marker | 拐点处的标记样式 |
mfc(marker face color | 标记的背景颜色 |
# 以折线图为例
fig = plt.figure(figsize=(4,3))
x = np.random.randint(0,20,10)
plt.plot(
x,
color='r',
ls='--',
lw='1',
alpha=0.2,
marker='o',
mfc='g',
)
默认情况下,我们设置的X轴的范围,就是X轴的取值范围,刻度是默认的,Y轴也是根据Y的取值范围确定的。有时候我们需要修改刻度,使得图象更加细致,通过 xticks()
,yticks()
方法可以修改刻度。
plt.figure(figsize=(4,3))
x = np.linspace(0,10)
y = np.sin(x)
plt.plot(x,y)
# 设置X和Y轴的刻度
plt.xticks(ticks=np.arange(0,11,1),fontsize=10,color='g')
plt.yticks(
ticks=[-1,0,1],
labels=['min','0','max'], # 显示刻度标签
fontsize=10,
color='b',
ha='right' # 水平对齐方式
)
# 立即显示图象,如果不加会打印很多对象地址
plt.show()
如果我们想要修改坐标轴的范围,那么可以使用两种方法。
现在是不改变坐标轴范围的情况:
plt.figure(figsize=(5,3))
x = np.linspace(0,2*np.pi)
y = np.sin(x)
plt.plot(x,y,c='r')
plt.show()
现在我们在原来代码的基础上,添加上两行代码:
plt.figure(figsize=(4,3))
x = np.linspace(0,2*np.pi)
y = np.sin(x)
plt.plot(x,y,c='r')
# 改变X轴范围为-2-8,Y轴范围为-2-2
plt.xlim(-2,8)
plt.ylim(-2,2)
plt.show()
在原来没有改变坐标轴范围的代码基础上添加一行代码:
plt.figure(figsize=(4,3))
x = np.linspace(0,2*np.pi)
y = np.sin(x)
plt.plot(x,y,c='r')
# 改变X轴范围为-2-8,Y轴范围为-2-2
plt.axis([-2,8,-2,2])
plt.show()
也可以实现同样的效果:
此外,坐标轴还有以下设置,作为 axis() 方法的参数:
参数值 | 作用 |
---|---|
off | 不显示坐标轴 |
equal | 让X轴和Y轴刻度距离(分度值)相同 |
scaled | 自动缩放坐标轴和图片匹配 |
tight | 紧凑型自动适配图片 |
square | 让画布呈现正方形,X轴和Y轴宽高一致 |
下面是代码示例:
plt.figure(figsize=(4,3))
x = np.linspace(0,2*np.pi)
y = np.sin(x)
plt.plot(x,y,c='r')
# 改变X轴范围为-2-8,Y轴范围为-2-2
plt.axis('off')
plt.show()
因为使用的是 off
,那么就是不显示坐标轴,得到的就是如下曲线。
一张图片拥有一个标题,可以直观的告诉人们这是描述什么的图象,因此图片标题是非常重要的。此外,我们还可以给图片设置网格底,下面介绍图片标题以及网格的设置。
fig = plt.figure(figsize=(4,3))
plt.title('直线') # 设置标题
# 设置父标题
plt.suptitle(
'父标题',
y=1.1, # 位置
fontsize=10
)
# 设置网格线
plt.grid(
ls='--',# 网格线样式
lw=0.5, # 线宽
c='gray',# 线条颜色
axis='y' # 只显示Y轴网格线
)
plt.plot([0,1],[1,3])
标签是用于描述X轴、Y轴的文本,比如说,横轴表示科目,纵轴表示分数,那么就要通过标签来设置。
project = ['科目一','科目二','科目三']
scores = [90,80,100]
fig = plt.figure(figsize=(4,3))
# 设置标签(rotation表示旋转角度)
plt.xlabel('科目',fontsize=10,rotation=45)
# horizontalalignment表示水平对齐方式
plt.ylabel('分数',fontsize=10,rotation=0,horizontalalignment='right')
plt.plot(project,scores)
文本是用于标记图象中某个点的值是多少,见的是非常多的,在绘图中会经常使用到。
fig = plt.figure(figsize=(4,3))
x = np.linspace(1,10,10)
y = np.random.randint(20,40,10)
plt.plot(x,y,ls='--',marker='*')
# 加上文本
for a,b in zip(x,y):
# 这个循环的意思是,分别取 x,y 中的一个元素,返回一个元组
plt.text(
x = a, # x轴坐标
y = b + 1, # y轴坐标(用于确定文本位置)
s = b, # 文本内容
fontsize = 10, # 字体大小
color='g',
ha='center',
va='center'
)
有时候某一个点可能有特殊含义,需要用文字说明,那么这时候就需要使用到注释。注释是一种用箭头指向某一个位置,然后显示文本的方式。
fig = plt.figure(figsize=(4,3))
x = np.linspace(1,10,10)
y = np.array([10,20,30,40,20,30,10,20,0,30])
plt.plot(x,y,ls='--',marker='*')
# 添加注释 annotation
plt.annotate(
s='最大值', # 注释内容
xy=(4,40), # 注释的坐标点,也就是箭头指向的位置
xytext=(1,35), # 标注内容的位置
# 箭头样式
arrowprops = {
'width':1, # 箭头线的宽度
'headwidth':4, # 箭头头部的宽度
'facecolor':'red' # 箭头的背景颜色
}
)
plt.show()
有时候,我们希望将自己可视化的作品图片保存下来,用于PPT展示或其他用处,那么我们可以使用 savefig()
方法。
fig = plt.figure(figsize=(4,3))
x = np.linspace(0,2*np.pi,100)
plt.plot(x,np.sin(x))
# 保存图片
plt.savefig('sin.png')
运行之后,不仅会在 Jupyter Notebook 下打印图片,还会保存图片到当前目录。
我们还可以添加一些别的设置:
fig = plt.figure(figsize=(4,3))
x = np.linspace(0,2*np.pi,100)
plt.plot(x,np.sin(x))
# 保存图片
plt.savefig(
fname = 'sin.png',# 图片名字
dpi = 100, # 图片像素密度
facecolor = 'pink', # 背景颜色
pad_inches = 1 # 内边距
)
本文主要讲解了Matplotlib绘图相关配置,是利用Matplotlib绘图的基本功。
⭐️如果有不懂的地方,欢迎大家和我一起探讨 ~
好啦,这就是今天要分享给大家的全部内容了,我们下期再见!