zoukankan      html  css  js  c++  java
  • Matplotlib 绘图库从入门到精通

       matplotlib是python的一个绘图库。使用它可以很方便的绘制出版质量级别的图形。说实话没有matlab画的图清楚。使用Matplotlib,能够轻易生成各种图像,例如:直方图、波谱图、条形图、散点图等。

    绘图核心API

    案例:绘制一条正弦曲线

    import numpy as np
    import matplotlib.pyplot as plt
    
    xs = np.linspace(-np.pi, np.pi, 1000)
    ys = np.sin(xs)
    plt.plot(xs, ys)
    plt.show()

    绘制水平线和垂直线:

    plt.vlines(vval, ymin, ymax, ...)  绘制垂直线  

    参数:

    • vval:垂直线的 x轴坐标的起始值
    • ymin:垂直线长度的最小值 
    • ymax:垂直线长度的最大值

    plt.hlines(xval, xmin, xmax, ...)  绘制水平线 

    参数:

    • vval:水平线的 y轴坐标的起始值
    • ymin:水平线长度的最小值 
    • ymax:水平线长度的最大值
    import matplotlib.pyplot as plt
    
    plt.vlines(0,0,10)  # x轴
    plt.hlines(0,0,10)  # y轴
    plt.show()

    线条、线宽和颜色

    linestyle 线形

      常见的线:直线:-  虚线: - -  点线::  点划线:-.  星号:*

      常见的点:点:.  方形:s  圆:o  像素:,  三角形:^

    linewidth  线宽

    color  颜色

    • 英文颜色单词
    • 常见颜色英文单词首字母
    • 16进制表示颜色:#495434
    • rgb或rgba(1,1,1) 或 (1,1,1,1)

    常见的颜色:蓝色:b  青色:c  红色:r  黑色:k  绿色:g  品红:r  黄色:y  白色:w

    alpha  透明度,浮点数值

    plt.plot(xarray, yarray, linestyle='', linewidth=1, color='', alpha=0.5)

    坐标轴取值范围

    plt.xlim(x_min,x_min)

    参数:

    • x_limt_min:x轴范围最小值
    • x_limt_min:x轴范围最大值

    plt.ylim(y_min,y_min)

    参数:

    • y_limt_min:y轴范围最小值
    • y_limt_min:y轴范围最大值

    坐标轴刻度

    plt.xticks(x_val_list , x_text_list )

    参数:

    • x_val_list: x轴刻度值序列
    • x_text_list: x轴刻度标签文本序列 [可选]

    plt.yticks(y_val_list , y_text_list )

    • y_val_list: y轴刻度值序列
    • y_text_list: y轴刻度标签文本序列 [可选]
    plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi], ["","-π/2", 0, "π/2", "π"])

    刻度文本的特殊语法--LaTax语法字符串

    plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
        [r"$-pi$",r"$-frac{pi}{2}$", 0, r"$frac{pi}{2}$", r"$pi$"])

     

    设置坐标轴

    坐标轴名:'left':左轴、'right':右轴、'bottom':下轴、'top':上轴

    ax = plt.gca()           获取其中某个坐标系
    axis = ax.spines['坐标轴名']  获取某个具体的上下左右坐标轴,left、right、bottom、top

    axis.set_position(("data", val))  设置坐标轴位置

    参数:

    • type: 移动坐标轴的参照类型 一般为'data' (以数据的值作为移动参照值)
    • val: 参照值

    axis.set_color(color)    设置坐标轴的颜色

    案例:设置坐标轴至中心

    ax = plt.gca()
    ax.spines['top'].set_color('none')
    ax.spines['right'].set_color('none')
    ax.spines['left'].set_position(('data', 0))
    ax.spines['bottom'].set_position(('data', 0))
    plt.yticks([-1, -0.5, 0.5, 1])

    图例

    显示图例,需要先在plt.plot中设置曲线的label,再plt.legend设置图例

    plt.plot(xarray, yarray ... label='', ...)  label: <关键字参数 str> 支持LaTex排版语法字符串

    plt.legend(loc='')

      loc:制定图例的显示位置 (若不设置loc,则显示默认最优位置)

    'best'  最优的位置
    'upper right' 上右 
    'upper left' 上左 
    'lower left' 下左 
    'lower right' 下右 
    'right' 右 
    'center left' 中心偏左 
    'center right' 中心偏右 
    'lower center' 中心偏下 
    'upper center' 中心偏上 
    'center' 中心 

    plt.title("****)  设置图的标题

    plt.xlabel("x")  设置x轴的名称

    plt.ylabel("y")  设置y轴的名称

    plt.grid(linestyle="")    设置网格线,参数可以不写

    mp.tick_params(labelsize=8)  设置刻度字体大小

    标注点

    plt.scatter(x, y, marker='', s=60, edgecolor='', facecolor='', zorder=3)

    参数:

    • x,y:     需要标注的点,或点的数组
    • marker:    点型
    • s:       大小
    • edgecolor:  边缘色
    • facecolor:  填充色 
    • zorder:    绘制图层编号 (编号越大,图层越靠上,就不会被线条盖住)
    • label:    用于在图例中显示的字符串

    添加注释

    有时候我们需要对特定的点进行标注,我们可以使用 plt.annotate 函数来实现。

    这里我们要标注的点是 (x0, y0) = (π, 0)

    annotate("备注内容", xycoords="data", xy=(x,y), textcoords='offset points', xytext=(x, y), fontsize=14, arrowprops=dict(arrowstyle='', connectionstyle=''))

    参数:

    • 第一个参数,就是备注的内容,支持LaTax语法
    • xycoords='data':参照类型 一般为'data' (以数据的值作为移动参照值)
    • textcoords='offset points':表示对于标注位置的描述(offset points表示参照点的偏移坐标系)
    • xytext=(+30, -30)  xy 偏差值,即标注位置是 xy 位置向右移动 30,向下移动30;
    • fontsize:字体大小
    • arrowprops 是对图中箭头类型和箭头弧度的设置,需要用 dict 形式传入。

      • arrowstyle='', #定义箭头样式
      • connectionstyle='' #定义连接线的样式
    import matplotlib.pyplot as plt
    import numpy as np
    
    x = np.linspace(0, 2 * np.pi, 50)
    y = np.sin(x)
    plt.plot(x, y)
    
    x0 = np.pi
    y0 = 0
    
    plt.scatter(x0, y0, s=50)        # 画出标注点
    # 右边的
    plt.annotate('sin(np.pi)=%s' % y0, xy=(np.pi, 0), xycoords='data', xytext=(+30, -30),
                 textcoords='offset points', fontsize=16,
                 arrowprops=dict(arrowstyle='->', connectionstyle="arc3,rad=.2"))
    # 左边的
    plt.text(0.5, -0.25, "sin(np.pi) = 0", fontdict={'size': 16, 'color': 'r'})
    
    plt.show()

    ============   =============================================
    Name           Attrs
    ============   =============================================
      '-'          None
      '->'         head_length=0.4,head_width=0.2
      '-['         widthB=1.0,lengthB=0.2,angleB=None
      '|-|'        widthA=1.0,widthB=1.0
      '-|>'        head_length=0.4,head_width=0.2
      '<-'         head_length=0.4,head_width=0.2
      '<->'        head_length=0.4,head_width=0.2
      '<|-'        head_length=0.4,head_width=0.2
      '<|-|>'      head_length=0.4,head_width=0.2
      'fancy'      head_length=0.4,head_width=0.4,tail_width=0.4
      'simple'     head_length=0.5,head_width=0.5,tail_width=0.2
      'wedge'      tail_width=0.3,shrink_factor=0.5
    ============   =============================================
    箭头样式
    ============   =============================================
    Name           Attrs
    ============   =============================================
      'angle'         angleA=90,angleB=0,rad=0.0
      'angle3'         angleA=90,angleB=0`   
      'arc'            angleA=0,angleB=0,armA=None,armB=None,rad=0.0
      'arc3'         rad=0.0
      'bar'         armA=0.0,armB=0.0,fraction=0.3,angle=None
    ============   =============================================
    连接线样式

    我们也可以使用 plt.text 函数来添加注释。

    plt.text是在图中书写文本

    plt.text(x,y,"内容", ha="",va="", size, alpha)

    参数:

    • x,y:为本文的位置
    • ha:文本水平位置 "center"
    • va:文本水平位置 "center"
    • size:字体大小
    • alpha:透明度

    一次性绘制多个图形

    当需要两组数据进行对比,或者一组数据的不同展示方式,我们就可以在一个窗口中绘制多个图形。

    图形窗口——figure

    matplotlib在绘制图形的时候都在一个默认的figure中。我们可以通过plt.figure()再创建一个窗口

    plt.figure("窗口名", figsize=(4,3),facecolor="")

    参数:

    • figsize:窗口大小,元组形式
    • facecolor:图标背景颜色

    每次调用一次figure方法,一来是创建一个新窗口,而来是编辑这个窗口,如果创建的窗口已经存在,则是编辑那个已经存在的窗口。

    import matplotlib.pyplot as plt
    import numpy as np
    
    data = np.arange(100, 201)  # 生成一组100到200,步长为1的数组
    # 在第一个默认窗口画
    plt.plot(data)  # 绘制data
    
    data2 = np.arange(200,301)
    plt.figure(figsize=(6, 3))    # 生成一个图形窗口,设置窗口的大小为(6,3)
    # 在第二个窗口画
    plt.plot(data2) # 绘制data2
    
    plt.show()  # 展现

    子图——subplot

      有时候我们需要将多张子图展示在一起,可以使用 plt.subplot()实现。即在调用plot()函数之前需要先调用 subplot()函数。该函数的第一个参数代表子图的总行数,第二个参数代表子图的总列数,第三个参数代表活跃区域。下面绑定了实例,也可以不绑定。

    import matplotlib.pyplot as plt
    import numpy as np
    
    x = np.linspace(0, 2 * np.pi, 50)
    y = np.sin(x)
    
    ax1 = plt.subplot(2, 2, 1) # (行,列,活跃区)
    plt.plot(x, np.sin(x), 'r')
    
    ax2 = plt.subplot(2, 2, 2, sharey=ax1) # 与 ax1 共享y轴
    plt.plot(x, 2 * np.sin(x), 'g')
    
    ax3 = plt.subplot(2, 1, 2)  # 将窗口分为两行1列,这个图形占第二列
    plt.plot(x, np.cos(x), 'b')
    
    plt.show()

    代码解析:

    1、subplot(2,2,x)表示将图像窗口分为2行2列。x表示当前子图所在的活跃区域。

    2、subplot(2,1,2)将窗口分为两行一列,这个图形画在第二列

    3、plt.subplot(2,2,2,sharey=ax1)    # 是与ax1函数共享受一个y轴。

    4、如果之前定义了图片fig = plt.figure(),那么可以通过ax4 = fig.add_subplot(2,1,3)添加子图

    运行结果如下:

    注意;subplot函数的参数不仅仅支持上面的这种形式,还可以将三个整数(10之内的)合并一个整数。例如:plt.subplot(2,2,1)可以写成plt.subplot(221),结果是一样的。

    常用的图形实例

    Matplotlib可以生成非常多的图形,常用的有:线形图、散点图、饼状图、条形图、直方图。我们来依次了解一下。

    线形图——plot

    import matplotlib.pyplot as plt
    
    plt.plot([1,2,3],[3,6,9], "-r")
    plt.plot([1,2,3],[2,4,9], ":g")
    
    plt.show()

    代码解析:

    1、plot函数的第一个数组是横轴的值,第二个数组是纵轴的值,

    2、最后一个参数是由两个字符构成,分别是线条的样式和颜色。前者是红色的直线,后者是绿色的点线,关于样式和颜色的说明请参见plor函数的APIDoc:matplotlib.pyplot.plot

    运行结果如下:

    散点图——scatter

    先上代码

    import matplotlib.pyplot as plt
    import numpy as np
    
    plt.subplot(2,1,1)
    k = 500
    x = np.random.rand(k)
    y = np.random.rand(k)      # [0,1)之间的随机数
    size = np.random.rand(k) * 50 # 生成每个点的大小
    colour = np.arctan2(x, y) # 生成每个点的颜色
    plt.scatter(x, y, s=size, c=colour)
    plt.colorbar() # 添加颜色栏
    
    N = 20
    # 参数c表示点的颜色,s是点的大小,alpha是透明度
    
    plt.subplot(2,3,4)
    plt.scatter(np.random.rand(N) * 100,
                np.random.rand(N) * 100,
                c="r", s=100, alpha=0.5)    # 红色
    
    plt.subplot(2,3,5)
    plt.scatter(np.random.rand(N) * 100,
                np.random.rand(N) * 100,
                c="g", s=200, alpha=0.5)    # 绿色
    
    plt.subplot(2,3,6)
    plt.scatter(np.random.rand(N) * 100,
                np.random.rand(N) * 100,
                c="b", s=300, alpha=0.5)    # 蓝色
    
    plt.show() 

     代码解析

    1、这幅图包含三组数据,每组数据都包含了20个随机坐标的位置

    2、参数c表示点的颜色,c的值可以是列表或者公式;s是点的大小,alpha是透明度

    d = (x-172)**2 + (y-60)**2
    mp.scatter(x, y, c=d, cmap='jet')    #以c作为参数,取cmap颜色映射表中的颜色值

      cmap颜色映射表,值越大颜色偏蓝,值越小颜色偏红。

    3、plt.colorbar()添加右边的颜色栏

    运行结果:

    饼状图——pie

    mp.axis('equal')    设置坐标大小一致,目的是为了让饼状图是圆而不是椭圆
    mp.pie(values, spaces, labels, colors, '%d%%', shadow=True, startangle=90, radius=1)

    • values:值列表
    • spaces:扇形之间的间距列表
    • labels:标签列表
    • colors:颜色列表
    • autopct='%d%%':标签所占比例格式
    • shadow=True:是否显示阴影
    • startangle=90:逆时针绘制饼状图时的起始角度
    • radius=1:半径

    先上代码:

    import matplotlib.pyplot as plt
    import numpy as np
    
    labels = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
    
    data = np.random.rand(7) * 100  # 生成7组随机数
    
    # labels指定标签,autopct指定数值的精度
    plt.pie(data, labels=labels, autopct="%1.1f%%")
    plt.axis("equal")   # 设置了坐标大小一致
    plt.legend()    # 指明要绘制的图例
    
    plt.show()

    代码解析:

    1、data是一个包含7个数据的随机数值

    2、图中的标签通过labels来指定

    3、autopct指定了数值的精度格式

    4、plt.axis('equal')设置了坐标轴大小一致

    5、plt.legend()指明要绘制图例(见下图的右上角)

    运行结果:

    柱形图——bar

    plt.bar(x, y, width, color="", label="", alpha=0.2)

    参数:

    • x:水平坐标轴
    • y:柱状图高度数组
    • width:柱子的宽度,小于1
    • color:柱子的颜色
    • label:用于图例显示
    • tick_label:刻度标签
    • alpha:透明度
    import numpy as np
    import matplotlib.pyplot as plt
    
    apples = np.array([30, 25, 22, 36, 21, 29, 20, 24, 33, 19, 27, 15])
    oranges = np.array([24, 33, 19, 27, 35, 20, 15, 27, 20, 32, 20, 22])
    plt.figure('Bar', facecolor='lightgray')
    plt.title('Bar', fontsize=20)
    plt.xlabel('Month', fontsize=14)
    plt.ylabel('Price', fontsize=14)
    plt.tick_params(labelsize=10)
    plt.grid(axis='y', linestyle=':')
    plt.ylim((0, 40))
    labels=['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
            'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    x = np.arange(len(apples))
    plt.bar(x-0.2, apples, 0.4, color='dodgerblue',label='Apple', tick_label=labels)
    plt.bar(x + 0.2, oranges, 0.4, color='orangered',label='Orange', alpha=0.75, tick_label=labels)
    plt.legend()
    plt.show()

    直方图——hist

    直方图是描述数据中某范围内数据出现的频率,

    先上代码

    import matplotlib.pyplot as plt
    import numpy as np
    
    # 生成3组数据
    data = [np.random.randint(0, n, n) for n in [3000, 4000, 5000]]
    labels = ['3K', '4K', '5K'] # 设置标签
    
    # 设置数据点
    bins = [0, 100, 500, 1000, 2000, 3000, 4000, 5000]
    
    plt.hist(data, bins=bins, label=labels)
    plt.legend()
    
    plt.show()

    代码解析

    [np.random.randint(0, n, n) for n in [3000, 4000, 5000]]生成了包含三个数组的列表。

    • 第一个数组包含了3000个随机数,这些随机数的范围是 [0, 3000)
    • 第二个数组包含了4000个随机数,这些随机数的范围是 [0, 4000)
    • 第三个数组包含了5000个随机数,这些随机数的范围是 [0, 5000)

     2、bins数组用来指定我们显示的直方图的边界,即:[0, 100) 会有一个数据点,[100, 500)会有一个数据点,以此类推。所以最终结果一共会显示7个数据点。

    运行结果

      我们看到,三组数据在3000以下都有数据,并且频度是差不多的。但蓝色条只有3000以下的数据,橙色条只有4000以下的数据。这与我们的随机数组数据刚好吻合。

    等高线图--contour

    组成等高线需要网格点坐标矩阵,也需要每个点的高度。

    cntr = plt.contour(x, y, z, 8, colors='black', linewidths=0.5)

    • x:网格坐标矩阵的x坐标 (2维数组)
    • y:网格坐标矩阵的y坐标 (2维数组)
    • z:网格坐标矩阵的z坐标 (2维数组)
    • 8:把等高线绘制成8部分
    • colors='black':等高线的颜色
    • linewidths=0.5:线宽

    plt.clabel(cntr, inline_spacing=1, fmt='%.1f', fontsize=10)  为等高线图添加高度标签
    plt.contourf(x, y, z, 8, cmap='jet')    填充等高线颜色

    import numpy as np
    import matplotlib.pyplot as plt
    
    n = 1000
    # 生成网格化坐标矩阵
    x, y = np.meshgrid(np.linspace(-3, 3, n), np.linspace(-3, 3, n))
    # 根据每个网格点坐标,通过某个公式计算z高度坐标
    z = (1 - x/2 + x**5 + y**3) * np.exp(-x**2 - y**2)
    plt.figure('Contour', facecolor='lightgray')
    plt.title('Contour', fontsize=20)
    plt.xlabel('x', fontsize=14)
    plt.ylabel('y', fontsize=14)
    plt.tick_params(labelsize=10)
    plt.grid(linestyle=':')
    plt.contourf(x, y, z, 8, cmap='jet')      # 添加颜色
    cntr = plt.contour(x, y, z, 8, colors='black', linewidths=0.5)  # 绘制等高线图
    # 为等高线图添加高度标签 
    plt.clabel(cntr, inline_spacing=1, fmt='%.1f', fontsize=10) 
    plt.show()

    填充

    plt.fill_between(x, sin_x, cos_x, sin_x<cos_x, color='',alpha=0.2)

    参数:

    • x:x轴的水平坐标
    • sin_x:下边界曲线上点的垂直坐标
    • cos_x:上边界曲线上点的垂直坐标
    • sin_x<cos_x:填充条件,为True时填充
    • color:填充颜色
    • alpha:透明度

    举例:绘制两条曲线: sin_x = sin(x) cos_x = cos(x / 2) / 2 [0-8π]

    import numpy as np
    import matplotlib.pyplot as mp
    
    x = np.linspace(0, 8 * np.pi, 1000)
    sinx = np.sin(x)
    cosx = np.cos(x / 2) / 2
    mp.figure('Fill', facecolor='lightgray')
    mp.title('Fill')
    mp.plot(x, sinx, color='dodgerblue', label='sinx', linewidth=2)
    mp.plot(x, cosx, color='orangered', label='cosx', linewidth=2)
    # 绘制填充
    mp.fill_between(x, sinx, cosx, sinx > cosx, color='dodgerblue', alpha=0.5)
    mp.fill_between(x, sinx, cosx, sinx < cosx, color='orangered', alpha=0.5)
    
    mp.legend()
    mp.show()

     

    3D图像

    3维点阵图

    ax3d.scatter(
        x,                 # x轴坐标数组
        y,                # y轴坐标数组
        z,                # z轴坐标数组
        marker='',         # 点型
        s=10,            # 大小
        zorder='',        # 图层序号
        color='',        # 颜色
        edgecolor='',     # 边缘颜色
        facecolor='',    # 填充色
        c=v,            # 颜色值 根据cmap映射应用相应颜色
        cmap=''            # 
    )

    案例:随机生成3组坐标,服从标准正态分布规则,并且绘制它们。

    import numpy as np
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import axes3d
    
    n = 500
    x = np.random.normal(0, 1, n)
    y = np.random.normal(0, 1, n)
    z = np.random.normal(0, 1, n)
    plt.figure('3D scatter')
    ax3d = plt.gca(projection='3d')
    d = x ** 2 + y ** 2 + z ** 2
    ax3d.scatter(x, y, z, s=70, c=d, alpha=0.7, cmap='jet')
    ax3d.set_xlabel('x')
    ax3d.set_ylabel('y')
    ax3d.set_zlabel('z')
    plt.tight_layout()
    plt.show()

    3D曲面图

    ax3d.plot_surface(
        x,                     # 网格坐标矩阵的x坐标 (2维数组)
        y,                     # 网格坐标矩阵的y坐标 (2维数组)
        z,                     # 网格坐标矩阵的z坐标 (2维数组)
        rstride=30,            # 行跨距
        cstride=30,         # 列跨距
        cmap='jet'            # 颜色映射
    )

    案例:绘制3d平面图

    import numpy as np
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import axes3d
    
    n = 1000
    # 生成网格化坐标矩阵
    x, y = np.meshgrid(np.linspace(-3, 3, n), np.linspace(-3, 3, n))
    # 根据每个网格点坐标,通过某个公式计算z高度坐标
    z = (1 - x / 2 + x ** 5 + y ** 3) * np.exp(-x ** 2 - y ** 2)
    plt.figure('3D', facecolor='lightgray')
    
    ax3d = plt.gca(projection='3d')
    plt.title('3D', fontsize=20)
    ax3d.set_xlabel('x', fontsize=14)
    ax3d.set_ylabel('y', fontsize=14)
    ax3d.set_zlabel('z', fontsize=14)
    plt.tick_params(labelsize=10)
    # 绘制3D平面图
    # rstride: 行跨距
    # cstride: 列跨距
    ax3d.plot_surface(x, y, z, rstride=30, cstride=30, cmap='jet')
    plt.show()

    等高线图

    组成等高线需要网格点坐标矩阵,也需要每个点的高度。所以等高线属于3D数学模型范畴。

    cntr = mp.contour(
        x,                     # 网格坐标矩阵的x坐标 (2维数组)
        y,                     # 网格坐标矩阵的y坐标 (2维数组)
        z,                     # 网格坐标矩阵的z坐标 (2维数组)
        8,                     # 把等高线绘制成8部分
        colors='black',        # 等高线的颜色
        linewidths=0.5        # 线宽
    )
    # 为等高线图添加高度标签
    mp.clabel(cntr, inline_spacing=1, fmt='%.1f',
              fontsize=10)
    # 填充等高线
    mp.contourf(x, y, z, 8, cmap='jet')

    案例:生成网格坐标矩阵,并且绘制等高线:

    import numpy as np
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import axes3d
    
    n = 1000
    # 生成网格化坐标矩阵
    x, y = np.meshgrid(np.linspace(-3, 3, n), np.linspace(-3, 3, n))
    # 根据每个网格点坐标,通过某个公式计算z高度坐标
    z = (1 - x / 2 + x ** 5 + y ** 3) * np.exp(-x ** 2 - y ** 2)
    plt.figure('Contour', facecolor='lightgray')
    plt.title('Contour', fontsize=20)
    plt.xlabel('x', fontsize=14)
    plt.ylabel('y', fontsize=14)
    plt.tick_params(labelsize=10)
    plt.grid(linestyle=':')
    # 绘制等高线图
    plt.contourf(x, y, z, 8, cmap='jet')
    cntr = plt.contour(x, y, z, 8, colors='black', linewidths=0.5)
    # 为等高线图添加高度标签
    plt.clabel(cntr, inline_spacing=1, fmt='%.1f', fontsize=10)
    plt.show()

    简单动画

    动画即是在一段时间内快速连续的重新绘制图像的过程。

    matplotlib提供了方法用于处理简单动画的绘制。定义update函数用于即时更新图像。

    import matplotlib.animation as ma
    #定义更新函数行为
    def update(number):
        pass
    # 每隔10毫秒执行一次update更新函数,作用于plt.gcf()当前窗口对象
    anim = ma.FuncAnimation(plt.gcf(), update, interval=10)
    # plt.gcf():    获取当前窗口
    # update:    更新函数
    # interval:    间隔时间(单位:毫秒)
    plt.show()

    使用生成器函数提供数据,实现动画绘制

    在很多情况下,绘制动画的参数是动态获取的,matplotlib支持定义generator生成器函数,用于生成数据,把生成的数据交给update函数更新图像:

    import matplotlib.animation as ma
    #定义更新函数行为
    def update(data):
        t, v = data
        ...
        pass
    
    def generator():
        yield t, v
            
    # 每隔10毫秒将会先调用生成器,获取生成器返回的数据,
    # 把生成器返回的数据交给并且调用update函数,执行更新图像函数
    anim = ma.FuncAnimation(mp.gcf(), update, generator,interval=10)

    案例:绘制信号曲线:y=sin(2 * π * t) * exp(sin(0.2 * π * t)),数据通过生成器函数生成,在update函数中绘制曲线。

    import numpy as np
    import matplotlib.pyplot as mp
    import matplotlib.animation as ma
    
    x = 0
    mp.figure("Signal", facecolor='lightgray')
    mp.title("Signal", fontsize=14)
    mp.xlim(0, 20)
    mp.ylim(-3, 3)
    mp.grid(linestyle='--', color='lightgray', alpha=0.5)
    pl = mp.plot([], [], color='dodgerblue', label='Signal')[0]
    
    
    def update(data):
        t, v = data
        x, y = pl.get_data()  # x,y是保存x,y坐标的ndarray对象
        x = np.append(x, t)
        y = np.append(y, v)
        pl.set_data(x, y)  # 重新设置数据源
        # 移动坐标轴
        if (x[-1] > 20):
            mp.xlim(x[-1] - 20, x[-1])
    
    
    def y_generator():
        global x
        y = np.sin(2 * np.pi * x) * np.exp(np.sin(0.2 * np.pi * x))
        yield (x, y)
        x += 0.05
    
    
    anim = ma.FuncAnimation(mp.gcf(), update, y_generator, interval=20)
    mp.tight_layout()
    mp.show()

    绘制dates与收盘价的折线图:

    import numpy as np
    import matplotlib.pyplot as mp
    import datetime as dt
    import matplotlib.dates as md
    
    def dmy2ymd(dmy):
        # 把日月年字符串转为年月日字符串
        dmy = str(dmy, encoding='utf-8')
        d = dt.datetime.strptime(dmy, '%d-%m-%Y').date()
        ymd = d.strftime('%Y-%m-%d')
        return ymd
    
    # 加载文件
    dates, opening_prices, highest_prices, lowest_prices, 
    closing_prices = np.loadtxt('./aapl.csv', delimiter=',',
                                usecols=(1, 3, 4, 5, 6),
                                unpack=True, dtype='M8[D], f8, f8, f8, f8',
                                converters={1: dmy2ymd})
    
    # 绘制收盘价的折线图
    mp.figure('AAPL', facecolor='lightgray')
    mp.title('AAPL', fontsize=18)
    mp.xlabel('Date', fontsize=14)
    mp.ylabel('Price', fontsize=14)
    mp.grid(linestyle=':')
    mp.tick_params(labelsize=10)
    
    ax = mp.gca()       # 设置刻度定位器
    maloc = md.WeekdayLocator(byweekday=md.MO)      # 每周一一个主刻度
    ax.xaxis.set_major_locator(maloc)
    
    ax.xaxis.set_major_formatter(md.DateFormatter('%Y-%m-%d'))      # 设置主刻度日期的格式
    ax.xaxis.set_minor_locator(md.DayLocator())             # DayLocator:每天一个次刻度
    dates = dates.astype(md.datetime.datetime)              # 把dates的数据类型改为matplotlib的日期类型
    
    # 绘制收盘价
    mp.plot(dates, closing_prices, label='Closing Prices', linewidth=2, color='dodgerblue', linestyle='--', alpha=0.7)
    mp.legend()
    mp.gcf().autofmt_xdate()        # 刻度参数倾斜
    mp.show()
    View Code

    刻度定位器

    ax=plt.gca()  获取当前坐标轴

    x轴空刻度

    ax.xaxis.set_major_locator(plt.NullLocator())

    水平坐标轴的主刻度定位器,间隔1

    ax.xaxis.set_major_locator(plt.MultipleLocator(1))

    水平坐标轴的次刻度定位器为多点定位器,间隔0.1

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

    常用刻度器如下:

    # 空定位器:不绘制刻度
    plt.NullLocator()
    
    # 最大值定位器:最多绘制nbins+1个刻度
    plt.MaxNLocator(nbins=3)
    
    # 定点定位器:根据locs参数中的位置绘制刻度
    plt.FixedLocator(locs=[0, 2.5, 5, 7.5, 10])
    
    # 自动定位器:由系统自动选择刻度的绘制位置
    plt.AutoLocator()
    
    # 索引定位器:由offset确定起始刻度,由base确定相邻刻度的间隔
    plt.IndexLocator(offset=0.5, base=1.5)
    
    # 多点定位器:从0开始,按照参数指定的间隔(缺省1)绘制刻度
    plt.MultipleLocator()
    
    # 线性定位器:等分numticks-1份,绘制numticks个刻度
    plt.LinearLocator(numticks=21)
    
    # 对数定位器:以base为底,绘制刻度
    plt.LogLocator(base=2)

    时间刻度器

    文件在我的github中:https://github.com/LXP-Neve/data

    import matplotlib.dates as md
    
    ax = mp.gca()  # 设置刻度定位器
    ax.xaxis.set_major_locator(md.WeekdayLocator(byweekday=md.MO))  # 每周一一个主刻度
    ax.xaxis.set_major_formatter(md.DateFormatter('%Y-%m-%d'))  # 设置主刻度日期的格式
    ax.xaxis.set_minor_locator(md.DayLocator())  # 每天一个次刻度
    dates = dates.astype(md.datetime.datetime)  # 把dates的数据类型改为matplotlib的日期类型
    """加载文件"""
    import numpy as np
    import matplotlib.pyplot as mp
    import datetime as dt
    import matplotlib.dates as md
    
    
    def dmy2ymd(dmy):
        # 把日月年字符串转为年月日字符串
        dmy = str(dmy, encoding='utf-8')
        d = dt.datetime.strptime(dmy, '%d-%m-%Y').date()
        ymd = d.strftime('%Y-%m-%d')
        return ymd
    
    
    # 加载文件
    dates, opening_prices, highest_prices, lowest_prices, closing_prices = 
        np.loadtxt('./aapl.csv', delimiter=',',
                   usecols=(1, 3, 4, 5, 6),
                   unpack=True, dtype='M8[D], f8, f8, f8, f8',
                   converters={1: dmy2ymd})
    
    # 绘制收盘价的折线图
    mp.figure('AAPL', facecolor='lightgray')
    mp.title('AAPL', fontsize=18)
    mp.xlabel('Date', fontsize=14)
    mp.ylabel('Price', fontsize=14)
    mp.grid(linestyle=':')
    mp.tick_params(labelsize=10)
    
    ax = mp.gca()  # 设置刻度定位器
    ax.xaxis.set_major_locator(md.WeekdayLocator(byweekday=md.MO))  # 每周一一个主刻度
    ax.xaxis.set_major_formatter(md.DateFormatter('%Y-%m-%d'))  # 设置主刻度日期的格式
    ax.xaxis.set_minor_locator(md.DayLocator())  # 每天一个次刻度
    dates = dates.astype(md.datetime.datetime)  # 把dates的数据类型改为matplotlib的日期类型
    
    # 绘制收盘价
    mp.plot(dates, closing_prices, label='Closing Prices', linewidth=2, color='dodgerblue', linestyle='--', alpha=0.7)
    mp.legend()
    mp.gcf().autofmt_xdate()  # 刻度参数倾斜
    mp.show()
    View Code

    网格刻度线

    ax = plt.gca()

    #绘制刻度网格线

    ax.grid(which='', axis='', linewidth=1, linestyle='', color='', alpha=0.5)

    参数

    • which:major 主刻度;minor 次刻度
    • axis:'x'、'y'/'both'-->绘制x或y轴
    • linewidth:线宽
    • linestyle:线型
    • color:颜色
    • alpha:透明度
    import matplotlib.pyplot as plt
    
    y = [1, 10, 100, 1000, 100, 10, 1]
    # 设置刻度定位器
    ax = plt.gca()
    ax.xaxis.set_major_locator(plt.MultipleLocator(1))
    ax.xaxis.set_minor_locator(plt.MultipleLocator(0.1))
    ax.yaxis.set_major_locator(plt.MultipleLocator(250))
    ax.yaxis.set_minor_locator(plt.MultipleLocator(50))
    # 绘制刻度网格线
    ax.grid(which='major', axis='both', color='orangered', linewidth=0.75)
    ax.grid(which='minor', axis='both', color='orangered', linewidth=0.25)
    
    plt.plot(y, 'o-')
    plt.show()
    View Code

    指数增长坐标

    y轴将以指数方式递增。 基于半对数坐标绘制第二个子图,表示曲线:[1, 10, 100, 1000, 100, 10, 1]。

    y = [1, 10, 100, 1000, 100, 10, 1]
    plt.semilogy(y)
    import matplotlib.pyplot as plt
    
    plt.figure('Semilogy')
    plt.subplot(211)
    y = [1, 10, 100, 1000, 100, 10, 1]
    # 设置刻度定位器
    ax = plt.gca()
    ax.xaxis.set_major_locator(plt.MultipleLocator(1))
    ax.xaxis.set_minor_locator(plt.MultipleLocator(0.1))
    ax.yaxis.set_major_locator(plt.MultipleLocator(250))
    ax.yaxis.set_minor_locator(plt.MultipleLocator(50))
    # 绘制刻度网格线
    ax.grid(which='major', axis='both', color='orangered', linewidth=0.75)
    ax.grid(which='minor', axis='both', color='orangered', linewidth=0.25)
    plt.plot(y, 'o-')
    
    # 半对数坐标系
    plt.subplot(212)
    y = [1, 10, 100, 1000, 100, 10, 1]
    # 设置刻度定位器
    ax = plt.gca()
    ax.xaxis.set_major_locator(plt.MultipleLocator(1))
    ax.xaxis.set_minor_locator(plt.MultipleLocator(0.1))
    ax.yaxis.set_major_locator(plt.MultipleLocator(250))
    ax.yaxis.set_minor_locator(plt.MultipleLocator(50))
    # 绘制刻度网格线
    ax.grid(which='major', axis='both', color='orangered', linewidth=0.75)
    ax.grid(which='minor', axis='both', color='orangered', linewidth=0.25)
    plt.semilogy(y, 'o-')
    
    plt.show()
    View Code

    解决中文乱码问题

    默认情况下,Matplotlib中文会出现乱码,只显示方框。

    import matplotlib.pyplot as plt
    
    x = ['北京', '上海', '深圳', '广州']
    y = [60000, 58000, 50000, 52000]
    
    plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
    plt.rcParams['axes.unicode_minus']=False #用来正常显示符号
    
    plt.plot(x, y)
    plt.gcf().autofmt_xdate()  # 自动设置旋转,避免重叠
    plt.show()

     只需要配置一下后台字体就可以了。

     matplotlib官方文档

     Python 机器学习库 NumPy 教程

    会动的音频

  • 相关阅读:
    [SQL]数据更新
    Hadoop之mapred
    hadoop之hdfs
    HTML —— 11.25日总结
    HTML —— 11.19日的总结
    三个爬虫的小栗子
    HTML —— video标签
    py爬虫 —— 三个爬虫的小栗子
    HTML —— img标签
    py爬虫 —— py爬虫requests
  • 原文地址:https://www.cnblogs.com/LXP-Never/p/9724374.html
Copyright © 2011-2022 走看看