目录
-
Matplotlib介绍
Matplotlib是一个Python的2D绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形。通过Matplotlib,开发者可以仅需要几行代码,便可以生成绘图。一般可绘制折线图、散点图、柱状图、饼图、直方图、子图等等。Matplot使用Numpy进行数组运算,并调用一系列其他的Python库来实现硬件交互。
Pylab是matplotlib面向对象绘图库的一个接口,它的语法和matlab十分相似。也就是说,它主要的绘图命令和matlab对应的命令有相似的参数。
-
初级绘制
-
绘图简介
使用matplotlib库绘图,原理很简单,如下5步:
-
创建一个图纸(figure)
-
在图纸上创建一个或多个绘图(plotting)区域(坐标系/轴,axes)
-
在plotting区域上描绘点、线等
-
为plotting添加修饰标签(绘图线上的或坐标轴上的)
-
其他各种DIY
-
-
在上面的过程中,主要就是下面三个元素:
-
变量
-
函数
-
图纸(figure)和坐标轴(axes)
其中,变量和函数通过改变figure和axes中的元素(例如:title,label,点和线等等)一起描述figure和axes,也就是在画布上绘图。图片结构如下所示:
如上图所示,一张图纸(figure)中有坐标轴(axes),title为图像标题,axis为坐标轴,label为坐标轴标注,tick为刻度线,tick label为刻度注释。
-
-
-
2D各种图形绘制
-
简单案例剖析
我们说Matplotlib是一个非常简单而又完善的开源绘图库,那么它到底有多简单呢?
下面我们用三行代码绘制一张简单的的折线图。
-
我们可以看到,一张和山峰相似的折线图就绘制出来了,接下来,我们来解析一下这三行代码的含义:
这行代码是从Matplotlib中导入了pyplot绘图模块,并将其简称为plt。pyplot模块是Matplotlib最核心的模块,几乎所有样式的2D图形都是经过该模块绘制出来的。这里简称其为plt是约定俗成的,希望你也这样写代码,以便拥有更好的可读性。
plt.plot()函数是pyplot模块下面的直线绘制(折线图)方法类。示例中包含了一个[1,3,5,2,6,3]列表,这里默认将该列表作为y值,而x值会从0到n-1.
最后一行代码表示将图显示出来。
-
除了折线图,怎样绘制其他图?
除了折线图,我们平常还要绘制柱状图、散点图、饼状图等等。这些图应该怎样绘制呢?
上文中,我们提到了pyplot模块,其中pyplot.plot()方法是用来绘制折线图的。你应该会很容易联想到,更改后面的方法类名,就可以更改图形的样式。的确,在matplotlib中,大部分图形样式的绘制方法都存在于pyplot模块中。例如:
除此之外,对图像样式的微调,包括标注、填充、自定义坐标轴等也同样包含在pyplot模块中。例如:
matplotlib.pyplot 模块下一共包含了160余个不同的方法(官方文档P1387),这些方法涉及到图像绘制的方方面面。
-
2D图像绘制
下面,我们就来学习一些常见类型的图像绘制及参数使用。
-
线型图
方法:matplotlib.pyplot.plot(*args,**kwargs)
上面我们建东使用该方法来绘制折线图。其实,matplotlib.pyplot.plot(*args,**kwargs)方法严格来讲可以绘制线型图或者样本标记。其中*args允许输入单个y值或x,y值。
例如我们绘制正弦曲线:
这样,一条正弦曲线就绘制出来了。但值得注意的是,pyplot.plot()在这里绘制的正弦曲线,实际上不是严格意义上的曲线图,而是在两点之间仍然是直线。因为取得点比较多,离得比较近,这里看起来像曲线 |
np.linspace()使用详解 np.linspace() 生成(start,stop)区间指定元素个数num的list,均匀分布 np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None) start :序列的起点 stop :序列的结束 num :int型数值,可选项,用来指定元素的个数,默认是50 endpoint:是否包含右边界点,True表示包含,默认为True,不包含为False retstep:bool,optional可选,为Ture返回步长(stop-start)/num的值 |
np.logspace()使用详解 np.logspace()方法与np.linspace()方法类似。只不过生成的不是均匀分布数据,而是log分布数据 |
np.array()使用详解 numpy.array(object, dtype=None, copy=True, order='K', subok=False, ndmin=0) object:一个数组 dtype:数组中数据的类型,如果没有给出,取最小类型 其余参数都是可选的 |
-
柱形图
方法:matplotlib.pyplot.bar(*args, **kwargs)
这里我们直接用上面的代码,仅把plt.plot(x,y)改成plt.bar(x,y)试一下:
效果好像不太好,问题当然出现在这里x = np.linspace(-2*np.pi, 2*np.pi, 1000)。横坐标是等间距生成的1000个值,效果当然会堆积在一起了,将1000改成10再试一次。 |
这时我们得到的图形仍然为有正弦的痕迹,因为我们的y=sin(x),当我们对y取一下绝对值后np.abs(np.sin(x)),得到的柱形图如下 |
-
散点图
方法:matplotlib.pyplot.scatter(*args, **kwargs)
散点图就是呈现在二维平面的一些点,这种图像的需求也是非常罕见的。比如,我们通过GPS采集的数据点,它会包含经度和纬度两个值,这样的情况就可以绘制称散点图。下面,我们画一个试一试:
其中:高斯分布 numpy.random.normal(loc=0.0, scale=1.0, size=None) loc : float此概率分布的均值(对应着整个分布的中心centre) scale : float,此概率分布的标准差(对应与分布的宽度,scale越大,分布波形越矮胖;scale越小,分布波形越瘦高) size : int or tuple of ints,输出的shape,默认为None,只输出一个值 |
正态分布: numpy.random.randn(size) 即所谓的标准正态分布, 对应于numpy.random.normal(loc=0, scale=1, size=None)。 |
-
饼状图
方法:matplotlib.pyplot.pie(*args, **kwargs)
饼状图在有限列表以百分比呈现时特别有用,你可以很清晰的看出来各类别之间的大小关系,以及各类别占总体的比例。
这里的Z值反映了各类别之间的大小关系,而且无论输入多少个值,最终都是在一张饼(100%)瓜分 |
-
量场图
方法:matplotlib.pyplot.quiver(*args, **kwargs)
量场图就是由向量组成的图像,在气象学等方面被广泛应用。从图像的角度来看,量场图就是带方向的箭头符号。
-
等高线图
方法:matplotlib.pyplot.contourf(*args, **kwargs)
中学学习地理的时候,我们就知道等高线了。等高线图是工程领域经常接触的一类图,那么如何用 Matplotlib 画出来呢?
值得注意的是,当我们向 contourf(X,Y,Z) 传入数据时,一定要注意相互之间的维度关系,不然很容易报错。其中,当 X,Y,Z 都是 2 维数组时,它们的形状必须相同。如果都是 1 维数组时,len(X)是 Z 的列数,而 len(Y) 是 Z 中的行数。 |
2 维数组示例: |
1 维数组示例: |
-
2D绘图进阶(样式,颜色等等)
-
线型图样式
我们已经知道了,线型图通过 matplotlib.pyplot.plot(*args, **kwargs)方法绘出。其中,args代表数据输入,而 kwargs的部分就是用于设置样式参数了。
二维线型图包含的参数超过 40 余项(文档 P1390)。其中常用的也有 10 余项,选取一些比较有代表性的参数列举如下:
-
其实,大部分都是所颜色所对应的英文名称首字母。当然,你也可以通过color = '#008000'的方式来设置任何你想要的颜色。 |
||
线型的样式 linestyle = 预设的参数值(文档 P1250)有: |
||
样本点标记样式 marker = 预设的参数值(文档 P1527)就更多了: 下图展示了所有标记对应的参数值和样式 |
下面我们来重新画一遍正弦函数的图像。添加几个参数,希望它不再那么单调。
-
散点图样式
了线型图以外,散点图也是常用图形之一。例如,我们在使用机器学习算法聚类的时候,往往就会通过散点图将样本数据展示出来。
Matplotlib 中,绘制散点图的方法我们已经知道了,那就是 matplotlib.pyplot.scatter()。接下来,我们就看一看它包含有哪些参数。
其中,散点的大小通过设置数值大小控制。散点的颜色可以是一种,参数值和线型的颜色设置类似。散点的颜色也可以是多种,可以使用一个列表对每一个点的颜色单独设置。 |
-
饼状图样式
饼状图通过 matplotlib.pyplot.pie() 绘出。我们也可以进一步设置它的颜色、标签、阴影等各类样式。下面就绘出一个示例。
-
组合图
上面演示了三种常见图像的绘制。实际上,我们往往会遇到将几种类型的一样的图放在一张图内显示,也就是组合图的绘制。
其实很简单,你只需要将需要或者的组合图样式放在一起就好了,比如柱形图和折线图。
-
子图绘制
上面提到了组合图绘制,但有一些图是无法组合直接放在一起的,这时就需要子图了。子图,就是将几张独立的图放在一张大图中呈现。在一些需要对比的情形下,子图非常有效。
Matplotlib 中,绘制子图的方法为matplotlib.pyplot.subplot(),我们通过该方法来控制各子图的显示顺序。其中:
下面列举了三种常见子图的位置关系示意图 |
接下来,我们绘制了一个由 4 个子图(2 行 x 2 列)组成的大图。 |
除了这类平行或垂直排列的子图,我们还可以通过 matplotlib.pyplot.subplot()绘制出更复杂的样式。比如,大图套小图。 |
-
绘制图例
一般情况下,当绘制好图案后,还需要绘制图例。Matplotlib 中,图例可以通过 matplotlib.pyplot.legend()方法绘制。我们又拿上面的正弦和余弦曲线举例。
在这里,我们需要修改两个地方,也就是通过 label= 为每一条曲线添加标签。然后,增加一条 plt.legend(loc='upper left')就可以了。其中,loc='upper left'是指明图例的位置,例如这里是左上方。你还可以通过 down和 right组合实现位置的变换。 |
-
图像标注
当我们绘制一些较为复杂的图像时,阅读对象往往很难全面理解图像的含义。而此时,图像标注往往会起到画龙点睛的效果。图像标注,就是在画面上添加文字注释、指示箭头、图框等各类标注元素。
Matplotlib 中,文字标注的方法由 matplotlib.pyplot.text()实现。最基本的样式为 matplotlib.pyplot.text(x, y, s),其中 x, y 用于标注位置定位,s 代表标注的字符串。除此之外,你还可以通过 fontsize= , horizontalalignment= 等参数调整标注字体的大小,对齐样式等。
下面,我们举一个对柱形图进行文字标注的示例。
除了文字标注之外,还可以通过 matplotlib.pyplot.annotate() 方法向图像中添加箭头等样式标注。接下来,我们向上面的例子中增添一行增加箭头标记的代码。 |
-
动态图绘制
动态图是绘图中不可缺少的一部分,虽然演示环境要求高且使用频率低,但是一些特定的场景下,动态图传达的信息量远大于静态图片。
举个例子来讲,数值计算中,我们往往会使用到梯度下降法。如果用语言和公式描述梯度下降的过程会非常枯燥。要是通过绘制一张演示梯度下降过程的动图,就算第一次接触该方法,也会很快的理解。
Matplotlib很早开始就支持动态图了,下面就通过简单的小例子来演示一下动态图的绘制。
动态图主要是通过animation模块实现。具体就是matplotlib.animation.FuncAnimation(fig,func)。其中fig代表所绘制的图像,而func可以看作是更新函数,它刷新每一帧的值。
-
Matplotlib三维绘图(3D)
-
mplot3d绘图模块介绍
前面,我们已经了解了如果使用 Matplotlib 中的 pyplot 模块绘制简单的 2D 图像。其实,Matplotlib 也可以绘制 3D 图像,与二维图像不同的是,绘制三维图像主要通过 mplot3d 模块实现。但是,使用 Matplotlib 绘制三维图像实际上是在二维画布上展示,所以一般绘制三维图像时,同样需要载入 pyplot模块。
mplot3d模块下主要包含 4 个大类,分别是:
-
-
mpl_toolkits.mplot3d.axes3d()
-
mpl_toolkits.mplot3d.axis3d()
-
mpl_toolkits.mplot3d.art3d()
-
mpl_toolkits.mplot3d.proj3d()
其中,axes3d()下面主要包含了各种实现绘图的类和方法。axis3d()主要是包含了和坐标轴相关的类和方法。art3d() 包含了一些可将 2D 图像转换并用于 3D 绘制的类和方法。proj3d()中包含一些零碎的类和方法,例如计算三维向量长度等。
一般情况下,我们用到最多的就是 mpl_toolkits.mplot3d.axes3d()下面的 mpl_toolkits.mplot3d.axes3d.Axes3D()类,而 Axes3D()下面又存在绘制不同类型 3D 图的方法。你可以通过下面的方式导入 Axes3D()。
-
三维散点图
接下来,通过一个简单的例子,来看一看绘制三维图像具体需要几个步骤。
-
首先,我们导入 numpy 随机生成一组数据。
-
接下来,开始绘图。第一步是载入 2D, 3D 绘图模块。
-
第二步,使用 Axes3D() 创建 3D 图形对象。
-
最后,调用散点图绘制方法绘图并显示出来。
-
除开生成数据和模块导入,实际上只用了 4 行短小的代码就绘制出了一幅三维散点图像。
-
-
三维线型图
线形图和散点图相似,需要传入 x, y, z 三个坐标的数值。详细的代码如下。
-
三维柱状图
绘制完线型图,我们继续尝试绘制三维柱状图,其实它的绘制步骤和上面同样非常相似。
-
三维去面图
接下来需要绘制的三维曲面图要麻烦一些,我们需要对数据进行矩阵处理。其实和画二维等高线图很相似,只是多增加了一个维度。
-
混合图绘制
混合图就是将两种不同类型的图绘制在一张图里。绘制混合图一般有前提条件,那就是两种不同类型图的范围大致相同,否则将会出现严重的比例不协调,而使得混合图失去意义。
-
子图绘制
-
三维图绘制总结
本次实验主要是学会如果使用 Matplotlib 完成简单的 3D 绘图。你会发现,三维绘图其实就是在二维绘图上的演变。二者的区别重点在两个方面,首先需要建一个了三维画布,其次需要多输入一个维度值,即 z 值。
-
参考绘图网址
-
Matplotlib 绘图教程(2D入门)
-
Matplotlib 绘图教程(2D进阶)
-
Matplotlib 绘图教程(3D)
-
官方文档
-