matplotlib的原理是用Artist对象在画布(canvas)上绘制(Render)图形。步骤类似于:
API | 说明 |
---|---|
matplotlib.backend_bases.FigureCanvas | 绘图区,所有的图像都是在绘图区完成的 |
matplotlib.backend_bases.Renderer | 渲染器,可以近似理解为画笔,控制如何在 FigureCanvas 上画图 |
matplotlib.artist.Artist | 具体的图表组件,即调用了Renderer的接口在Canvas上作图 |
前两者处理程序和计算机的底层交互的事项,第三项Artist就是具体的调用接口来做出我们想要的图,比如图形、文本、线条的设定。通常来说**,95%的时间都是用来和matplotlib.artist.Artist类打交道**。
类型 | 说明 |
---|---|
primitive | 基本要素,包含一些要在绘图区作图用到的标准图形对象,如曲线Line2D,文字text,矩形Rectangle,图像image等 |
containers | 容器,即用来装基本要素的地方,包括图形figure、坐标系Axes和坐标轴Axis |
matplotlib的标准使用流程为:
import matplotlib.pyplot as plt
import numpy as np
#step1
#用matplotlib.pyplot.figure()创建一个Figure实例
fig = plt.figure()
#step2
#用Figure实例创建一个两行一列(即可以有两个subplot)的绘图区,并同时在第一个位置创建一个subplot
ax = fig.add_subplot(2,1,1)#两行一列,第一个subplot
#step3
#用Axes实例的方法画一条曲线
t = np.arange(0.0,1.0,0.01)
s = np.sin(2*np.pi*t)
line, = ax.plot(t,s,color = 'blue',lw = 2)
各容器中可能会包含多种基本要素-primitives, 本文主要介绍primitives 的几种类型:曲线-Line2D,矩形-Rectangle,图像-image。
matplotlib中曲线的绘制,主要是通过类matplotlib.lines.Line2D来完成的。它的基类:是matplotlib.artist.Artist。matplotlib中线-line的含义:它表示的可以是连接所有顶点的实线样式,也可以是每个顶点的标记。此外,这条线也会受到绘画风格的影响,比如,可以创建虚线种类的线。
其构造函数为:
class matplotlib.lines.Line2D(xdata, ydata, linewidth=None, linestyle=None, color=None, marker=None, markersize=None, markeredgewidth=None, markeredgecolor=None, markerfacecolor=None, markerfacecoloralt='none', fillstyle=None, antialiased=None, dash_capstyle=None, solid_capstyle=None, dash_joinstyle=None, solid_joinstyle=None, pickradius=5, drawstyle=None, markevery=None, **kwargs)
其中常用的的参数有:
有三种方法可以用设置线的属性:
#1)直接在plot()函数中设置
import matplotlib.pyplot as plt
x = range(5)
y = [2,5,7,8,10]
plt.plot(x,y,linewidth = 10);#设置线的粗细参数为10
#2)通过获得线对象,对线对象进行设置
x = range(5)
y = [2,5,7,8,10]
line, = plt.plot(x,y,'-')
line.set_antialiased(False)#关闭抗锯齿功能
#3)获得线属性,使用setp()函数设置
x = range(5)
y = [2,5,7,8,10]
lines = plt.plot(x,y)
plt.setp(lines,color = 'r',linewidth = 10);
#1.pyplot方法绘制
import matplotlib.pyplot as plt
x = range(5)
y = [2,5,7,8,10]
plt.plot(x,y)
#2.Line2D对象绘制
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
fig = plt.figure()
ax = fig.add_subplot(111)
line = Line2D(x,y)
ax.add_line(line)
ax.set_xlim(min(x),max(x))
ax.set_ylim(min(y),max(y))
plt.show()
2. errorbar绘制误差折线图
pyplot里有个专门绘制误差线的功能,通过errorbar类实现。其构造函数为:
matplotlib.pyplot.errorbar(x, y, yerr=None, xerr=None, fmt='', ecolor=None, elinewidth=None, capsize=None, barsabove=False, lolims=False, uplims=False, xlolims=False, xuplims=False, errorevery=1, capthick=None, *, data=None, **kwargs)
其中最主要的参数是前几个:
#绘制errorbar
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
x = np.arange(10)
y = 2.5*np.sin(x/20*np.pi)
yerr = np.linspace(0.05,0.2,10)
plt.errorbar(x,y+3,yerr = yerr,label = "both limits(default)");
matplotlib.patches.Patch类是二维图形类。它的基类是matplotlib.artist.Artist,其构造函数为:
Patch(edgecolor=None, facecolor=None, color=None, linewidth=None, linestyle=None, antialiased=None, hatch=None, fill=True, capstyle=None, joinstyle=None, **kwargs)
Rectangle矩形类在官网中的定义是: 通过锚点xy及其宽度和高度生成。 Rectangle本身的主要比较简单,即xy控制锚点,width和height分别控制宽和高。它的构造函数:
class matplotlib.patches.Rectangle(xy, width, height, angle=0.0, **kwargs)
在实际中最常见的矩形图是hist直方图和bar条形图。
matplotlib.pyplot.hist(x,bins=None,range=None, density=None, bottom=None, histtype='bar', align='mid', log=False, color=None, label=None, stacked=False, normed=None)
一些常用的参数有:
#hist绘制直方图
import matplotlib.pyplot as plt
import numpy as np
x = np.random.randint(0,100,100)#生成[0-100)之间的100个数据,即数据集
bins = np.arange(0,101,10)#设置连续的边界值,即直方图的分布区间[0,10),[10,20)......
plt.hist(x,bins,color = 'fuchsia',alpha = 0.5)#alpha设置透明度,0为完全透明
plt.xlabel('scores')
plt.ylabel('count')
plt.xlim(0,100)#设置x轴分布范围
plt.show()
#Rectangle矩形类绘制直方图
import pandas as pd
import re
df = pd.DataFrame(columns = ['data'])
df.loc[:,'data'] = x
df['fenzu'] = pd.cut(df['data'],bins = bins,right = False,include_lowest = True)
df_cnt = df['fenzu'].value_counts().reset_index()
df_cnt.loc[:,'mini'] = df_cnt['index'].astype(str).map(lambda x:re.findall('\[(.*)\,', x)[0]).astype(int)
df_cnt.loc[:,'maxi'] = df_cnt['index'].astype(str).map(lambda x:re.findall('\,(.*)\)', x)[0]).astype(int)
df_cnt.loc[:,'width'] = df_cnt['maxi'] - df_cnt['mini']
df_cnt.sort_values('mini',ascending = True,inplace = True)
df_cnt.reset_index(inplace = True,drop = True)
#用Rectangle把hist绘制出来
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(111)
for i in df_cnt.index:
rect = plt.Rectangle((df_cnt.loc[i,'mini'],0),df_cnt.loc[i,'width'],df_cnt.loc[i,'fenzu'])
ax1.add_patch(rect)
ax1.set_xlim(0,100)
ax1.set_ylim(0,16)
plt.show()
matplotlib.pyplot.bar(left, height, alpha=1, width=0.8, color=, edgecolor=, label=, lw=3)
一些常用的参数有:
#bar绘制柱状图
import matplotlib.pyplot as plt
y = range(1,17)
plt.bar(np.arange(16),y,alpha = 0.5,width = 0.5,color = 'yellow',edgecolor = 'red',label = 'The First Bar',lw = 3)
# Rectangle矩形类绘制柱状图
#import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(111)
for i in range(1,17):
rect = plt.Rectangle((i+0.25,0),0.5,i)
ax1.add_patch(rect)
ax1.set_xlim(0, 16)
ax1.set_ylim(0, 16)
plt.show()
matplotlib.patches.Polygon类是多边形类。其基类是matplotlib.patches.Patch,它的构造函数:
class matplotlib.patches.Polygon(xy, closed=True, **kwargs)
xy是一个N×2的numpy array,为多边形的顶点。closed为True则指定多边形将起点和终点重合从而显式关闭多边形。
matplotlib.patches.Polygon类中常用的是fill类,它是基于xy绘制一个填充的多边形。
matplotlib.pyplot.fill(*args, data=None, **kwargs)
参数说明 : 关于x、y和color的序列,其中color是可选的参数,每个多边形都是由其节点的x和y位置列表定义的,后面可以选择一个颜色说明符。可以通过提供多个x、y、[颜色]组来绘制多个多边形。
#用fill来绘制图形
import matplotlib.pyplot as plt
x = np.linspace(0,5*np.pi,1000)
y1 = np.sin(x)
y2 = np.sin(2*x)
plt.fill(x,y1,color = 'g',alpha = 0.3)
matplotlib.patches.Wedge类是多边形类。其基类是matplotlib.patches.Patch,它的构造函数:
class matplotlib.patches.Wedge(center, r, theta1, theta2, width=None, **kwargs)
一个Wedge-契形 是以坐标x,y为中心,半径为r,从θ1扫到θ2(单位是度)。如果宽度给定,则从内半径r -宽度到外半径r画出部分楔形。wedge中比较常见的是绘制饼状图。
matplotlib.pyplot.pie语法为:
matplotlib.pyplot.pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=0, radius=1, counterclock=True, wedgeprops=None, textprops=None, center=0, 0, frame=False, rotatelabels=False, *, normalize=None, data=None)
制作数据x的饼图,每个楔子的面积用x/sum(x)表示。最主要的参数是前4个:
#pie绘制饼状图
import matplotlib.pyplot as plt
labels = ['Frogs','Hogs','Dogs','Logs']
sizes = [15,30,45,10]
explode = (0,0.1,0,0)
fig1,ax1 = plt.subplots()
ax1.pie(sizes,explode = explode,labels = labels,autopct = '%1.1f%%',shadow = True, startangle = 90)
ax1.axis('equal')#相等的纵横比确保将饼图绘制为圆形
plt.show()
#wedge绘制饼状图
import matplotlib.pyplot as plt
from matplotlib.patches import Circle,Wedge
from matplotlib.collections import PatchCollection
fig = plt.figure()
ax1 = fig.add_subplot(111)
theta1 = 0
sizes = [15,30,45,10]
patches = []
patches += [
Wedge((0.3,0.3), 0.2, 0, 54),
Wedge((0.3,0.3), 0.2, 54, 162),
Wedge((0.3,0.3), 0.2, 162, 324),
Wedge((0.3,0.3), 0.2, 324, 360),
]
colors = 100 * np.random.rand(len(patches))
p = PatchCollection(patches, alpha = 0.4)
p.set_array(colors)
ax1.add_collection(p)
plt.show()
collections类是用来绘制一组对象的集合,collections有许多不同的子类,如RegularPolyCollection, CircleCollection, Pathcollection, 分别对应不同的集合子类型。其中比较常用的就是散点图,它是属于PathCollection子类,scatter方法提供了该类的封装,根据x与y绘制不同大小或颜色标记的散点图。 它的构造函数为:
Axes.scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, verts=, edgecolors=None, *, plotnonfinite=False, data=None, **kwargs)
最主要的参数是前5个:
#用scatter绘制散点图
x = [0,2,4,6,8,10]
y = [10]*len(x)
s = [20*2**n for n in range(len(x))]
plt.scatter(x,y,s = s)
plt.show()
images是matplotlib中绘制image图像的类,其中最常用的imshow可以根据数组绘制成图像,它的构造函数为:
class matplotlib.image.AxesImage(ax, cmap=None, norm=None, interpolation=None, origin=None, extent=None, filternorm=True, filterrad=4.0, resample=False, **kwargs)
imshow根据数组绘制图像,其语法为:
matplotlib.pyplot.imshow(X, cmap=None, norm=None, aspect=None, interpolation=None, alpha=None, vmin=None, vmax=None, origin=None, extent=None, shape=, filternorm=1, filterrad=4.0, imlim=, resample=None, url=None, *, data=None, **kwargs)
使用imshow画图时首先需要传入一个数组,数组对应的是空间内的像素位置和像素点的值,interpolation参数可以设置不同的差值方法,具体效果如下:
#用scatter绘制散点图
x = [0,2,4,6,8,10]
y = [10]*len(x)
s = [20*2**n for n in range(len(x))]
plt.scatter(x,y,s = s)
plt.show()
import matplotlib.pyplot as plt
import numpy as np
methods = [None, 'none', 'nearest', 'bilinear', 'bicubic', 'spline16',
'spline36', 'hanning', 'hamming', 'hermite', 'kaiser', 'quadric',
'catrom', 'gaussian', 'bessel', 'mitchell', 'sinc', 'lanczos']
grid = np.random.rand(4,4)
fig,axs = plt.subplots(nrows=3, ncols=6,figsize = (9,6),subplot_kw={'xticks' :[],'yticks':[]})
for ax,interp_method in zip(axs.flat,methods):
ax.imshow(grid,interpolation = interp_method,cmap = 'viridis')
ax.set_title(str(interp_method))
plt.tight_layout()
plt.show()
容器会包含一些基本元素,并且容器还有它自身的属性。
matplotlib.figure.Figure是Artist 最顶层的container-对象容器,它包含了图表中的所有元素。一张图表的背景就是在Figure.patch的一个矩形Rectangle。当我们向图表添加**Figure.add_subplot()或者Figure.add_axes()**元素时,这些都会被添加到Figure.axes列表中。
fig = plt.figure()
ax1 = fig.add_subplot(211)
ax2 = fig.add_axes([0.1,0.1,0.7,0.3])#位置参数,四个数分别代表了(left,bottom,width,height)
print(ax1)
print(fig.axes)#fig.axes中包含了subplot和axes两个实例,刚刚添加的
由于Figure维持了current axes,因此不应该手动的从Figure.axes列表中添加删除元素,而是要通过Figure.add_subplot()、Figure.add_axes()来添加元素,通过Figure.delaxes()来删除元素。但是可以迭代或者访问Figure.axes中的Axes,然后修改这个Axes的属性。如遍历axes里面的内容,并且添加网格线:
fig = plt.figure()
ax1 = fig.add_subplot(211)
for ax in fig.axes:#遍历
ax.grid(True)#添加网格线
Figure也有它自己的text、line、patch、image。可以直接通过add primitive语句直接添加。但是注意Figure默认的坐标系是以像素为单位,可能需要转换成figure坐标系:(0,0)表示左下点,(1,1)表示右上点。
Figure容器的常见属性有:
matplotlib.axes.Axes是matplotlib的核心。大量的用于绘图的Artist存放在它内部,并且它有许多辅助方法来创建和添加Artist给它自己,而且它也有许多赋值方法来访问和修改这些Artist。和Figure容器类似,Axes包含了一个patch属性,对于笛卡尔坐标系而言,它是一个Rectangle;对于极坐标而言,它是一个Circle。这个patch属性决定了绘图区域的形状、背景和边框。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
fig = plt.figure()
ax = fig.add_subplot(111)
rect = ax.patch #axes的patch是一个Rectangle实例
rect.set_facecolor("green")
Axes有许多方法用于绘图,如.plot()、.text()、.hist()、.imshow()等方法用于创建大多数常见的primitive(如Line2D,Rectangle,Text,Image等等)。
Subplot就是一个特殊的Axes,其实例是位于网格中某个区域的Subplot实例。其实你也可以在任意区域创建Axes,通过Figure.add_axes([left,bottom,width,height])来创建一个任意区域的Axes,其中left,bottom,width,height都是[0,1]之间的浮点数,代表了相对于Figure的坐标。
不应该直接通过Axes.lines和Axes.patches列表来添加图表。因为当创建或添加一个对象到图表中时,Axes会做许多自动化的工作:它会设置Artist中figure和axes的属性,同时默认Axes的转换;它也会检视Artist中的数据,来更新数据结构,这样数据范围和呈现方式可以根据作图范围自动调整。可以使用Axes的辅助方法.add_line()和.add_patch()方法来直接添加。
Axes还包含两个最重要的Artist container:
Axes容器的常见属性有:
matplotlib.axis.Axis实例处理tick line、grid line、tick label以及axis label的绘制,它包括坐标轴上的刻度线、刻度label、坐标网格、坐标轴标题。通常你可以独立的配置y轴的左边刻度以及右边的刻度,也可以独立地配置x轴的上边刻度以及下边的刻度。刻度包括主刻度和次刻度,它们都是Tick刻度对象。
Axis也存储了用于自适应,平移以及缩放的data_interval和view_interval。它还有Locator实例和Formatter实例用于控制刻度线的位置以及刻度label。每个Axis都有一个label属性,也有主刻度列表和次刻度列表。这些ticks是axis.XTick和axis.YTick实例,它们包含着line primitive以及text primitive用来渲染刻度线以及刻度文本。
刻度是动态创建的,只有在需要创建的时候才创建(比如缩放的时候)。Axis也提供了一些辅助方法来获取刻度文本、刻度线位置等等。常见的如下:
#不用print,直接显示结果
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
fig,ax = plt.subplots()
x = range(5)
y = [2,5,7,8,10]
plt.plot(x,y,'-')
axis = ax.xaxis #axis为X轴对象
axis.get_ticklocs() #获取刻度线位置
axis.get_ticklabels() #获取刻度label列表(一个Text实例的列表),可以通过minor=True|False关键字参数控制输出minor还是major的tick label。
axis.get_ticklines() # 获取刻度线列表(一个Line2D实例的列表),可以通过minor=True|False关键字参数控制输出minor还是major的tick line。
axis.get_data_interval()# 获取轴刻度间隔
axis.get_view_interval()# 获取轴视角(位置)的间隔
fig = plt.figure() #创建一个新图表
rect = fig.patch #矩形实例并将其设为黄色
rect.set_facecolor("lightgoldenrodyellow")
ax1 = fig.add_axes([0.1,0.3,0.4,0.4]) #创建一个axes对象,从(0.1,0.3)的位置开始,宽和高都为0.4
rect = ax1.patch #ax1的矩形设为灰色
rect.set_facecolor("lightslategray")
for label in ax1.xaxis.get_ticklabels():
#调用x轴刻度标签实例,是一个text实例
label.set_color("red") #颜色
label.set_rotation(45) #旋转角度
label.set_fontsize(16) #字体大小
for line in ax1.yaxis.get_ticklines():
#调用y轴刻度线条实例,是一个Line2D实例
line.set_color("green") #颜色
line.set_markersize(25) #marker大小
line.set_markeredgewidth(2) #marker粗细
plt.show()
matplotlib.axis.Tick是从Figure到Axes到Axis到Tick中最末端的容器对象。Tick包含了tick、grid line实例以及对应的label。所有的这些都可以通过Tick的属性获取,常见的tick属性有:
例子:将Y轴右边轴设为主轴,并将标签设置为美元符号且为绿色。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
fig,ax = plt.subplots()
ax.plot(100*np.random.rand(20))
#设置ticker的显示格式
formatter = matplotlib.ticker.FormatStrFormatter("$%1.2f")
ax.yaxis.set_major_formatter(formatter)
#设置ticker的参数,右侧为主轴,颜色为绿色
ax.yaxis.set_tick_params(which = "major",labelcolor = "green",labelleft = False,labelright = True);
参考资料:https://datawhalechina.github.io/fantastic-matplotlib/%E7%AC%AC%E4%BA%8C%E5%9B%9E%EF%BC%9A%E8%89%BA%E6%9C%AF%E7%94%BB%E7%AC%94%E8%A7%81%E4%B9%BE%E5%9D%A4/index.html