首先,不能马上让人上手的教程,就是耍流氓。
我们都知道,matplotlib是Python下一个极其强大的作图库。但是它虽然强大,却有着陡峭的学习曲线,想要用它来灵活地作图需要花费大量的学习时间,这也是为什么近年来基于matplotlib封装的Seaborn等作图库迅速流行起来的原因。
我们希望能迅速上手一个工具并画出美观而有说服力、有解释力的图形,而不是花费大量的时间却仍然飘在云里雾里。
matplotlib有两种语言风格,一种是沿袭自MatLab的命令式风格,一种是Python的面向对象风格。不同的作图风格有时会让我们感到混乱,这也在无形中增加了我们的学习难度。不过我们今天不是来讨论风格优劣的,我们今天的目的是熟悉matplotlib的基本作图函数,以达到快速上手Python可视化的目的。
今天,我们先抛却又臭又长的官方文档,抛却庞大的作图知识体系,尝试在30分钟内掌握基本的作图能力。
我们先从最常用的作图函数以及样式调整函数学起,其他的让它们先玩儿去吧。
欢迎大家关注我的个人博客【数洞】 【备用站】
1. plot()
plot()函数包含了很多基础的绘图功能,这里我们用它来绘制线图,用以展现数据的变化趋势。
import matplotlib.pyplot as plt
import numpy as np
# 生成数据
x = np.linspace(0, 10, 1000)
y = np.sin(x)
# 使用plt.plot()绘图
# lw ~ line width,用于设置线条宽度
# '-r'是说线条使用正常的连续曲线,颜色使用红色
# label设置线条的标签,我们会在图例中看到它
plt.plot(x, y, ls='-r', lw=2, label='sin(x)')
plt.legend()
plt.show()
2. scatter()
scatter()函数用以绘制散点图,我们常用它来观察变量间的相关性。
import matplotlib.pyplot as plt
import numpy as np
# 生成数据
x = np.linspace(0, 10, 100)
y = np.random.rand(100)
# 使用plt.scatter()绘图
# c ~ color,用于设置颜色
# alpha用于控制透明度
plt.scatter(x, y, c='g', alpha=0.5, label='scatters')
plt.legend()
plt.show()
3. xlim() / ylim()
这两个函数用于设置坐标轴的数值显示范围。
import matplotlib.pyplot as plt
import numpy as np
# 生成数据
x = np.linspace(0, 10, 100)
y = np.random.rand(100)
# 使用scatter绘图
plt.scatter(x, y, label='scatters')
plt.legend()
# 使用xlim()/ylim()调整坐标轴
# 我们需要上下(左右)两个边界的数值
plt.xlim(2, 10)
plt.ylim(-0.2, 1.2)
plt.show()
可以看到,虽然我们数据的范围是x ∈ [0, 10], y ∈ [0, 1],但在我们的强烈要求下,图片上只展示出了其中的一部分。
4. xlabel() / ylabel()
顾名思义,这两个函数用于设置坐标轴的标签。
import matplotlib.pyplot as plt
import numpy as np
# 生成数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
# 使用scatter绘图
# ls ~ line style,用于设置线条类型
plt.plot(x, y, ls='-.', lw=2, c='g', label='sin(x)')
plt.legend()
# 使用xlim()/ylim()调整坐标轴
plt.xlabel('x-axis')
plt.ylabel('y-axis')
plt.show()
5. grid()
就喜欢这么直白的命名,grid()函数正是用于设置图形中的网格线。
import matplotlib.pyplot as plt
import numpy as np
# 生成数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
# 使用scatter绘图
plt.plot(x, y, ls='-.', lw=2, c='c', label='sin(x)')
plt.legend()
# 使用grid()调整网格线
# linestyle用于设置网格的线条类型,color用于设置网格的线条颜色
plt.grid(linestyle=':', color='r')
plt.show()
啊,好丑。
6. axhline() / axvline()
ax ~ axis
h ~ horizontal,水平的
v ~ vertical,垂直的
组合起来看,我们可以猜到,这两个函数分别用于设置水平参考线和垂直参考线。
import matplotlib.pyplot as plt
import numpy as np
# 生成数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
# 使用scatter绘图
plt.plot(x, y, ls='-.', lw=2, c='c', label='sin(x)')
plt.legend()
# 这里的参数跟之前几个函数的参数类似,不再赘述
plt.axhline(y=0, c='r', ls='--', lw=2)
plt.axvline(x=5, c='g', ls='-.', lw=2)
plt.show()
7. axhspan() / axvspan()
ax ~ axis
h ~ horizontal,水平的
v ~ vertical,垂直的
span ~ 跨度,区间,范围
这两个函数分别用于设置平行于x轴/y轴的参考区域。
import matplotlib.pyplot as plt
import numpy as np
# 生成数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
# 使用scatter绘图
plt.plot(x, y, ls='-.', lw=2, c='c', label='sin(x)')
plt.legend()
# xmin/xmax/ymin/ymax用于设置区间范围
# facecolor用于设置区域颜色
# alpha用于设置透明度
plt.axhspan(ymin=-0.25, ymax=0.25, facecolor='purple', alpha=0.3)
plt.axvspan(xmin=4, xmax=6, facecolor='g', alpha=0.3)
plt.show()
8. annotate()
这个函数就是为了在图形中添加指向性注释文本,为了能灵活调整注释的位置以及指示箭头的样式,这个函数提供了丰富的可选参数,想要熟练使用这一函数需要我们花一些功夫去探索。
import matplotlib.pyplot as plt
import numpy as np
# 生成数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
# 使用scatter绘图
plt.plot(x, y, ls='-.', lw=2, c='c', label='sin(x)')
plt.legend()
# 这里的参数跟之前几个函数的参数类似,不再赘述
plt.axhspan(ymin=-0.25, ymax=0.25, facecolor='purple', alpha=0.3)
plt.axvspan(xmin=4, xmax=6, facecolor='g', alpha=0.3)
# 使用annotate()添加注释
plt.annotate('maximum',
xy = (np.pi * 3 / 2, -1),
xytext = (np.pi * 3 / 2 - 0.6, -0.7),
weight = 'bold',
color = 'r',
arrowprops = {
'arrowstyle': '->',
'connectionstyle': 'arc3',
'color': 'r',
'alpha': 0.3
})
plt.show()
可以看到,我们为(π/2, -1)位置的最低点加了一个“minimum”的红色文本注释,这里边我们用到了以下的配置项,它们的含义是:
xy: 指示点的坐标,即我们希望注释箭头指向的点的坐标
xytext: 注释文本左端的坐标(不是文本中心的坐标)
weight: 注释文本的字体粗细风格,bold是粗体,正常粗细则用regular
color: 注释文本的颜色
-
arrowprops: arrow + props(properties),箭头属性,字典格式
- arrowstyle: 箭头类型
- connectionstyle: 连接类型
- color: 箭头颜色
...
更多的参数大家可以查阅文档,里边有详细的介绍。至于查阅文档,为大家推荐一个软件,在Mac下有一个叫Dash的软件,简直是文档查阅神器,在Linux和Windows下有一个叫Zeal的替代软件。强烈推荐没用过的同学体验下。
9. text()
这个函数同样是用于图形中的注释,但它跟annotate()的区别是它用于添加无指向性注释文本,也就是不带指向性箭头的文本注释。
import matplotlib.pyplot as plt
import numpy as np
# 生成数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
# 使用scatter绘图
plt.plot(x, y, ls='-.', lw=2, c='c', label='sin(x)')
plt.legend()
# 这里的参数跟之前几个函数的参数类似,不再赘述
plt.axhspan(ymin=-0.25, ymax=0.25, facecolor='purple', alpha=0.3)
plt.axvspan(xmin=np.pi*3/2-1, xmax=np.pi*3/2+1, facecolor='g', alpha=0.3)
# 使用annotate()添加注释
plt.text(np.pi * 3 / 2 - 0.7, -0.7, 'minimum', weight='regular', color='r', fontsize=12)
plt.text(np.pi * 3 / 2 - 1, 0.7, 'y=sin(x)', weight='regular', color='r', fontsize=16)
plt.show()
由于没有了箭头,我们就不需要那个字典参数了,同时坐标等参数都更直接地使用x、y等来表达。我们使用fontsize参数设置了注释文本的大小。
10. title()
这个函数最简单,就是用于设置图形的标题。
import matplotlib.pyplot as plt
import numpy as np
# 生成数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
# 使用scatter绘图
plt.plot(x, y, ls='-.', lw=2, c='c', label='sin(x)')
plt.legend()
# 设置标题
plt.title('A Sine Curve')
plt.show()
11. legend()
这个函数我们已经见过好多次了,它用于添加图例。
10. title()
这个函数最简单,就是用于设置图形的标题。
import matplotlib.pyplot as plt
import numpy as np
# 生成数据
x = np.linspace(0, 10, 100)
y = np.sin(x)
# 使用scatter绘图
plt.plot(x, y, ls='-.', lw=2, c='c', label='sin(x)')
# 控制图例位置
plt.legend(loc='lower right')
# 设置标题
plt.title('A Sine Curve')
plt.show()
这里我们将图例放在了右下角,图例的位置使用loc参数来控制:
- upper left: 左上角
- upper center: 中上
- upper right: 右上角
- lower left: 左下角
- lower center: 中下
- lower right: 右下角
12. 小挑战
在最后,我们用一个小挑战来回顾下之前的内容:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm as cm
# 生成数据
x = np.linspace(0.5, 3.5, 100)
y = np.sin(x)
y1 = np.random.randn(100)
# 创建图形并设置大小
plt.figure(figsize=(12, 8))
# 散点图
plt.scatter(x, y1, c='0.5', label='scatters')
# sin(x)图
plt.plot(x, y, '--g', lw=2, label='sin(x)')
# 样式调整
# 去掉图形上边和右侧的边框
for spine in plt.gca().spines.keys():
if spine == 'top' or spine == 'right':
plt.gca().spines[spine].set_color('none')
# 设置坐标轴上的刻度线位置(其实这里的设置跟默认一样)
plt.gca().xaxis.set_ticks_position('bottom')
plt.gca().yaxis.set_ticks_position('left')
# 将刻度线放在坐标轴内侧
plt.tick_params(direction = 'in')
# 设置坐标轴范围
plt.xlim(0, 4)
plt.ylim(-3, 3)
# 设置轴标签
plt.xlabel('X 轴')
plt.ylabel('Y 轴')
# 设置网格线
plt.grid(True, ls=':', color='r', alpha=0.5)
# 添加水平参考线
plt.axhline(y=0, c='r', ls='--', lw=2)
# 添加垂直参考区间
plt.axvspan(xmin=1, xmax=2, facecolor='g', alpha=0.1)
# 添加sin(x)的最高点注释
plt.annotate('maximum',
xy = (np.pi/2, 1),
xytext = (np.pi/2, 1.3),
weight = 'regular',
color = 'r',
fontsize = 12,
arrowprops = {
'arrowstyle': '->',
'connectionstyle': 'arc3',
'color': 'r'
})
# 添加y轴边框注释
plt.annotate('spines',
xy = (0, -2.5),
xytext = (0.25, -2.3),
weight = 'regular',
color = 'c',
fontsize = 12,
arrowprops = {
'arrowstyle': '->',
'connectionstyle': 'arc3',
'color': 'c'
})
# 添加x轴边框注释
plt.annotate('',
xy = (0.25, -3),
xytext = (0.37, -2.4),
arrowprops = {
'arrowstyle': '->',
'connectionstyle': 'arc3',
'color': 'c'
})
# 添加一个指向tick的箭头
plt.annotate('',
xy = (3.5, -2.98),
xytext = (3.6, -2.7),
arrowprops = {
'arrowstyle': '->',
'connectionstyle': 'arc3',
'color': 'c'
})
# 在上边的箭头旁添加注释文字
plt.text(3.6, -2.7, "'|' is tickline", weight='bold', color='c')
plt.text(3.6, -2.9, "3.5 is ticklabel", weight='bold', color='c')
# 设置标题
plt.title('Structure of matplotlib')
# 添加图例
plt.legend()
# 展示图形
plt.show()
可以看到,我们配置了很多小细节,是不是很有成就感?
没错,matplotlib就是这么强大,这还仅仅是它的冰山一角呢!
好了,以上就是用来作图以及调整图形样式的十来个常用的函数,本文严重参考刘大成先生的《Python数据可视化之matplotlib实践》一书,这本书的组织形式是截止目前我认为讲解matplotlib库中最清晰、最适合新手的,强烈推荐。