MPL-02:使用Figure与Axes坐标轴管理

本主题专门讲解Figure的设计结构与Figure对象的应用:

  1. Figure对象的创建与相关参数;
  2. 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)

  有兴趣的可以跟踪pyplot模块的figure函数,可以完整看见Figure的创建过程,由FigureManager创建与管理的。
  默认情况下没有Axes,就没有图形显式。

2. 创建Figure对象的参数-figure函数参数

%matplotlib inline
import matplotlib.pyplot as plt
#建议不要使用Figure构造器创建Figure对象
fig=plt.figure()
fig.show(warn=False)

  pylot的figure函数声明如下:

matplotlib.pyplot.figure(num=None, figsize=None, dpi=None, facecolor=None, edgecolor=None, frameon=True, FigureClass=, 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)
MPL-02:使用Figure与Axes坐标轴管理_第1张图片
运行效果

  在独立窗体中显示,需要添加一行代码:

plt.show()

  运行效果如下:

MPL-02:使用Figure与Axes坐标轴管理_第2张图片
独立窗体显示

  从上述输出可以看出,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
                 ):

  其中还有几个属性subplotsparstight_layoutconstrained_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() #在不需要窗体的情况下,可以不使用这种方式显示。
MPL-02:使用Figure与Axes坐标轴管理_第3张图片
运行效果

二、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)
MPL-02:使用Figure与Axes坐标轴管理_第4张图片
采用的是极坐标运行效果

  绘制一个标准坐标轴:·

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)
MPL-02:使用Figure与Axes坐标轴管理_第5张图片
标准坐标轴

【涨姿势时刻】请大家猜猜:'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()
MPL-02:使用Figure与Axes坐标轴管理_第6张图片
有乱码的title属性效果

  其中汉字问题的解决帮办法:
    (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

  下面是字体设置后的效果:


MPL-02:使用Figure与Axes坐标轴管理_第7张图片
使用的是msyh.ttf字体文件效果

  下面是使用代码控制字体:(由于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()
MPL-02:使用Figure与Axes坐标轴管理_第8张图片
使用字体后刷新的效果

【例子-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()
MPL-02:使用Figure与Axes坐标轴管理_第9张图片
xlabel,xlim,xscale属性效果

【例子-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()
MPL-02:使用Figure与Axes坐标轴管理_第10张图片
xticklabels属性效果

【例子-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()
MPL-02:使用Figure与Axes坐标轴管理_第11张图片
margin属性效果,注意坐标轴的正负

【例子-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()
MPL-02:使用Figure与Axes坐标轴管理_第12张图片
xticks属性效果

  坐标轴的几个属性,相互之间是有影响的,有的是相互矛盾的,大家可以根据常理理解,掌握其中矛盾的地方。

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()
MPL-02:使用Figure与Axes坐标轴管理_第13张图片
使用Axes对象

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()
MPL-02:使用Figure与Axes坐标轴管理_第14张图片
多个坐标轴

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()
MPL-02:使用Figure与Axes坐标轴管理_第15张图片
使用pos形式的参数

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()
MPL-02:使用Figure与Axes坐标轴管理_第16张图片
占两列的情况

【例子-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()
MPL-02:使用Figure与Axes坐标轴管理_第17张图片
占两行的情况

【例子-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()
MPL-02:使用Figure与Axes坐标轴管理_第18张图片
占两行,第二列的情况

附录

  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


  下一个主题开始图形绘制。

你可能感兴趣的:(MPL-02:使用Figure与Axes坐标轴管理)