《scikit-learn机器学习常用算法原理及编程实战》—2.5.2 图形对象

举报
华章计算机 发表于 2019/05/31 16:33:48 2019/05/31
【摘要】 本书摘自《scikit-learn机器学习常用算法原理及编程实战》一书中的第2章,第2.5.2节,编著是黄永昌 .

2.5.2  图形对象

  在Matplotlib里,一个图形(figure)是指图片的全部可视区域,可以使用plt.figure()来创建。在一个图形里,可以包含多个子图(subplot),可以使用plt.subplot()来创建子图。子图按照网格形状排列显示在图形里,可以在每个子图上单独作画。坐标轴(Axes)和子图类似,唯一不同的是,坐标轴可以在图形上任意摆放,而不需要按照网格排列,这样显示起来更灵活,可以使用plt.axes()来创建坐标轴。

  当我们使用默认配置进行作画时,Matplotlib调用 plt.gca() 函数来获取当前的坐标轴,并在当前坐标轴上作画。plt.gca()函数调用plt.gcf()函数来获取当前图形对象,如果当前不存在图形对象,则会调用plt.figure()函数创建一个图形对象。

  plt.figure()函数有以下几个常用的参数。

* num:图形对象的标识符,可以是数字或字符串。当num所指定的图形存在时,直接返回这个图形的引用,如果不存在,则创建一个以这个num为标识符的新图形。最后把当前作画的图形切换到这个图形上。

* figsize:以英寸为单位的图形大小(width, height),是一个元组。

* dpi:指定图形的质量,每英寸多少个点。

  下面的代码创建了两个图形,一个是'sin',并且把正弦曲线画在这个图形上。然后创建了另外一个名称是'cos'的图形,并把余弦曲线画在这个图形上。接着切换到之前创建的'sin'图形上,把余弦图片也画在这个图形上。

  

  %matplotlib inline

  from matplotlib import pyplot as plt

  import numpy as np

  

  X = np.linspace(-np.pi, np.pi, 200, endpoint=True)

  C, S = np.cos(X), np.sin(X)

  

  plt.figure(num='sin', figsize=(16, 4))            # 创建 'sin' 图形

  plt.plot(X, S)                                    # 把正弦画在这个图形上

  plt.figure(num='cos', figsize=(16, 4))            # 创建 'cos' 图形

  plt.plot(X, C)                  # 把余弦画在这个图形上

  plt.figure(num='sin')            # 切换到 'sin' 图形上

  plt.plot(X, C)                  # 在原来的基础上,把余弦曲线也画在这个图形上

  print plt.figure(num='sin').number

  print plt.figure(num='cos').number

  

  执行结果如图2-9和图2-10所示。

image.png

图2-9  正弦曲线

image.png

图2-10  余弦曲线

  不同的图形可以单独保存为一个图片文件,但子图是指一个图形里分成几个区域,在不同的区域里单独作画,所有的子图最终都保存在一个文件里。plt.subplot()函数的关键参数是一个包含3个元素的元组,分别代表子图的行、列以及当前激活的子图序号。比如plt.subplot(2, 2, 1)表示把图表对象分成两行两列,激活第一个子图来作画。我们看一个网格状的子图的例子:

  

  %matplotlib inline

  from matplotlib import pyplot as plt

  

  plt.figure(figsize=(18, 4))

  plt.subplot(2, 2, 1)

  plt.xticks(())

  plt.yticks(())

  plt.text(0.5, 0.5, 'subplot(2,2,1)', ha='center', va='center',

          size=20, alpha=.5)

  

  plt.subplot(2, 2, 2)

  plt.xticks(())

  plt.yticks(())

  plt.text(0.5, 0.5, 'subplot(2,2,2)', ha='center', va='center',

          size=20, alpha=.5)

  

  plt.subplot(2, 2, 3)

  plt.xticks(())

  plt.yticks(())

  plt.text(0.5, 0.5, 'subplot(2,2,3)', ha='center', va='center',

          size=20, alpha=.5)

  

  plt.subplot(2, 2, 4)

  plt.xticks(())

  plt.yticks(())

  plt.text(0.5, 0.5, 'subplot(2,2,4)', ha='center', va='center',

          size=20, alpha=.5)

  

  plt.tight_layout()

  plt.show()

  

  输出的图形如图2-11所示。

image.png

