美文网首页
9.1 matplotlib API入门

9.1 matplotlib API入门

作者: 米小河123 | 来源:发表于2020-03-17 14:13 被阅读0次

    第9章 绘图和可视化
    绘图是数据分析中最重要的工作之一。它可能是探索过程的一部分,例如,帮助我们找出异常值、必要的数据转换、得出有关模型的idea等。另外,做一个可交互的数据可视化也许是工作的最终目标。Python有很多库进行静态或动态的数据可视化,但我这里主要关注matplotlib和基于它的库。
    matplotlib是一个用于创建出版质量图表的桌面绘图包(主要是2D方面)。matplotlib和IPython社区进行合作,简化了从IPython shell(包括现在的Jupyter notebook)进行交互式绘图。matplotlib支持各种操作系统上许多不同的GUI后端,而且还能将图片导出为各种常见的矢量(vector)和光栅(raster)图:PDF、SVG、JPG、PNG、BMP、GIF等。除了几章,本书中的大部分图都是用它生成的。
    随着时间的发展,matplotlib衍生出了多个数据可视化的工具集,它们使用matplotlib作为底层。其中之一是seabrorn,本章后面会学习它。
    学习本章代码案例的最简单方法是在Jupyter notebook进行交互式绘图。在Jupyter notebook中执行下面的语句:

    %matplotlib notebook
    

    9.1 matplotlib API入门
    matplotlib的通常引入约定是:

    In [11]: import matplotlib.pyplot as plt
    

    在Jupyter中运行%matplotlib notebook(或在IPython中运行%matplotlib),就可以创建一个简单的图形。如果一切设置正确,会看到图9-1:

    In [12]: import numpy as np
    
    In [13]: data = np.arange(10)
    
    In [14]: data
    Out[14]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    
    In [15]: plt.plot(data)
    
    图9-1 简单的线图

    虽然seaborn这样的库和pandas的内置绘图函数能够处理许多普通的绘图任务,但如果需要自定义一些高级功能的话就必须学习matplotlib API。

    笔记:虽然本书没有详细地讨论matplotlib的各种功能,但足以将你引入门。matplotlib的示例库和文档是学习高级特性的最好资源。

    Figure和Subplot
    matplotlib的图像都位于Figure对象中。你可以用plt.figure创建一个新的Figure:

    In [16]: fig = plt.figure()
    

    如果用的是IPython,这时会弹出一个空窗口,但在Jupyter中,必须再输入更多命令才能看到。plt.figure有一些选项,特别是figsize,它用于确保当图片保存到磁盘时具有一定的大小和纵横比。
    不能通过空Figure绘图。必须用add_subplot创建一个或多个subplot才行:

    In [17]: ax1 = fig.add_subplot(2, 2, 1)
    

    这条代码的意思是:图像应该是2*2的(即最多4张图),且当前选中的是4个subplot中的第一个(编号从1开始)。如果再把后面两个subplot也创建出来,最终得到的图像如图9-2所示:

    In [18]: ax2 = fig.add_subplot(2, 2, 2)
    
    In [19]: ax3 = fig.add_subplot(2, 2, 3)
    
    图9-2 带有三个subplot的Figure.png

    提示:使用Jupyter notebook有一点不同,即每个小窗重新执行后,图形会被重置。因此,对于复杂的图形,必须将所有的绘图命令存在一个小窗里。

    上面那些由fig.add_subplot所返回的对象是AxesSubplot对象,直接调用它们的实例方法就可以在其它空着的格子里面画图了,如图9-4所示:

    In [21]: ax1.hist(np.random.randn(100), bins=20, color='k', alpha=0.3)
    
    In [22]: ax2.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30))
    
    图9-4 继续绘制两次之后的图像.png

    你可以在matplotlib的文档中找到各种图表类型。
    创建包含subplot网格的figure是一个非常常见的任务,matplotlib有一个更为方便的方法plt.subplots,它可以创建一个新的figure,并返回一个含有已创建的subplot对象的Numpy数组:

    In [24]: fig, axes = plt.subplots(2, 3)
    
    In [25]: axes
    Out[25]: 
    array([[<matplotlib.axes._subplots.AxesSubplot object at 0x7fb626374048>,
            <matplotlib.axes._subplots.AxesSubplot object at 0x7fb62625db00>,
            <matplotlib.axes._subplots.AxesSubplot object at 0x7fb6262f6c88>],
           [<matplotlib.axes._subplots.AxesSubplot object at 0x7fb6261a36a0>,
            <matplotlib.axes._subplots.AxesSubplot object at 0x7fb626181860>,
            <matplotlib.axes._subplots.AxesSubplot object at 0x7fb6260fd4e0>]], dtype
    =object)
    

    这是非常实用的,因为可以轻松地对axes数组进行索引,就好像是一个二维数组一样,例如axes[0, 1]。你还可以通过sharex和sharey指定subplot应该具有相同地x轴和y轴。在比较相同范围的数据时,这也是非常实用的,否则,matplotlib会自动缩放各图表的界限。有关该方法的更多信息,请参见表9-1。

    表9-1 pyplot.subplots的选项.png

    调整subplot周围的间距
    默认情况下,matplotlib会在subplot外围留下一定的边距,并在subplot之间留下一定的间距。间距跟图像的高度和宽度有关,因此,如果你调整了图像大小(不管是编程还是手工),间距也会自动调整。利用figure的subplots_adjust方法可以轻而易举地修改间距,此外,它也是个顶级函数:

    subplots_adjust(left=None, bottom=None, right=None, top=None,
                    wspace=None, hspace=None)
    

    wspace和hspace用于控制宽度和高度的百分比,可以用作subplot之间的间距。下面是一个简单的例子,其中我将间距收缩到了0(如图9-5所示):

    fig, axes = plt.subplots(2, 2, sharex=True, sharey=True)
    for i in range(2):
        for j in range(2):
            axes[i, j].hist(np.random.randn(500), bins=50, color='k', alpha=0.5)
    plt.subplots_adjust(wspace=0, hspace=0)
    
    图9-5 各subplot之间没有间距.png
    不难看出,其中的轴标签重叠了。matplotlib不会检查标签是否重叠,所以对于这种情况,你只能自己设定刻度位置和刻度标签。后面几节将会详细介绍该内容。
    颜色、标记和线型
    matplotlib的plot函数接受一组X和Y坐标,还可以接受一个表示颜色和线型的字符串缩写。例如,要根据X和Y绘制绿色虚线,你可以执行如下代码:
    ax.plot(x, y, 'g--')
    

    这种在一个字符串中指定颜色和线型的方式非常方便。在实际中,如果你是用代码绘图,你可能不想通过处理字符串来获得想要的格式。通过下面这种更为明确的方式也能得到同样的效果:

    ax.plot(x, y, linestyle='--', color='g')
    

    常用的颜色可以使用颜色缩写,你也可以指定颜色码(例如,'#CECECE')。你可以通过查看plot的文档字符串查看所有线型的合集(在IPython和Jupyter中使用plot?)。
    线图可以使用标记强调数据点。因为matplotlib可以创建连续线图,在点之间进行插值,因此有时可能不太容易看出真实数据点的位置。标记也可以放到格式字符串中,但标记类型和线型必须放在颜色后面(见图9-6):

    In [30]: from numpy.random import randn
    
    In [31]: plt.plot(randn(30).cumsum(), 'ko--')
    
    图9-6 带有标记的线型图.png

    还可以将其写成更为明确的形式:

    plot(randn(30).cumsum(), color='k', linestyle='dashed', marker='o')
    

    在线型图中,非实际数据点默认是按线性方式插值的。可以通过drawstyle选项修改(见图9-7):

    In [33]: data = np.random.randn(30).cumsum()
    
    In [34]: plt.plot(data, 'k--', label='Default')
    Out[34]: [<matplotlib.lines.Line2D at 0x7fb624d86160>]
    
    In [35]: plt.plot(data, 'k-', drawstyle='steps-post', label='steps-post')
    Out[35]: [<matplotlib.lines.Line2D at 0x7fb624d869e8>]
    
    In [36]: plt.legend(loc='best')
    
    图9-7 不同drawstyle选项的线型图.png

    你可能注意到运行上面代码时有输出<matplotlib.lines.Line2D at ...>。matplotlib会返回引用了新添加的子组件的对象。大多数时候,你可以放心地忽略这些输出。这里,因为我们传递了label参数到plot,我们可以创建一个plot图例,指明每条使用plt.legend的线。

    笔记:你必须调用plt.legend(或使用ax.legend,如果引用了轴的话)来创建图例,无论你绘图时是否传递label标签选项。

    相关文章

      网友评论

          本文标题:9.1 matplotlib API入门

          本文链接:https://www.haomeiwen.com/subject/qvxsictx.html