美文网首页
matplotlib 可视化的基本原理

matplotlib 可视化的基本原理

作者: 丰年的博客 | 来源:发表于2020-05-02 18:36 被阅读0次

    在平时使用matploglib的时候,将问题解决方法、使用心得、基本概念等等,都零零散散做了一些总结,但是一直没有系统的进行过整理。为了能够更好的巩固matplotlib的使用,将之前的总结进行一次系统化的梳理。

    为什么需要数据可视化?

    无论是工作,学习,生活中都会遇到各种数据:年度预算数据,项目人力成本数据,实验记录数据,投资收益等等。当直接面对各种数据的时候,无法直观的反映出各种数据间的关系,因此就需要借助各种图表来对数据进行可视化的展示。选择合理的数据图表,比用数据和文字描述更明了、更容易理解,将数据转换成图表的形式呈现,可以帮助我们更好地了解数据之间的关联关系及变化趋势,对问题的研究可以做出合理的推断和预测。
    使用不同的图表从不同的方面来阐述问题,从不同的角度表现相对的关系、数据与数据之间的联系,从而寻找问题更好的解决方法。
    如下图左表格中x,y的数据,单纯从数据中看无法直观的看出x,y之间的关系。但是从右图可以很直观的看出x,y之间为正相关。

    matplotlib简介

    matplotlib使用numpy进行数组运算,并调用一系列其他的Python库来实现硬件交互。matplotlib的核心是一套由对象构成的绘图API。它利用通用的图形用户界面工具包,如Tkinter, wxPython, Qt或GTK+,向应用程序嵌入式绘图提供了应用程序接口(API)。matplotlib是基于Python语言的开源项目,旨在为Python提供一个数据绘图包。matplotlib的对象体系严谨而丰富,为使用者提供了巨大的发挥空间。在熟悉了核心对象之后,可以轻易的定制图像。matplotlib的对象体系也是计算机图形学的一个优秀范例。
    matplotlib最初由John D. Hunter撰写,它拥有一个活跃的开发社区,并且根据BSD样式许可证分发。 在John D. Hunter2012年去世前不久,Michael Droettboom被提名为matplotlib的主要开发者。

    可以通过官网和源码可以更加深入的了解matplotlib。
    官网:https://matplotlib.org
    源码:https://github.com/matplotlib/matplotlib

    matplotlib 可视化的结构

    使用matplotlib绘图,主要掌握figure(画布)、axes(坐标系)、axis(坐标轴)之间的关系。在matplotlib中,整个图像为一个Figure对象。在Figure对象中可以包含一个,或者多个axes对象。每个Axes对象都是一个拥有自己坐标系统的绘图区域。
    如下图所示,在同一个figure画布中,存在四个坐标系,对应的每个坐标系都有各自的坐标轴。


    AxesAxisFig.png

    举个比较形象的例子,一个画家需要创作一幅油画。首先需要在画框上固定一张画布上,有了画布就可以创作任意的作品了,这个过程就是matplotlib中初始化画布(figure);其次,需要规划在这个画布上的布局,是一整幅还是多个子图构成?如果是多了子图就需要为不同的的板块分配区域了,这个区域就对应了matplotlib中为不同的子图指定的坐标系(axes)。对应的画布中可能会存在1个或者多个坐标系;然后,在不同的子图创作完成之后,需要对边界进行勾勒,这个边界就对应了matplotlib中的坐标轴(axis).

    matplotlib的构成

    matplotlib官网上提供描述其结构的一张图,为了更方便的了解其内容将其中涉及到的内容增加了中文的说明。通过这张可以大致了解到通过绘制一张图所涵盖的部分。通过运行后面的


    AnatomyOfMatplotlib.png

    相关代码

    • matplotlib图的构成(图AnatomyOfMatplotlib):

    由于matplotlib对于中文显示的支持不太好,会导致中文显示为乱码。对于中文字符显示的解决方案会在后面进行说明

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.ticker import AutoMinorLocator, MultipleLocator, FuncFormatter
    
    #支持中文
    matplotlib.rcParams['font.family'] = ['Heiti TC']
    
    np.random.seed(19680801)
    
    X = np.linspace(0.5, 3.5, 100)
    Y1 = 3+np.cos(X)
    Y2 = 1+np.cos(1+X/0.75)/2
    Y3 = np.random.uniform(Y1, Y2, len(X))
    
    fig = plt.figure(figsize=(8, 8))
    ax = fig.add_subplot(1, 1, 1, aspect=1)
    
    
    def minor_tick(x, pos):
        if not x % 1.0:
            return ""
        return "%.2f" % x
    
    #设置x轴主刻度的位置,主刻度标签设置为1的倍数
    ax.xaxis.set_major_locator(MultipleLocator(1.000))
    #设置x轴次刻度的位置,将每一个主刻度的区间等分为4格,如对应图中第一个主刻度区间中0.25,0.50,0.75
    ax.xaxis.set_minor_locator(AutoMinorLocator(4))
    
    #设置y轴主刻度的位置,主刻度标签设置为1的倍数
    ax.yaxis.set_major_locator(MultipleLocator(1.000))
    #设置y轴次刻度的位置,将每一个主刻度的区间等分为4格
    ax.yaxis.set_minor_locator(AutoMinorLocator(4))
    
    #设置x轴副刻度的文本显示格式
    ax.xaxis.set_minor_formatter(FuncFormatter(minor_tick))
    
    #设置x轴和y轴的显示区间
    ax.set_xlim(0, 4)
    ax.set_ylim(0, 4)
    
    
    #设置主刻度中刻度的长宽属性
    ax.tick_params(which='major', width=1.0)
    ax.tick_params(which='major', length=10)
    
    #设置次刻度的文本大小,颜色
    ax.tick_params(which='minor', width=1.0, labelsize=10)
    ax.tick_params(which='minor', length=5, labelsize=10, labelcolor='0.25')
    
    #显示网格设置
    ax.grid(linestyle="--", linewidth=0.5, color='.25', zorder=-10)
    
    #按照y1,y2,y3来绘制
    ax.plot(X, Y1, c=(0.25, 0.25, 1.00), lw=2, label="Blue signal", zorder=10)
    ax.plot(X, Y2, c=(1.00, 0.25, 0.25), lw=2, label="Red signal")
    ax.plot(X, Y3, linewidth=0,
            marker='o', markerfacecolor='w', markeredgecolor='k')
    
    #设置图的标题
    ax.set_title("Anatomy of a figure", fontsize=20, verticalalignment='bottom')
    #设置x轴lable
    ax.set_xlabel("X axis label")
    #设置y轴lable
    ax.set_ylabel("Y axis label")
    
    #设置图例
    ax.legend()
    
    
    #通过patches和patheffects中的函数来绘制对应图中圆圈标注的地方
    def circle(x, y, radius=0.15):
        from matplotlib.patches import Circle
        from matplotlib.patheffects import withStroke
        circle = Circle((x, y), radius, clip_on=False, zorder=10, linewidth=1,
                        edgecolor='black', facecolor=(0, 0, 0, .0125),
                        path_effects=[withStroke(linewidth=5, foreground='w')])
        ax.add_artist(circle)
    
    #设置文本显示的属性
    def text(x, y, text):
        ax.text(x, y, text, backgroundcolor="white",
                ha='center', va='top', weight='bold', color='blue')
    
    
    #对各个标注点的显示
    # Minor tick
    circle(0.50, -0.10)
    text(0.50, -0.32, "次刻度标签(Minor tick label)")
    
    # Major tick
    circle(-0.03, 4.00)
    text(0.03, 3.80, "主刻度(Major tick)")
    
    # Minor tick
    circle(0.00, 3.50)
    text(0.00, 3.30, "次刻度(Minor tick)")
    
    # Major tick label
    circle(-0.15, 3.00)
    text(-0.15, 2.80, "主刻度标签(Major tick label)")
    
    # X Label
    circle(1.80, -0.27)
    text(1.80, -0.45, "x轴标签(X axis label)")
    
    # Y Label
    circle(-0.27, 1.80)
    text(-0.27, 1.6, "y轴标签(Y axis label)")
    
    # Title
    circle(1.60, 4.13)
    text(1.60, 3.93, "名称(Title)")
    
    # Blue plot
    circle(1.75, 2.80)
    text(1.75, 2.60, "线条(Line)\n(line plot)")
    
    # Red plot
    circle(1.20, 0.60)
    text(1.20, 0.40, "线条(Line)\n(line plot)")
    
    # Scatter plot
    circle(3.20, 1.75)
    text(3.20, 1.55, "节点样式(Markers)\n(scatter plot)")
    
    # Grid
    circle(3.00, 3.00)
    text(3.00, 2.80, "网格(Grid)")
    
    # Legend
    circle(3.70, 3.80)
    text(3.70, 3.60, "图例(Legend)")
    
    # Axes
    circle(0.5, 0.5)
    text(0.5, 0.3, "坐标系(Axes)")
    
    # Figure
    circle(-0.3, 0.65)
    text(-0.3, 0.45, "画布(Figure)")
    
    color = 'blue'
    
    #注解的显示,图中右下角spines
    ax.annotate('坐标轴(Spines)', xy=(4.0, 0.35), xytext=(3.3, 0.5),
                weight='bold', color=color,
                arrowprops=dict(arrowstyle='->',
                                connectionstyle="arc3",
                                color=color))
    
    ax.annotate('', xy=(3.15, 0.0), xytext=(3.45, 0.45),
                weight='bold', color=color,
                arrowprops=dict(arrowstyle='->',
                                connectionstyle="arc3",
                                color=color))
    
    #文本的显示
    ax.text(4.0, -0.4, "参考自官网的简介(\nMade with http://matplotlib.org)",
            fontsize=10, ha="right", color='.5')
    
    
    #fig.savefig('./img/AnatomyOfMatplotlib.png')
    plt.show()
    
    • 多子图显示(图AxesAxisFig):
    import numpy as np
    import matplotlib.pyplot as plt
    
    x = np.linspace(0.0,6.0)
    
    figure,ax=plt.subplots(2,2,figsize=(16,9))
    
    ax[0][0].plot(x,np.sin(np.pi*x));
    ax[0][0].set_title("正弦")
    ax[0][0].set_xlabel("时间")
    ax[0][0].set_ylabel("幅度")
    ax[0][0].set_ylabel("幅度")
    
    ax[0][1].plot(x,np.cos(np.pi*x));
    ax[0][1].set_title("余弦")
    ax[0][1].set_xlabel("时间")
    ax[0][1].set_ylabel("幅度")
    
    ax[1][0].plot(x,np.log((x+1)*10));
    ax[1][0].set_title("指数")
    ax[1][0].set_xlabel("时间")
    ax[1][0].set_ylabel("距离")
    
    
    ax[1][1].plot(x,x*4);
    ax[1][1].set_title("投资")
    ax[1][1].set_xlabel("资金")
    ax[1][1].set_ylabel("收益")
    
    figure.tight_layout(pad=1.5)
    #figure.savefig('./img/Subplots.png')
    

    相关文章

      网友评论

          本文标题:matplotlib 可视化的基本原理

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