图2-11  subplot输出的子图

  更复杂的子图布局,可以使用gridspec来实现,其优点是可以指定某个子图横跨多个列或多个行。

  

  %matplotlib inline

  from matplotlib import pyplot as plt

  import matplotlib.gridspec as gridspec

  

  plt.figure(figsize=(18, 4))

  G = gridspec.GridSpec(3, 3)

  

  axes_1 = plt.subplot(G[0, :])        # 占用第一行,所有的列

  plt.xticks(())

  plt.yticks(())

  plt.text(0.5, 0.5, 'Axes 1', ha='center', va='center', size=24, alpha=.5)

  

  axes_2 = plt.subplot(G[1:, 0])      # 占用第二行开始之后的所有行,第一列

  plt.xticks(())

  plt.yticks(())

  plt.text(0.5, 0.5, 'Axes 2', ha='center', va='center', size=24, alpha=.5)

  

  axes_3 = plt.subplot(G[1:, -1])      # 占用第二行开始之后的所有行,最后一列

  plt.xticks(())

  plt.yticks(())

  plt.text(0.5, 0.5, 'Axes 3', ha='center', va='center', size=24, alpha=.5)

  

  axes_4 = plt.subplot(G[1, -2])      # 占用第二行,倒数第二列

  plt.xticks(())

  plt.yticks(())

  plt.text(0.5, 0.5, 'Axes 4', ha='center', va='center', size=24, alpha=.5)

  

  axes_5 = plt.subplot(G[-1, -2])      # 占用倒数第一行,倒数第二列

  plt.xticks(())

  plt.yticks(())

  plt.text(0.5, 0.5, 'Axes 5', ha='center', va='center', size=24, alpha=.5)

  

  plt.tight_layout()

  plt.show()

  

  画出来的子图布局如图2-12所示。

image.png

图2-12  GridSpec

  坐标轴使用plt.axes()来创建,它用一个矩形来给坐标轴定位,矩形使用[left, bottom, width, height]来表达。其数据为图形对象对应坐标轴长度的百分比。

  

  %matplotlib inline

  from matplotlib import pyplot as plt

  

  plt.figure(figsize=(18, 4))

  

  plt.axes([.1, .1, .8, .8])

  plt.xticks(())

  plt.yticks(())

  plt.text(.2, .5, 'axes([0.1, 0.1, .8, .8])', ha='center', va='center',

          size=20, alpha=.5)

  

  plt.axes([.5, .5, .3, .3])

  plt.xticks(())

  plt.yticks(())

  plt.text(.5, .5, 'axes([.5, .5, .3, .3])', ha='center', va='center',

          size=16, alpha=.5)

  

  plt.show()

  

  画出来的图形如图2-13所示。

image.png

图2-13  坐标轴

  一个优美而恰当的坐标刻度对理解数据异常重要,Matplotlib内置提供了以下几个坐标刻度。

* NullLocater:不显示坐标刻度标签,只显示坐标刻度。

* MultipleLocator:以固定的步长显示多个坐标标签。

* FixedLocator:以列表形式显示固定的坐标标签。

* IndexLocator:以offset为启始位置,每隔base步长就画一个坐标标签。

* LinearLocator:把坐标轴的长度均分为numticks个数,显示坐标标签。

* LogLocator:以对数为步长显示刻度标签。

* MaxNLocator:从提供的刻度标签列表里,显示出最大不超过nbins个数的标签。

* AutoLocator:自动显示刻度标签。

  除了内置标签外,我们也可以继承matplotlib.ticker.Locator类来实现自定义样式的刻度标签。

  通过下面的代码把内置坐标刻度全部画出来,可以直观地观察到内置坐标刻度的样式。具体可参阅随书代码ch02.04.ipynb。

  

  %matplotlib inline

  from matplotlib import pyplot as plt

  import numpy as np

  

  def tickline():

      plt.xlim(0, 10), plt.ylim(-1, 1), plt.yticks([])

      ax = plt.gca()

      ax.spines['right'].set_color('none')

      ax.spines['left'].set_color('none')

      ax.spines['top'].set_color('none')

      ax.xaxis.set_ticks_position('bottom')

      ax.spines['bottom'].set_position(('data',0))

      ax.yaxis.set_ticks_position('none')

      ax.xaxis.set_minor_locator(plt.MultipleLocator(0.1))

      # 设置刻度标签的文本字体大小

      for label in ax.get_xticklabels() + ax.get_yticklabels():

          label.set_fontsize(16)

      ax.plot(np.arange(11), np.zeros(11))

      return ax

  

  locators = [

                  'plt.NullLocator()',

                  'plt.MultipleLocator(base=1.0)',

                  'plt.FixedLocator(locs=[0, 2, 8, 9, 10])',

                  'plt.IndexLocator(base=3, offset=1)',

                  'plt.LinearLocator(numticks=5)',

                  'plt.LogLocator(base=2, subs=[1.0])',

                  'plt.MaxNLocator(nbins=3, steps=[1, 3, 5, 7, 9, 10])',

                  'plt.AutoLocator()',

              ]

  

  n_locators = len(locators)

  

  # 计算图形对象的大小

  size = 1024, 60 * n_locators

  dpi = 72.0

  figsize = size[0] / float(dpi), size[1] / float(dpi)

  fig = plt.figure(figsize=figsize, dpi=dpi)

  fig.patch.set_alpha(0)

  

  

  for i, locator in enumerate(locators):

      plt.subplot(n_locators, 1, i + 1)

      ax = tickline()

      ax.xaxis.set_major_locator(eval(locator))      # 使用 eval 表达式:eval is evil

      plt.text(5, 0.3, locator[3:], ha='center', size=16)

  

  plt.subplots_adjust(bottom=.01, top=.99, left=.01, right=.99)

  plt.show()

  运用效果如图2-14所示。

image.png

图2-14  内置坐标刻度


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。