本主题专门讲解Figure的设计结构与Figure对象的应用:
- Figure对象的创建与相关参数;
- Figure的坐标轴管理;
一、Figure对象创建与相关参数
1. 创建Figure对象
%matplotlib inline
import matplotlib.pyplot as plt
#coding=utf-8
import matplotlib.pyplot as plt
#建议不要使用Figure构造器创建Figure对象
fig=plt.figure()
fig.show(warn=False)
<Figure size 432x288 with 0 Axes>
有兴趣的可以跟踪pyplot模块的figure函数,可以完整看见Figure的创建过程,由FigureManager创建与管理的。
默认情况下没有Axes,就没有图形显式。
2. 创建Figure对象的参数-figure函数参数
%matplotlib inline
import matplotlib.pyplot as plt
#建议不要使用Figure构造器创建Figure对象
fig=plt.figure()
fig.show(warn=False)
<Figure size 432x288 with 0 Axes>
pylot的figure函数声明如下:
matplotlib.pyplot.figure(num=None, figsize=None, dpi=None, facecolor=None, edgecolor=None, frameon=True, FigureClass=<class 'matplotlib.figure.Figure'>, clear=False, **kwargs)
num : integer or string, optional, default: None
这是Figure的ID,类型可以是整数或者字符串,缺省值None;
|-1)如果值为None,则创建新窗体,按照递增方式赋值一个ID作为num,并返回该Figure对象;
|-2)如果提供num为整数,并且num表示的ID存在,则激活该Figure对象,并返回Figure对象的引用。
|-3)如果提供num为整数,并且num表示的ID不存在,则创建新窗体,赋值ID为num,并返回该Figure对象;
|-4)如果提供num为字符串,创建方式与整数(存在与不存在)一样,但与整数不同的是字符串num会被用来作为窗体的标题,ID就不再是整数形式。
figsize : tuple of integers, optional, default: None
(高度,宽度)单位为英寸,缺省值由rcParams\["figure.figsize"\] = \[6.4, 4.8\]设置
dpi : integer, optional, default: None
分辨率:每英寸的像素值。缺省值由rcParams\["figure.dpi"\] = 100设置.
facecolor :
背景颜色,可以使用元组表示,也可以使用字符表示,缺省值由rcParams\["figure.facecolor"\] = 'w'设置.
edgecolor :
边界颜色,可以使用元组表示,也可以使用字符表示,缺省值由rcParams\["figure.edgecolor"\] = 'w'设置.
frameon : bool, optional, default: True
控制是否绘制、Figure的框架。
FigureClass : subclass of Figure
用来创建定制的Figure对象。
clear: bool, optional, default: False
如果Figure存在,则清除原来的内容,当num不存在,这个参数没有用。
注意:
|-(1)最后一个**kwargs 参数实际说明figure函数支持matplotlib中与figure有关的所有参数。
|-(2)由于字符的颜色很难记忆,表示颜色的能力也有限,下面我采用(r,g,b,a)格式表示颜色。
%matplotlib inline
import matplotlib.pyplot as plt
#建议不要使用Figure构造器创建Figure对象
fig=plt.figure(
num='岗位分析趋势图',
figsize=(5.5,3.5),
dpi=100,
facecolor=(0,1,0,1),
edgecolor=(1,0,0,1),
frameon=True,
linewidth=1 #这个参数是属于kwargs的。支持所有与figure参数有关的属性。
)
plt.plot(1,1)
fig.show(warn=False)
在独立窗体中显示,需要添加一行代码:
plt.show()
运行效果如下:
从上述输出可以看出,linewidth不在其中,这个参数通过kwargs传递给Figure构造器。除了全局属性,影响到Figure的参数的,需要从Figure构造器获取。下面是Figure构造器的声明情况:
def __init__(self,
figsize=None,
dpi=None,
facecolor=None,
edgecolor=None,
#=============================================
linewidth=0.0,
#=============================================
frameon=None,
subplotpars=None, # default to rc
tight_layout=None, # default to rc figure.autolayout
constrained_layout=None, # default to rc
#figure.constrained_layout.use
):
其中还有几个属性subplotspars与tight_layout,constrained_layout等几个参数,也可以在figure函数中使用,这里只有linewidth不在全局参数中。
注意:在figure中linewidth默认值是0。
3. 创建Figure对象的参数-全局参数
上面使用的参数,除linewidth外,实际上都可以使用全局参数来设置,这样可以简化每次调用figure的重复劳动。这些属性很难记,可以通过查文档来获取,也可以写一个程序来获取这些属性值。
与figure有关的参数:
#coding=utf-8
import matplotlib
for key in matplotlib.rcParams.keys():
if 'figure' in key:
print(key,':',matplotlib.rcParams[key])
figure.autolayout : False
figure.constrained_layout.h_pad : 0.04167
figure.constrained_layout.hspace : 0.02
figure.constrained_layout.use : False
figure.constrained_layout.w_pad : 0.04167
figure.constrained_layout.wspace : 0.02
figure.dpi : 72.0
figure.edgecolor : (1, 1, 1, 0)
figure.facecolor : (1, 1, 1, 0)
figure.figsize : [6.0, 4.0]
figure.frameon : True
figure.max_open_warning : 20
figure.subplot.bottom : 0.125
figure.subplot.hspace : 0.2
figure.subplot.left : 0.125
figure.subplot.right : 0.9
figure.subplot.top : 0.88
figure.subplot.wspace : 0.2
figure.titlesize : large
figure.titleweight : normal
下面代码是显示与所有linewidth有关的属性的缺省值。
for key in matplotlib.rcParams.keys():
if 'linewidth' in key:
print(key,":",matplotlib.rcParams[key])
axes.linewidth : 0.8
boxplot.boxprops.linewidth : 1.0
boxplot.capprops.linewidth : 1.0
boxplot.flierprops.linewidth : 1.0
boxplot.meanprops.linewidth : 1.0
boxplot.medianprops.linewidth : 1.0
boxplot.whiskerprops.linewidth : 1.0
grid.linewidth : 0.8
hatch.linewidth : 1.0
lines.linewidth : 1.5
patch.linewidth : 1.0
下面使用全局参数创建Figure对象。
import matplotlib.pyplot as plt
import matplotlib as mpl
#全局参数设置
mpl.rcParams['figure.figsize']=(5.5,3.5)
mpl.rcParams['figure.dpi']=100
mpl.rcParams['figure.facecolor']=(1,1,0,1)
mpl.rcParams['figure.edgecolor']=(1,0,1,1)
mpl.rcParams['figure.frameon']=True
#创建Figure对象
fig=plt.figure(num='岗位分析趋势图',linewidth=3)
plt.plot(1,1)
fig.show(warn=False)
plt.show() #在不需要窗体的情况下,可以不使用这种方式显示。
二、Figure对象与坐标轴
Figure对象提供两个函数添加坐标轴:
|- add_axes ( *args, **kwargs ) :返回Axes对象或者子类对象。
|- add_subplot ( *args, **kwargs ):返回axes.SubplotBase对象(也是Axes的子类)或者其他Axes的子类对象
1. 使用add_axes添加坐标轴
1.1. add_axes的核心参数*args说明:
(1)rect : sequence of float
新坐标参数,参数形式为\[left, bottom, width, height\] 参数为分数。
(2)projection : {None, 'aitoff', 'hammer', 'lambert', 'mollweide', 'polar', 'rectilinear', str}, optional
坐标轴类型,使用字符串表示,缺省值是矩形线性坐标轴.
(3)polar : boolean, optional
是否是极坐标,True表示极坐标,等价于projection='polar'.
(4)sharex, sharey : Axes, optional
指定共享其他坐标轴对象的属性,包含相同的界限(limits), 刻度(ticks), 与比例(scale)
(5)label : str
坐标轴的标签,用来唯一标示坐标轴的ID,不用于显示。
下面是一个例子:
注意:其中第一个参数,不能带形式参数,是必须的参数值,用来指定坐标的区域。
import matplotlib.pyplot as plt
#建议不要使用Figure构造器创建Figure对象
fig=plt.figure(num='岗位分析趋势图',linewidth=1)
axes=fig.add_axes(
[0,0,1,1],
projection='polar',#{None, 'aitoff', 'hammer', 'lambert', 'mollweide', 'polar', 'rectilinear', str}
label='坐标轴标签'
)
fig.show(warn=False)
绘制一个标准坐标轴:·
import matplotlib.pyplot as plt
#建议不要使用Figure构造器创建Figure对象
fig=plt.figure(num='岗位分析趋势图',linewidth=1)
axes=fig.add_axes(
[0,0,1,1],
projection='rectilinear',#{None, 'aitoff', 'hammer', 'lambert', 'mollweide', 'polar', 'rectilinear', str}
label='坐标轴标签'
)
fig.show(warn=False)
【涨姿势时刻】请大家猜猜:'aitoff', 'hammer', 'lambert', 'mollweide'都是什么坐标!
1.2.add_axes的参数**kwargs说明:
属性 | 属性描述 | |
---|---|---|
adjustable | {'box', 'datalim'} | |
agg_filter | a filter function, which takes a (m, n, 3) float array and a dpi value, and returns a (m, n, 3) array | |
alpha | float | |
anchor | 2-tuple of floats or {'C', 'SW', 'S', 'SE', ...} | |
animated | bool | |
aspect | {'auto', 'equal'} or num | |
autoscale_on | bool | |
autoscalex_on | bool | |
autoscaley_on | bool | |
axes_locator | Callable[[Axes, Renderer], Bbox] | |
axisbelow | bool or 'line' | |
clip_box | Bbox | |
clip_on | bool | |
clip_path | [(Path, Transform) | Patch\ | None] |
contains | callable | |
facecolor | color | |
fc | color | |
figure | Figure | |
frame_on | bool | |
gid | str | |
in_layout | bool | |
label | object | |
navigate | bool | |
navigate_mode | unknown | |
path_effects | AbstractPathEffect | |
picker | None or bool or float or callable | |
position | [left, bottom, width, height] or Bbox | |
rasterization_zorder | float or None | |
rasterized | bool or None | |
sketch_params | (scale: float, length: float, randomness: float) | |
snap | bool or None | |
title | str | |
transform | Transform | |
url | str | |
visible | bool | |
xbound | unknown | |
xlabel | str | |
xlim | (left: float, right: float) | |
xmargin | float greater than -0.5 | |
xscale | {"linear", "log", "symlog", "logit", ...} | |
xticklabels | List[str] | |
xticks | list | |
ybound | unknown | |
ylabel | str | |
ylim | (bottom: float, top: float) | |
ymargin | float greater than -0.5 | |
yscale | {"linear", "log", "symlog", "logit", ...} | |
yticklabels | List[str] | |
yticks | list | |
zorder | float |
【例子-1】:指定标题(title)例子
import matplotlib.pyplot as plt
#建议不要使用Figure构造器创建Figure对象
fig=plt.figure('技术趋势图')
ax1=fig.add_axes(
[0.1,0.1,0.8,0.8],label='趋势图',projection="rectilinear",
fc=(1,0,0,1),
title="趋势图"
)
fig.show(warn=False)
plt.show()
其中汉字问题的解决帮办法:
(1**)获取字体配置文件与目录;
(2)拷贝汉字字体文件到配置下面字体库目录一般是fonts/ttf目录;
(3)修改配置文件:
下面是获取字体配置与存放目录代码:
import matplotlib as mpl
#获取配置文件
print(mpl.get_configdir())
print(mpl.matplotlib_fname())
/Users/yangqiang/.matplotlib
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/matplotlib/mpl-data/matplotlibrc
下面是字体设置后的效果:
下面是使用代码控制字体:(由于ipython缓冲的原因,如果没有效果,建议重启ipython notebook!)
import matplotlib.pyplot as plt
import matplotlib
#建议不要使用Figure构造器创建Figure对象
matplotlib.rcParams['font.family']='Microsoft Yahei'
fig=plt.figure('技术趋势图')
ax1=fig.add_axes(
[0.1,0.1,0.8,0.8],label='趋势图',projection="rectilinear",
fc=(1,0,0,1),
title="趋势图"
)
fig.show(warn=False)
plt.show()
【例子-2】:坐标轴指定标尺(xlabel,xlim,xscale)的例子
import matplotlib.pyplot as plt
#建议不要使用Figure构造器创建Figure对象
fig=plt.figure('技术趋势图')
ax1=fig.add_axes(
[0.1,0.1,0.8,0.8],
title="趋势图",
xlabel='x坐标',ylabel='y坐标',
xlim=(0.2,0.6),ylim=(0.4,0.6),
xscale='log',yscale='linear',
)
fig.show(warn=False)
plt.show()
【例子-3】:坐标轴指定刻度(xticklabels)的例子
当指定scale的值为一些特殊的值,下面几个属性就可能没有效果,所以下面例子设置xscale与yscale的值需要小心点。在下面例子中,把xscale指定为log模式,就不会显示刻度。
import matplotlib.pyplot as plt
#建议不要使用Figure构造器创建Figure对象
fig=plt.figure('技术趋势图')
ax1=fig.add_axes(
[0.1,0.1,0.8,0.8],
title="趋势图",
xlabel='x坐标',ylabel='y坐标',
xlim=(0.2,0.6),ylim=(0.4,0.6),
xscale='log',yscale='linear',
xticklabels=['a','b','c','d','e'],yticklabels=['A','B','C','D','E','F']
)
fig.show(warn=False)
plt.show()
【例子-4】使用边界(margin)的例子
import matplotlib.pyplot as plt
#建议不要使用Figure构造器创建Figure对象
fig=plt.figure('技术趋势图')
ax1=fig.add_axes(
[0.1,0.1,0.8,0.8],
title="趋势图",
xlabel='x坐标',ylabel='y坐标',
#xlim=(0.2,0.6),ylim=(0.4,0.6),
xscale='log',yscale='linear',
#xticklabels=['a','b','c'],yticklabels=['A','B','C','D','E','F'],
ymargin=-0.4
)
fig.show(warn=False)
plt.show()
【例子-05】 使用刻度(xticks)的例子
import matplotlib.pyplot as plt
#建议不要使用Figure构造器创建Figure对象
fig=plt.figure('技术趋势图')
ax1=fig.add_axes(
[0.1,0.1,0.8,0.8],
title="趋势图",
xlabel='x坐标',ylabel='y坐标',
xticks=[1,2,3,4,5,6],yticks=[1,2,3],
xticklabels=['a','b','c'],
#yticklabels=['A','B','C','D','E','F'],
ymargin=-0.2
)
fig.show(warn=False)
plt.show()
坐标轴的几个属性,相互之间是有影响的,有的是相互矛盾的,大家可以根据常理理解,掌握其中矛盾的地方。
1.3. 坐标轴的删除与添加
可以通过如下函数删除坐标轴。
|-fig.delaxes(ax)
也可以直接添加:
|-fig.add_axes(ax)
我们也可以直接使用Axes类构造坐标轴对象。其中的核心参数都与上面一样。
1.4. 使用定制构造的Axes对象
Axes的继承结构:
|-Artist
|-_AxesBase
|-Axes
Axes的构造器定义:
class matplotlib.axes.Axes(
fig,
rect,
facecolor=None,
frameon=True,
sharex=None, sharey=None,
label='',
xscale=None, yscale=None,
**kwargs)
上面参数的含义也是显而易见的。
#coding=utf-8
import matplotlib.pyplot as plt
fig=plt.figure('技术趋势图')
ax1=plt.Axes(
fig,
[0.1,0.1,0.8,0.8],
title="趋势图",
xlabel='x坐标',ylabel='y坐标',
xticks=[1,2,3,4,5,6],yticks=[1,2,3],
xticklabels=['a','b','c'],
#yticklabels=['A','B','C','D','E','F'],
ymargin=-0.2
)
fig.add_axes(ax1)
fig.show(warn=False)
plt.show()
2. 使用add_subplot添加坐标轴
add_subplot函数本质与上面一样,只是提供了更加灵活的方式。
(1)函数定义如下:
|-add_subplot(*args, **kwargs)
(2)调用方式如下:
|-add_subplot(nrows, ncols, index, **kwargs)
|-add_subplot(pos, **kwargs)
|-add_subplot(ax),这个函数与add_axes使用方法一样
其他参数与add_axes函数一样。下面直接使用例子说明三种调用方式:
2.1. add_subplot(nrows, ncols, index, **kwargs)调用方式
这三个参数用来产生多个坐标轴,坐标轴个数有nrows ncols;
|-nrows:坐标轴个数的行数
|-ncols:坐标轴个数的列数
|-index:坐标轴的位置
位置下标从1开始
#coding=utf-8
import matplotlib.pyplot as plt
fig=plt.figure('技术趋势图')
fig.add_subplot(2,2,1)
fig.add_subplot(2,2,2)
fig.add_subplot(2,2,3)
fig.add_subplot(2,2,4)
fig.show(warn=False)
plt.show()
2.2. add_subplot(pos, **kwargs)调用方式
pos参数用来产生多个坐标轴,pos必须是三位数的整数, ,,;
|-第一位数表示nrows
|-第二位数表示ncols
|-第三位数表示index
#coding=utf-8
import matplotlib.pyplot as plt
fig=plt.figure('技术趋势图')
fig.add_subplot(221)
fig.add_subplot(222)
fig.add_subplot(223)
fig.add_subplot(224)
fig.show(warn=False)
plt.show()
2.2. 坐标占多行与多列的情况
【例子-1】占两列的情况
#coding=utf-8
import matplotlib.pyplot as plt
fig=plt.figure('技术趋势图')
'''
fig.add_subplot(2,2,1)
fig.add_subplot(2,2,2)
fig.add_subplot(2,2,3)
fig.add_subplot(2,2,4)
'''
fig.add_subplot(2,1,1)
fig.add_subplot(2,2,3)
fig.add_subplot(2,2,4)
fig.show(warn=False)
plt.show()
【例子-2】占两行的情况
#coding=utf-8
import matplotlib.pyplot as plt
fig=plt.figure('技术趋势图')
fig.add_subplot(1,2,1)
fig.add_subplot(2,2,2)
fig.add_subplot(2,2,4)
fig.show(warn=False)
plt.show()
【例子-3】占两行,第二列的情况
#coding=utf-8
import matplotlib.pyplot as plt
fig=plt.figure('技术趋势图')
fig.add_subplot(1,2,2)
fig.add_subplot(2,2,1)
fig.add_subplot(2,2,3)
fig.show(warn=False)
plt.show()
附录
1. 本文的代码列表
|-plt02_figure.py
|-plt02_Axes_cls.py
|-plt02_add_axes.py
|-plt02_add_plot.py
2. 下载地址:
|-https://github.com/QiangAI/AICode/tree/master/matplot
下一个主题开始图形绘制。