目录
一、Matplotlib是什么?
二、Matplotlib架构
2.1脚本层(Scripting)
2.2美工层(Artist)
实例1:Figure
实例2:Axis、ticks与label
2.3后端层(Backend)
三、Matplotlib图形组成(重要,需要理解透彻)
四、两种不同的绘图模式
第一种方式绘图代码
第二种方式绘图代码
区别
Matplotlib 是一款用于数据可视化的 Python 软件包,支持跨平台运行,它能够根据 NumPy ndarray 数组来绘制 2D 图像,它使用简单、代码清晰易懂,深受广大技术爱好者喜爱。
(NumPy 是 Python 科学计算的软件包,ndarray 则是 NumPy 提供的一种数组结构。)
Matplotlib 由三个不同的层次结构组成,分别是脚本层、美工层和后端层。
脚本层是 Matplotlib 结构中的最顶层。我们编写的绘图代码大部分代码都在该层运行,它的主要工作是负责生成图形与坐标系。matplotlib.pyplot
,通常起别名为plt。
Artist
是Matplotlib的中间层,也是很多繁重的情况发生的地方,后端FigureCanvas
是画纸,Artist
是知道如何拿起Renderer
(画笔)并将墨水涂在画布上的对象,你在Matplotlib的Figure
都是Artist
的实例,包括title, lines, tick labels, images
等等,他们都属于基类matplotlib.artist.Artist
,而Artist
和backend
之间的关联发生在draw
方法中。由于Renderer
有一个指向其画布FigureCanvas
的指针,并知道如何在其上绘画,因此draw
方法可以将抽象的指令转换Artist
为像素缓冲区中的颜色、SVG 文件中的路径或任何具体表示。
我们用两张图来理解Artist
的各个实例与层次,在这张图中,我们给出了主要的实例:Figure(图)、Axes(轴域)、Text(文本)、2Dline(二维线条)、XAxis(X轴)、YAxis(Y轴)、Xlabel(X轴标签)、Xticks(X轴刻度)、Ylabel(Y轴标签)、Yticks(Y轴刻度)
,注意,Axes中的ax.set_xticklabels()
设置的就是plt.xticks().
最大的一类是Figure
,其次是Axes
,再其次是Axes
中的一些实例,轴、文本、线条等等,Text
可以包含图的标题、图注、图标等等一切的文本。
另外需要注意这些美工实例又分为原始型美工(Primitive artists)
与复合型美工(Composite artists)
,例如前面提到的Text
、以及背景的Rectangle、Circle
都是原始型美工,而Axis、Tick、labels、Axes、Figure
则是复合型美工,一个复合型美工可以包含多个复合型美工或者原始型美工,例如,Figure
可以包含包含一个或多个Axes
并且Figure
的背景是一个基元Rectangle
。
接下来我们对这些实例进行一一介绍:
将Figure看成是一张大的画板。那么问题来了:
问:如何创建画板?
答:用matplotlib.figure中的fig=Figure()来创建一张画板fig,也可以在函数式绘图中用fig=plt.figure()来建立fig。
但有个画板还不够,好比你要画油画,你不能画在画板上吧,至少需要一张画纸,这里的画纸就可以理解为以横纵坐标轴为长和宽所建立起来的矩形,2D的图像都在这个矩形内。
问:如何创建一张和多张画纸?
答:可以用canvas = FigureCanvas(fig)来产生一张画纸,或者如果用fig=plt.figure(),那他会默认产生一张画纸。且可以用fig.add_subplot(plt.subplots(子图)),或者fig.add_axes(轴域)来产生多的画纸,他们会将原来大的画纸进行拆分,拆分成若干张小画纸,画纸和画纸间可以嵌套,可以并列放置。
补充知识点:subplot和axes
Subplot负责将整个画板分割成几块,用ax = fig.add_subplot(abc)
来创建子图,里面的参数abc代表是产生a行b列一共a*b个子图区域,c表示给这个区域添加子图。
例如:ax1 = fig.add_subplot(221) , ax2 = fig.add_subplot(222) , ax4 = fig.add_subplot(224)
就是在2*2个区域中,在左上,右上和右下建立子图:
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
fig = Figure()
canvas = FigureCanvas(fig)
ax1 = fig.add_subplot(221)
ax2 = fig.add_subplot(222)
ax4 = fig.add_subplot(224)
canvas.print_png('test1.png')
%%html
![](test1.png)
Subplot建立子图的方式比较基础而且整洁,另一种形式Axes则较为灵活:
Axes,可以通过fig.add_axes([left,bottom,width,height])
添加子图的左边界、下边界、宽度和高度来在合适的位置上添加子图:
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
fig = Figure()
canvas = FigureCanvas(fig)
ax1 = fig.add_axes([0.1, 0.1, 0.2, 0.2]) #代表左边空出10%,底部空出10%,宽度为20%,高度为20%
ax1.set_title("ax1")
ax2 = fig.add_axes([0.3, 0.3, 0.4, 0.4]) #代表左边空出30%,底部空出30%,宽度为40%,高度为40%
ax2.set_title("ax2")
canvas.print_figure('test3.jpg')
%%html
![](test3.jpg)
Axes还可以嵌套,如果设置
ax1 = fig.add_axes([0.1, 0.1, 0.8, 0.8])
ax2 = fig.add_axes([0.3, 0.3, 0.4, 0.4])
问:如何确定使用哪个方法绘制子图?
答:关于Subplot和Axes本质上都是产生多张画纸,所以两者的区别并不大。如果想快速、标准的切割画板,可以用fig.add_subplot()
,而如果想自定义画纸,则可以使用fig.add_axes()
。这两种创建子图的方法,在脚本层都有对应的实现方式,下文我们会提到。
Axes是轴域,Axis就是轴,对应的有X轴和Y轴,每个轴都有ticks,即轴上的刻度与label,即轴标签,对于调整刻度可以用set_xlim()和set_ylim()
来调整,对于设置ticks的名称,则可以使用ax.set_xticklabels()
和ax.set_yticklabels()
来设置。对于设置标签,则用ax.set_xlabel()
和ax.set_ylabel()
来实现,还可以设置title,用set_title()
来实现我们可以在脚本层来更方便的控制。
ax=fig.add_axes([0.1, 0.1, 0.8, 0.8])
ax.set_xlim(-0.5,1.5)
ax.set_ylim(-0.5,1.5)
ax.set_xticklabels(['One','Two','Three'])
ax.set_xlabel('Date')
ax.set_ylabel('Units')
ax.set_title('Exponential vs. Linear performance')
实际上,调用Matplotlib的方式可以大不相同:有些人从 Python shell 交互式地使用 Matplotlib,他们键入命令时会弹出绘图窗口,有些人在 Jupyter Notebook用%matplotlib inline
或者%matplotlib notebook
的magic code绘制内联图或者交互式图表以进行快速数据分析;还有人将 Matplotlib 嵌入到 PyQt 或 PyGObject 等图形用户界面中以构建丰富的应用程序;或者有一些人运行 Web 应用程序服务器来动态提供图形等等。
为了支持所有这些用例,Matplotlib 可以针对不同的输出,这些不同的输出每一种都称为一种后端;“前端”是面向用户的代码,即绘图代码,而“后端”则在幕后完成所有艰苦的工作来制作图形。有两种类型的后端,第一种后端是用户界面后端(user interface backends):用PyQt/PySide、PyGObject、Tkinter、wxPython 或 macOS/Cocoa,也称为“交互式后端(interactive backends)”我们在jupyter notebook中用的%matplotlib notebook
就属于这一种;另一种后端是硬拷贝后端:用以制作图像文件PNG、SVG、PDF、PS,也称为“非交互式后端(non-interactive backends)”。
后端层是 Matplotlib 最底层,它定义了三个基本类,首先是 FigureCanvas(图层画布类),它提供了绘图所需的画布,其次是 Renderer(绘图操作类),它提供了在画布上进行绘图的各种方法,最后是 Event(事件处理类),它提供了用来处理鼠标和键盘事件的方法。
由matplotlib生成的图像由figure,axes,axis,artist四部分组成。通过一张figure解剖图,我们可以看到一个完整的matplotlib图像通常会包括以下四个层级,这些层级也被称为容器(container),下一节会详细介绍。在matplotlib的世界中,我们将通过各种命令方法来操纵图像中的每一个部分,从而达到数据可视化的最终效果,一副完整的图像实际上是各类子元素的集合。
matplotlib提供了两种最常用的绘图接口
x = np.linspace(0,2,100)#在[0,2]区间上平均取100个数
fig,ax =plt.subplots()
ax.plot(x,x,label = 'liner')
ax.plot(x,x**2,label = 'quadratic')
ax.plot(x,x**3,label = 'cubic')
ax.set_xlabel('x label')
ax.set_ylabel('y label')
ax.set_title('Simple plot')
ax.legend()
plt.show()
x = np.linspace(0,2,100)#在[0,2]区间上平均取100个数
plt.plot(x,x,label = 'liner')
plt.plot(x,x**2,label = 'quadratic')
plt.plot(x,x**3,label='cubic')
plt.xlabel('x label')
plt.ylabel('y label')
plt.title('Simple Plot')
plt.legend()
plt.show()
第一种方式先定义了fig,ax,后面的作图也都是以ax开始,这是因为plt.subplots可以绘制多个子图,ax是用来指定绘图区域。plt.subplots比plt.plot灵活方便,plt.plot比较简单。
fig,ax =plt.subplots(1,1,1)
等价于
fig = plt.figure
ax = fig.add_subplot(1,1,1)
第一个1参数是子图的行数,第二个2参数是子图的列数,第三个1参数是代表第一个子图
在第一种方式的基础上绘制多个子图:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
fig,ax=plt.subplots(2,2)
# 画第1个图:折线图
x=np.arange(1,100)
ax[0][0].plot(x,x*x)
# 画第2个图:散点图
ax[0][1].scatter(np.arange(0,10), np.random.rand(10))
# 画第3个图:饼图
ax[1][0].pie(x=[15,30,45,10],labels=list('ABCD'),autopct='%.0f',explode=[0,0.05,0,0])
# 画第4个图:条形图
ax[1][1].bar([20,10,30,25,15],[25,15,35,30,20],color='b')
plt.show()
注:ax[0][0]代表索引为0,0的子图