Python绝技:运用Python成为顶级数据工程师
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.2.4 Matplotlib

Matplotlib是绘制高质量2D图像的Python库。可以方便地绘制折线图、柱状图、散点图等多种图形;丰富的样式和灵活的标注可以更加直观地呈现图像;此外,Matplotlib的API的设计简洁清晰,官网的文档详尽易懂。这些特点使它成为Python实现数据可视化的一把利器。

官网手册

http://matplotlib.org/contents.html

内容概述

表2-4 两种类型的API使用

示例版本

版本号:1.53

日期:2016.12.05

示例讲解

用两种类型的API可以做出如图2.1所示的图像,请注意代码中尽量使用详尽的注释。读者可依据代码体会两种绘图思想。更多的细节处理可参考官网去学习与实现。

图2.1 Matplotlib绘制cosine图像

面向过程作图

面向过程作图是指利用pyplot包提供的函数命令来逐步绘图。步骤如下:先创建figure,类似于图纸;再调用函数创建坐标系,绘制图像;最后调整刻度及标签、添加注释并依次绘制图像的各个细节。

pyplot的绘图命令只是对面向对象做图接口的封装,实现类似MATLAB的作图方式。它的代码示例如下:

      import numpy as np
      import matplotlib.pyplot as plt
      #X轴、Y轴数据
      X = np.linspace(-1.5 * np.pi, 2 * np.pi, 256, endpoint=True)
      C= np.cos(X)
      #plt创建图纸
      plt.figure(figsize=(10, 4), dpi=100)
      #plt定位坐标
      ax = plt.subplot(111)
      #调整坐标轴
      ax.spines['right'].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('left')
      ax.spines['left'].set_position(('data',0))
      #plt画图
      plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-", label=
  "cosine")
      #axis对象设置数据轴宽度、修改刻度、刻度标签
      plt.xlim(X.min()*1.1, X.max()*1.1)
      plt.xticks([-1.5 * np.pi, -np.pi, -np.pi/2, 0, np.pi/2, np.pi, 1.5
  * np.pi, 2*np.pi],
                [r'$-3/2\pi$',    r'$-\pi$',    r'$-\pi/2$',    r'$0$',
  r'$+\pi/2$', r'$+\pi$', r'$+3/2\pi$', r'$+2\pi$'])
      plt.ylim(C.min()*1.1, C.max()*1.1)
      plt.yticks([-1, +1],
                [r'$-1$', r'$+1$'])
      #plt绘制注释
      t = 2*np.pi/3
      plt.plot([t, t], [0, np.cos(t)], color ='red', linewidth=1.5, linestyle
  ="--")
      plt.scatter([t, ], [np.cos(t), ], 50, color ='blue')
      plt.annotate(r'$\cos(\frac{2\pi}{3})=-\frac{1}{2}$',
      xy=(t, np.cos(t)),  xycoords='data',
      xytext=(-90, -50), textcoords='offsetpoints', fontsize=16,
      arrowprops=dict(arrowstyle="->", connectionstyle="arc3, rad=.2"))
      #plt调整图例
      plt.legend(loc='upperleft', frameon=False)
      #plt展示图像
      plt.show()

面向对象作图

Matplotlib提出了Object Container(对象容器)的概念,它有Figure、Axes、Axis、Tick四种类型的对象容器。Figure负责图像大小、位置等操作;Axes负责坐标系位置、绘图等操作;Axis负责坐标轴的操作;Tick负责刻度的相关操作。

四种对象容器之间是层层包含的关系。Figure包含Axes、Axes包含Axis、Axis包含Tick。我们用一种不太确切但是形象的方式来说明“包含”的含义以及作图的过程:Figure定位图像大小、位置之后返回一个Axes对象;Axes对象绘制图片、调整坐标轴位置之后发回一个Axis对象;Axis对象又可以来设置XY坐标的显示长度,刻度以及刻度标签等,之后返回Tick对象;Tick对象则可以格式化各个刻度的样式等。代码示例如下。

        import numpy as np
        import matplotlib.py plot as plt
        #X轴、Y轴数据
        X = np.linspace(-1.5 * np.pi, 2 * np.pi, 256, endpoint=True)
        C = np.cos(X)
        #创建figure对象
        fig = plt.figure(figsize=(10,4), dpi=100, tight_layout=True)
        #figure对象获取axes对象
        ax  = fig.add_subplot(111)
        #axes对象绘图
        ax.plot(X,   C,   color="blue",   linewidth=2.5,   linestyle="-",
    label="cosine")
        #axes对象调整坐标轴
        ax.spines['right'].set_color('none')
        ax.spines['top'].set_color('none')
        ax.spines['bottom'].set_position(('data',0))
        ax.spines['left'].set_position(('data',0))
        #axes对象获取axis对象
        xAxis = ax.get_xaxis()
        yAxis = ax.get_yaxis()
        #axis对象设置数据轴宽度、修改刻度、刻度标签
        xAxis.set_data_interval(X.min()*1.1, X.max()*1.1)
        xAxis.set_ticks([-1.5 * np.pi, -np.pi, -np.pi/2, 0, np.pi/2, np.pi,
    1.5 * np.pi, 2*np.pi])
        xAxis.set_ticklabels([r'$-3/2\pi$', r'$-\pi$', r'$-\pi/2$', r'$0$',
    r'$+\pi/2$', r'$+\pi$', r'$+3/2\pi$', r'$+2\pi$'])
        yAxis.set_data_interval(C.min()*1.1, C.max()*1.1)
        yAxis.set_ticks([-1, +1])
        yAxis.set_ticklabels([r'$-1$', r'$+1$'])
        #axis对象设置刻度位置
        xAxis.set_ticks_position('bottom')
        yAxis.set_ticks_position('left')
        #figure添加ax2对象,与ax共用一个区域
        ax2  = fig.add_subplot(111)
        #axes对象作图,以及添加注释
        t = 2*np.pi/3
        ax2.plot([t, t], [0, np.cos(t)], color ='red', linewidth=1.5, linestyle=
    "--")
        ax2.scatter([t, ], [np.cos(t), ], 50, color ='blue')
        ax2.annotate(r'$\cos(\frac{2\pi}{3})=-\frac{1}{2}$',
        xy=(t, np.cos(t)),  xycoords='data',
        xytext=(-90, -50), textcoords='offsetpoints', fontsize=16,
        arrowprops=dict(arrowstyle="->", connectionstyle="arc3, rad=.2"))
        #axes对象添加图例
        ax.legend(loc='upperleft', frameon=False)
        #展示图像
        fig.show()