zoukankan      html  css  js  c++  java
  • matplotlib:python数据处理三剑客之一

    1.基本使用

    import numpy as np
    import matplotlib.pyplot as plt
    import pandas as pd
    
    # 生成一系列x
    x = np.linspace(-1, 1, 50)
    # 生成对应的y
    y1 = 2 * x +1
    y2 = x ** 2
    # 传入对应的x和y,调用plot方法,绘制图像
    # plot会将所有的点连起来
    plt.plot(x, y1)
    plt.plot(x, y2)
    plt.show()
    

    2.调整图像大小

    x = np.linspace(-1, 1, 50)
    y1 = 2 * x +1
    y2 = x ** 2
    # 图像是画在画布上面的
    plt.figure(figsize=(8, 5))
    plt.plot(x, y1)
    plt.plot(x, y2)
    plt.show()
    

    3.绘制基本图形(折线图)

    3.1 基本绘制

    x = np.linspace(-1, 1, 50)
    y1 = 2 * x +1
    y2 = x ** 2
    plt.figure(figsize=(8, 5))
    # 其实之前介绍过了,就是使用plot方法即可
    plt.plot(x, y1)
    plt.plot(x, y2)
    plt.show()
    

    3.2 设置样式

    x = np.linspace(-1, 1, 50)
    y1 = 2 * x +1
    y2 = x ** 2
    plt.figure(figsize=(8, 5))
    
    # linestyle:表示线段的样式
    # color:表示颜色
    # marker:表示点的样式
    plt.plot(x, y1, linestyle="-", color="cyan", marker="o")
    plt.plot(x, y2, linestyle="--", color="red", marker="<")
    plt.show()
    

    关于样式:

    • linestyle

      '-' solid line style
      '--' dashed line style
      '-.' dash-dot line style
      ':' dotted line style
      
    • marker

      '.'       point marker
      ','       pixel marker
      'o'       circle marker
      'v'       triangle_down marker
      '^'       triangle_up marker
      '<'       triangle_left marker
      '>'       triangle_right marker
      '1'       tri_down marker
      '2'       tri_up marker
      '3'       tri_left marker
      '4'       tri_right marker
      's'       square marker
      'p'       pentagon marker
      '*'       star marker
      'h'       hexagon1 marker
      'H'       hexagon2 marker
      '+'       plus marker
      'x'       x marker
      'D'       diamond marker
      'd'       thin_diamond marker
      '|'       vline marker
      '_'       hline marker
      

    4.设置坐标轴

    4.1 设置坐标轴范围和描述

    # 将x修改一下, 改成-10到10
    x = np.linspace(-10, 10, 50)
    y1 = 2 * x +1
    y2 = x ** 2
    plt.figure(figsize=(8, 5))
    
    plt.plot(x, y1, linestyle="-", color="cyan", marker="o")
    plt.plot(x, y2, linestyle="--", color="red", marker="<")
    
    plt.xlim([-5, 5])  # 设置x坐标轴的范围是-5到5
    plt.ylim([-10, 20])  # 设置y坐标轴的范围是-10到20
    # 调整坐标轴范围还可以使用plt.axis([-5, 5, -10, 20])这种形式
    plt.xlabel("i am x axis")  # 设置x轴描述
    plt.ylabel("i am y axis")  # 设置y轴描述
    plt.show()
    

    4.2 设置坐标轴刻度

    x = np.linspace(-10, 10, 50)
    y1 = 2 * x +1
    y2 = x ** 2
    plt.figure(figsize=(8, 5))
    
    plt.plot(x, y1, linestyle="-", color="cyan", marker="o")
    plt.plot(x, y2, linestyle="--", color="red", marker="<")
    
    plt.xlim([-5, 5])  
    plt.ylim([-10, 20])  
    plt.xlabel("i am x axis")  
    plt.ylabel("i am y axis")  
    
    # 坐标轴属性可以通过gca = plt.gca()获取
    # 然后通过gca.属性去调节
    # 但是对于坐标轴刻度的话,和坐标轴范围一样,是可以直接通过plt来调节的
    plt.locator_params(nbins=20)  # 表示将轴分成20份
    # 如果只想对某一个轴,比如x轴去调节的话,可以通过plt.locator_params("x", nbins=20)
    
    plt.show()
    # 怎么样,是不是变密了呢?
    

    4.3 设置坐标轴倾斜角度以及曲线标记

    我们注意到x轴的刻度虽然多了,但是快连在一起,我们可不可以让其歪一些呢?这样就不会连接一起了,而且图上面有两个曲线,我们可不可以给每个曲线做个标记呢?

    x = np.linspace(-10, 10, 50)
    y1 = 2 * x +1
    y2 = x ** 2
    plt.figure(figsize=(8, 5))
    
    # 做标记的话,只需要加上一个label参数即可
    plt.plot(x, y1, linestyle="-", color="cyan", marker="o", label="2 * x + 1")
    plt.plot(x, y2, linestyle="--", color="red", marker="<", label="x ** 2")
    
    plt.xlim([-5, 5])  
    plt.ylim([-10, 20])  
    plt.xlabel("i am x axis")  
    plt.ylabel("i am y axis")  
    plt.locator_params(nbins=20)  
    
    # 通过plt.xticks调整x轴刻度,同理y轴的话就是yticks
    plt.xticks(rotation=60)  # 倾斜60度
    
    # 这一步是为了让plot中设置的label显示出来,没有这一句是不会显示的
    # 而且会自动帮我们找到一个合适的位置
    plt.legend() # 还可以加上一个loc='best',会寻找最好的位置,这里没有加,位置也是不错的
    plt.show()
    

    4.4 设置网格

    背景光秃秃的,不是很好看,我们也可以设置一些网格

    x = np.linspace(-10, 10, 50)
    y1 = 2 * x +1
    y2 = x ** 2
    plt.figure(figsize=(8, 5))
    plt.plot(x, y1, linestyle="-", color="cyan", marker="o", label="2 * x + 1")
    plt.plot(x, y2, linestyle="--", color="red", marker="<", label="x ** 2")
    
    plt.xlim([-5, 5])  
    plt.ylim([-10, 20])  
    plt.xlabel("i am x axis")  
    plt.ylabel("i am y axis")  
    plt.locator_params(nbins=20)  
    plt.xticks(rotation=60) 
    plt.legend() 
    
    # 设置网格
    plt.grid(color="pink")  # 此外plt.title("title")还可以设置标题
    plt.show()
    

    可以看到,需要什么样式,直接设置即可,会叠加在一起。我们这里的plot是折线图,而这些样式、属性啊在其他大部分图形上都是通用的

    4.5 自定义坐标轴

    x = np.linspace(-10, 10, 50)
    y1 = 2 * x +1
    y2 = x ** 2
    plt.figure(figsize=(8, 5))
    plt.plot(x, y1, linestyle="-", color="cyan", marker="o", label="2 * x + 1")
    plt.plot(x, y2, linestyle="--", color="red", marker="<", label="x ** 2")
    
    plt.xlim([-5, 5])  
    plt.ylim([-10, 20])  
    plt.xlabel("i am x axis")  
    plt.ylabel("i am y axis")  
    plt.locator_params(nbins=20)  
    plt.xticks(rotation=60) 
    # 将2 4 6 8换成对应的英文
    plt.yticks([2, 4, 6, 8], ["two", "four", "six", "eight"])
    plt.legend() 
    
    plt.grid(color="green")
    plt.show()
    

    但是这样其他的刻度就没了,因此我们只能手动调整。

    x = np.linspace(-10, 10, 50)
    y1 = 2 * x +1
    y2 = x ** 2
    plt.figure(figsize=(8, 5))
    plt.plot(x, y1, linestyle="-", color="cyan", marker="o", label="2 * x + 1")
    plt.plot(x, y2, linestyle="--", color="red", marker="<", label="x ** 2")
    
    plt.xlim([-5, 5])  
    plt.ylim([-10, 20])  
    plt.xlabel("i am x axis")  
    plt.ylabel("i am y axis")  
    plt.locator_params(nbins=20)  
    plt.xticks(rotation=60) 
    
    # 将坐标轴替换
    y_axis = list(range(-10, 20, 2))
    new_y_axis = list(map(lambda x: "two" if x == 2 else "four" if x == 4 else "six" if x == 6 else "eight" if x == 8 else x, y_axis))
    plt.yticks(y_axis, new_y_axis)
    plt.legend() 
    
    plt.grid(color="green")
    plt.show()
    

    4.6 设置边框属性

    我们发现目前的图形是一个矩形,也就是有四条线,如果我们想只有左边和下边的线呢?

    x = np.linspace(-10, 10, 50)
    y1 = 2 * x +1
    y2 = x ** 2
    plt.figure(figsize=(8, 5))
    plt.plot(x, y1, linestyle="-", color="cyan", marker="o", label="2 * x + 1")
    plt.plot(x, y2, linestyle="--", color="red", marker="<", label="x ** 2")
    
    plt.xlim([-5, 5])  
    plt.ylim([-10, 20])  
    plt.xlabel("i am x axis")  
    plt.ylabel("i am y axis")  
    plt.locator_params(nbins=20)  
    plt.xticks(rotation=60) 
    plt.legend() 
    
    # 获取坐标轴
    gca = plt.gca()  # get current axis
    # gca.spines拿到四个坐标轴,left、right、top、bottom,将上边和右边的坐标轴的颜色设置为none,隐藏起来即可
    gca.spines["right"].set_color("none")  
    gca.spines["top"].set_color("none")  
    # 将左边和下边的颜色设置成粉色和绿色,显眼一点
    gca.spines["left"].set_color("pink")
    gca.spines["bottom"].set_color("green")
    plt.show()
    

    4.7 调整移动坐标轴

    目前坐标轴不是我们上学学的那种二维直角坐标系,怎么变成那种坐标系呢?

    x = np.linspace(-10, 10, 50)
    y1 = 2 * x +1
    y2 = x ** 2
    plt.figure(figsize=(8, 5))
    plt.plot(x, y1, linestyle="-", color="cyan", marker="o", label="2 * x + 1")
    plt.plot(x, y2, linestyle="--", color="red", marker="<", label="x ** 2")
    
    plt.xlim([-5, 5])  
    plt.ylim([-10, 20])  
    plt.xlabel("i am x axis")  
    plt.ylabel("i am y axis")  
    plt.locator_params(nbins=20)  
    plt.xticks(rotation=60) 
    plt.legend() 
    
    gca = plt.gca()  # get current axis
    gca.spines["right"].set_color("none")  
    gca.spines["top"].set_color("none")  
    gca.spines["left"].set_color("pink")
    gca.spines["bottom"].set_color("green")
    
    # 写法比较固定,将下边的左边的轴的位置设置为('data', 0)
    gca.spines['bottom'].set_position(('data', 0))
    gca.spines['left'].set_position(('data',0))
    
    plt.show()
    

    可以看到,坐标轴移动了。但是这样有一个缺陷,那就是坐标轴的描述还处在原来的位置,和坐标轴以及刻度重叠了

    x = np.linspace(-10, 10, 50)
    y1 = 2 * x +1
    y2 = x ** 2
    plt.figure(figsize=(8, 5))
    plt.plot(x, y1, linestyle="-", color="cyan", marker="o", label="2 * x + 1")
    plt.plot(x, y2, linestyle="--", color="red", marker="<", label="x ** 2")
    
    plt.xlim([-5, 5])  
    plt.ylim([-10, 20])  
    plt.xlabel("i am x axis")  
    plt.ylabel("i am y axis")  
    plt.locator_params(nbins=20)  
    plt.xticks(rotation=60) 
    plt.legend() 
    
    gca = plt.gca()  # get current axis
    gca.spines["right"].set_color("none")  
    gca.spines["top"].set_color("none")  
    gca.spines["left"].set_color("pink")
    gca.spines["bottom"].set_color("green")
    
    gca.spines['bottom'].set_position(('data', 0))
    gca.spines['left'].set_position(('data',0))
    
    # 将x轴刻度设置为上方
    # y轴刻度设置为右方
    gca.xaxis.set_ticks_position("top")
    gca.yaxis.set_ticks_position("right")
    
    plt.show()
    

    感觉这样好白痴啊,不过无所谓,知道有这么个语法就可以了,也不常用

    4.8 添加注释

    x = np.arange(-10, 11)
    y = x ** 2
    plt.plot(x, y)
    plt.annotate("my name is satori",
                xy=(0, 5),  # 箭头坐标
                xytext=(0, 20),  # 文本坐标
                arrowprops={
                    "facecolor": "red",  # 颜色
                    "headlength": 10,  # 箭头长度
                    "headwidth": 30,  # 箭头的头的宽度,
                    "width": 20  # 箭头的身体的宽度
                })
    plt.show()
    

    5.绘制基本图形(散点图)

    x = np.random.normal(0, 1, 1024)
    y = np.random.normal(0, 1, 1024)
    # 散点图使用scatter函数,半藏的散
    plt.scatter(x, y)
    plt.show()
    

    当然散点图也可以指定样式

    plt.figure(figsize=(10, 8))
    x = np.random.normal(0, 1, 100)
    y = np.random.normal(0, 1, 100)
    
    # s:点的大小
    # color:颜色,不指定默认为蓝色
    # marker:形状,不指定默认为点。marker和plot里面的marker是一样的
    # alpha:透明度,不指定默认为1
    plt.scatter(x, y, s=75, color="green", marker="<", alpha=0.2)
    plt.show()
    

    关于颜色的问题,其实还有一个参数c,这个c是一个数组。举个例子吧,plt.scatter([1, 2, 3, 4], [2, 4, 6, 8], c=[0, 1, 1, 0]),首先x和y组合会形成四个点,坐标分别是(1, 2), (2, 4), (3, 6), (4, 8),而c是与之等长的数组,c是[0, 1, 1, 0],那么按照索引对应,如果对应c中是0的都是一个颜色,对应到1的都是一个颜色。我们在机器学习,对样本进行聚类的时候,就可以将样本标签(label)做为c,这样的话,不同的样本特征就会对应不同的颜色,这样通过颜色我们可以看出聚类的效果好不好。

    plt.figure(figsize=(10, 8))
    # x和y都是-10到10
    x = np.random.randint(-10, 10, 100)
    y = np.random.randint(-10, 10, 100)
    c = []
    for v in zip(x, y):
        # 如果x+y<0,我们分类为0
        # 如果0<=x+y<10,我们分类为1
        # 如果10<=x+y<20,我们分类为2
        if sum(v) < 0:
            c.append(0)
        elif sum(v) < 10:
            c.append(1)
        else:
            c.append(2)
            
    plt.scatter(x, y, c=c)
    plt.show()
    

    可以看出紫色的点是两个坐标之和小于0的,绿色的则是坐标之和位于0到10的,黄色的是坐标之和位于10到20的。

    plt.figure(figsize=(10, 8))
    # x和y都是-10到10
    x = np.random.normal(-1, 1, 1000)
    y = np.random.normal(-1, 1, 1000)
    c = np.arctan2(y, x)
    
    plt.axis([-1.5, 1.5, -1.5, 1.5])
    gca = plt.gca()
    gca.spines["left"].set_color("none")
    gca.spines["right"].set_color("none")
    gca.spines["top"].set_color("none")
    gca.spines["bottom"].set_color("none")
    # 如果xticks或者yticks里面传入一个空元祖或者空列表的话表示隐藏掉坐标轴
    plt.xticks(())
    plt.yticks([])
    
    plt.scatter(x, y, s=100, c=c, alpha=0.5)
    plt.show()
    

    6.绘制基本图形(条形图)

    plt.figure(figsize=(10, 8))
    # 还记得每一个图对应的每一个函数吗?
    # 散点图:scatter
    # 折线图:plot
    # 条形图:bar
    
    # 这个函数可以只接收两个参数,分别是条形图中每一条的索引和高度
    plt.bar(x=[0, 1, 2, 3, 4, 5], height=[11, 22, 33, 44, 55, 66])
    plt.show()
    

    当然也可以指定样式

    plt.figure(figsize=(10, 8))
    
    # facecolor:条形图内部填充色
    # edgecolor:条形图边框颜色
    # width:宽度
    plt.bar(x=[0, 1, 2, 3, 4, 5], height=[11, 22, 33, 44, 55, 66],
            edgecolor="blue",
            color="green",
            width=0.2)
    plt.show()
    

    绘制多个条形图

    plt.figure(figsize=(10, 8))
    X =[0, 1, 2, 3, 4, 5]
    height1 = [11, 22, 33, 44, 55, 66]
    height2 = [-11, -22, -33, -44, -55, -66]
    plt.bar(X,height1,
            edgecolor="blue",
            color="green",
            width=0.2)
    
    plt.bar(X, height2,
            edgecolor="pink",
            color="red",
            width=0.2)
    
    # 但是这样不够用美观,我们可以把轴隐藏掉
    # 对应值标记在对应条形图的上下方
    for x, y in zip(X, height1):
        # x, y表示坐标,我们上移一点,那么x保持不变,y增大一点
        # 第三个y则表示的是对应值
        # ha表示横向,v表示纵向,center是居中,bottom向下对其
        plt.text(x, y+0.1, y, ha="center", va="bottom")
        
    for x, y in zip(X, height2):
        # 这里的y要减少一点,因为向下的条形图部分
        plt.text(x, y-0.1, y, ha="center", va="top")
        
    plt.show()
    

    7.绘制基本图形(等高线图)

    n=256
    x=np.linspace(-3,3,n)
    y=np.linspace(-3,3,n)
    X,Y=np.meshgrid(x,y)
    
    #f函数用来计算高度值 
    def f(x,y):
        return (1 - x / 2 + x ** 5 + y ** 3) * np.exp(-x ** 2 - y ** 2)
    
    # 利用contour函数把颜色加进去 位置参数依次为X,Y,f(X,Y),8, 透明度为0.75,并将f(X,Y)的值对应到camp之中
    plt.contourf(X,Y,f(X,Y),8,alpha=0.75,cmap=plt.cm.hot)# 8表示等高线分成多少份 alpha表示透明度 cmap表示color map
    #使用plt.contour函数进行等高线绘制 参数依次为x,y,f(x,y),颜色选择黑色,线条宽度为0.5
    C=plt.contour(X,Y,f(X,Y),8,colors='black',linewidth=0.5)
    #使用plt.clabel添加高度数值 inline控制是否将label画在线里面,字体大小为10
    plt.clabel(C,inline=True,fontsize=10)
    plt.xticks(())#隐藏坐标轴
    plt.yticks(())
    plt.show()
    

    8.绘制基本图形(直方图)

    mu = 100
    sigma = 20
    x = mu + sigma * np.random.randn(2000)
    
    # 设置直方图
    # bins:表示要分成多少个区间
    # normed:表示是否进行标准化,标准化之后,阿么纵坐标不在是个数,而是频率
    plt.hist(x, bins=30, color="green", density=True)
    plt.show()
    

    9.绘制基本图形(双变量直方图)

    x = np.random.randn(1000)+2
    y = np.random.randn(1000)+3
     
     
    plt.hist2d(x, y, bins=40)
     
    plt.show()
    

    10.基本图形绘制(饼图)

    labels = ["satori", "mashiro", "nagisa"]
    fracs = [40, 30, 30]
     
    # 最重要的两个参数
    # x:所占的份额
    # labels:对应的标签
    plt.pie(x=fracs, labels=labels)
    plt.show()
    

    也可以指定样式

    labels = ["satori", "mashiro", "nagisa"]
    fracs = [40, 30, 30]
     
    # autopct:表示每一块的比例
    # explode:突出显示,每个部分不会贴在一块
    # shadow:加上一层阴影,指定为True即可
    plt.pie(x=fracs, labels=labels, autopct="%.0f%%", explode=[0.01, 0.2, 0.1], shadow=True)
    plt.show()
    

    11.基本图形绘制(箱型图)

    np.random.seed(100)
    data = np.random.normal(0, 1, size=1000)
    
    # sym:形状,表示异常值的形状
    # whis:表示虚线的长度,可以控制异常值显示的多少,越大虚线越长
    plt.boxplot(data, sym="<", whis=1.5)
    plt.show()
    

    12.3D图形绘制(不常用)

    from mpl_toolkits.mplot3d import Axes3D as A3
    fig = plt.figure(figsize=(10, 8))
    ax = A3(fig) 
    x = np.arange(-4, 4, 0.2)
    y = np.arange(-4, 4, 0.2)
    x, y = np.meshgrid(x, y)
    z = np.power(x, 2) + np.power(y, 2)
    plt.title("satori")
    
    # rstride,cstride表示行列每隔多少个点建一个面,cmap表示颜色
    ax.plot_surface(x, y, z, rstride=1,
                    cstride=1,
                    cmap=plt.cm.CMRmap,
                    alpha=0.4)
    ax.set_xlabel('x_label', color='r')
    ax.set_ylabel('y_label', color='g')
    ax.set_zlabel('z_label', color='b')
     
    plt.show()
    

    13.多图绘制

    规则排列

    方法一:

    x = np.arange(1, 100, 5)
     
    # 生成一个画布
    fig = plt.figure(figsize=(10, 8))
     
    # 往画布上添加对象
    # 这里的221表示,将画布分成2X2份,并处于第一个位置
    # 222则是第二个位置,注意是先从左往右,再从上往下
    s1 = fig.add_subplot(221)
    s2 = fig.add_subplot(222)
    s3 = fig.add_subplot(223)
    s4 = fig.add_subplot(224)
    y1 = np.log(x)
    y2 = np.sin(x)
    y3 = np.cos(x)
    y4 = x ** 2
    
    # 这里不再使用plt.plot,而是使用s
    s1.plot(x, y1, color="green", marker="x", linestyle="--")
    s2.plot(x, y2, color="blue", marker="o", linestyle="-.")
    s3.plot(x, y3, color="cyan", marker="<", linestyle="--")
    s4.plot(x, y4, color="yellow", marker=">", linestyle="-.")
    plt.show()
    

    方法二:

    import numpy as np
    import matplotlib.pyplot as plt
     
    x = np.arange(1, 100, 5)
    
    plt.figure(figsize=(10, 8))
    # 这里可以直接使用plt.subplot
    plt.subplot(221)
    plt.plot(x, np.log(x))
    plt.subplot(222)
    plt.plot(x, np.sin(x))
    plt.subplot(223)
    plt.plot(x, np.cos(x))
    plt.subplot(224)
    plt.plot(x, x**2)
     
    plt.show()
    

    这里没有设置样式,但是基本上是一样的。

    不规则排列

    x = np.arange(1, 100, 5)
     
    # 生成一个画布
    fig = plt.figure(figsize=(10, 8))
    
    
    # 分成3行3列
    """
    1 2 3
    4 5 6
    7 8 9
    """
    s1 = fig.add_subplot(331)
    s2 = fig.add_subplot(335)
    s3 = fig.add_subplot(337)
    s4 = fig.add_subplot(339)
    y1 = np.log(x)
    y2 = np.sin(x)
    y3 = np.cos(x)
    y4 = x ** 2
    
    # 这里不再使用plt.plot,而是使用s
    s1.plot(x, y1, color="green", marker="x", linestyle="--")
    s2.plot(x, y2, color="blue", marker="o", linestyle="-.")
    s3.plot(x, y3, color="cyan", marker="<", linestyle="--")
    s4.plot(x, y4, color="yellow", marker=">", linestyle="-.")
    plt.show()
    

    这样尽管不规则,但是一张图还是只占据一份的面积,比如第一张图,如果我想让其填满其所在的一整行,该怎么办呢?

    x = np.arange(1, 100, 5)
     
    # 生成一个画布
    fig = plt.figure(figsize=(10, 8))
    
    # 先计算好,我要分为几行显示
    # 比如第一张图显示第一行,填满
    # 第二张和第三张显示在第二行
    # 第四张显示在第三行,填满
    
    # 先分成3行1列,选择311,会把第一行占满
    s1 = fig.add_subplot(311)  
    s2 = fig.add_subplot(323)  # 由于第一张图把第一张占满了,那么3X2的基础上相当于1和2被占了,所以这里是323
    s3 = fig.add_subplot(324)
    s4 = fig.add_subplot(313)  # 这里是313,表示3X1,占满第三行
    y1 = np.log(x)
    y2 = np.sin(x)
    y3 = np.cos(x)
    y4 = x ** 2
    
    # 这里不再使用plt.plot,而是使用s
    s1.plot(x, y1, color="green", marker="x", linestyle="--")
    s2.plot(x, y2, color="blue", marker="o", linestyle="-.")
    s3.plot(x, y3, color="cyan", marker="<", linestyle="--")
    s4.plot(x, y4, color="yellow", marker=">", linestyle="-.")
    plt.show()
    

    分格显示

    方法一:

    fig = plt.figure(figsize=(10, 8))
    
    # subplot2grid创建小图
    # (3, 3)表示将整个图像分格为3行3列,(0, 0)表示从第1行和第1列开始
    # colspan表示跨3列,还有一个rowspan,不指定默认为1
    ax1 = plt.subplot2grid((3,3), (0, 0), colspan=3)
    # 从第2行第1列开始,跨两列
    ax2 = plt.subplot2grid((3, 3), (1, 0), colspan=2)
    # 从第2行第3列开始,跨两行
    ax3 = plt.subplot2grid((3, 3), (1, 2), rowspan=2)
    # 从第3行第1列开始,默认跨一行、一列
    ax4 = plt.subplot2grid((3, 3), (2, 0))
    # 从第3行第2列开始
    ax5 = plt.subplot2grid((3, 3), (2, 1))
    x = np.arange(1, 100, 5)
    y1 = np.log(x)
    y2 = np.sin(x)
    y3 = np.cos(x)
    y4 = x ** 2
    y5 = (1 + np.exp(-x))
    
    # 这里不再使用plt.plot,而是使用ax
    ax1.plot(x, y1, color="green", marker="x", linestyle="--")
    ax2.plot(x, y2, color="blue", marker="o", linestyle="-.")
    ax3.plot(x, y3, color="cyan", marker="<", linestyle="--")
    ax4.plot(x, y4, color="yellow", marker=">", linestyle="-.")
    ax5.plot(x, y5, color="yellow", marker=">", linestyle="-.")
    plt.show()
    

    当然也可以这么写

    fig = plt.figure(figsize=(10, 8))
    
    x = np.arange(1, 100, 5)
    y1 = np.log(x)
    y2 = np.sin(x)
    y3 = np.cos(x)
    y4 = x ** 2
    y5 = (1 + np.exp(-x))
    
    plt.subplot2grid((3,3), (0, 0), colspan=3)
    plt.plot(x, y1, color="green", marker="x", linestyle="--")
    
    plt.subplot2grid((3, 3), (1, 0), colspan=2)
    plt.plot(x, y2, color="blue", marker="o", linestyle="-.")
    
    plt.subplot2grid((3, 3), (1, 2), rowspan=2)
    plt.plot(x, y3, color="cyan", marker="<", linestyle="--")
    
    plt.subplot2grid((3, 3), (2, 0))
    plt.plot(x, y4, color="yellow", marker=">", linestyle="-.")
    
    plt.subplot2grid((3, 3), (2, 1))
    plt.plot(x, y5, color="yellow", marker=">", linestyle="-.")
    
    plt.show()
    

    方法二:

    import matplotlib.gridspec as grid_spec  # 引入新的模块
     
    fig = plt.figure(figsize=(10, 8))
    
    x = np.arange(1, 100, 5)
    y1 = np.log(x)
    y2 = np.sin(x)
    y3 = np.cos(x)
    y4 = x ** 2
    y5 = (1 + np.exp(-x))
    
    gs = grid_spec.GridSpec(3, 3)  # 还是将图像分成3行3列
    
    # plt.subplot2grid((3,3), (0, 0), colspan=3)
    plt.subplot(gs[0, :])  # 占第一行和所有列
    plt.plot(x, y1, color="green", marker="x", linestyle="--")
    
    # plt.subplot2grid((3, 3), (1, 0), colspan=2)
    plt.subplot(gs[1, : 2])
    plt.plot(x, y2, color="blue", marker="o", linestyle="-.")
    
    # plt.subplot2grid((3, 3), (1, 2), rowspan=2)
    plt.subplot(gs[1: , 2])
    plt.plot(x, y3, color="cyan", marker="<", linestyle="--")
    
    # plt.subplot2grid((3, 3), (2, 0))
    plt.subplot(gs[2, 0])
    plt.plot(x, y4, color="yellow", marker=">", linestyle="-.")
    
    # plt.subplot2grid((3, 3), (2, 1))
    plt.subplot(gs[2, 1])
    plt.plot(x, y5, color="yellow", marker=">", linestyle="-.")
    
    plt.show()
    

    14.添加坐标轴

    plt.figure(figsize=(10, 8))
    
    x = np.linspace(0, 10, 100)
    y1 = np.sin(x)
    y2 = np.cos(x)
    
    # 调用subplot不加参数,得到相应坐标轴
    ax1 = plt.subplot()
    # 生成一个双胞胎y轴
    ax2 = ax1.twinx()
    
    # 直接使用plt绘制即可,无需使用ax1和ax2,当然使用这两个也能绘制。
    plt.plot(x, y1, color="red", label="sin")
    plt.plot(x, y2, color="green", label="cos")
    plt.legend()
    plt.show()
    

    15.动画

    曲线的生成过程

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.animation as anime
    
    %matplotlib notebook
    fig = plt.figure(figsize=(10, 8))
    plt.grid(color="pink", linestyle="--")
    
    # 生成x,y数据
    x = np.linspace(0, 2 * np.pi, 100)
    y = np.sin(x)
    
    # plt.plot可以有返回值,这里必须是"ani,"  不是"ani" ,切记,否则动图是不会生成的
    # 这里的ani,拿到的是整个曲线
    ani, = plt.plot(x, y)
    
    
    # 构造函数,用来更新每一帧的x和y的值
    # 参数i表示第i帧
    def update_x_y(i):
        # 设置每一帧对应的曲线的坐标
        # 这里我们每次将x增大或者减小一点,这样图像才会移动
        # 至于增大或者减小的程度,由x决定
        # 让图像上的x的每个元素都随着帧数的增加而增大,这样就有了图像向右边走的效果
        ani.set_ydata(np.sin(x+i/100))
        return ani,   # 这里是要返回的,但是记住同样是"ani," 不是"ani"
    
    
    # 这里也要赋值,否则动图不会显示
    # fig:绘图对象
    # func:更新动画的函数
    # frames:一共要多少帧,这里是一个数组,也可以直接传入200
    # interval:间隔
    # blit:是否开启渲染
    f = anime.FuncAnimation(
        fig=fig,
        func=update_x_y,
        frames=np.arange(200),
        interval=20,
        blit=True
    )
    
    plt.show()
    

    大概长这样,声明一下,我这图像是在notebook里面生成的,但是我没有ffmpeg,无法自动合并。因此只能以html形式保存,然后到本地变成了一大堆的png,然后手动使用imageio模块,转成了gif,因此曲线变化的速度可能不和notebook不一样。

    曲线不动,一个点在曲线上面走

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.animation as anime
    
    %matplotlib notebook
    fig = plt.figure(figsize=(10, 8))
    plt.grid(color="pink", linestyle="--")
    
    # 生成x,y数据
    x = np.linspace(0, 2 * np.pi, 100)
    y = np.sin(x)
    
    # 绘制整个图像
    plt.plot(x, y)
    # 使用第一个点
    ani, = plt.plot(x[0], y[0], color="green", marker="o")
    
    # 构造函数,用来更新每一帧的x和y的值
    # 参数i表示第i帧
    def update_x_y(i):
        # set_ydata表示更新y的值,之前的ani,是用plt.plot(x, y)生成的,是一整条曲线
        # 这里的ani,是用plt.plot(x[0], y[0])生成的,是一个点
        # 而且这里是set_data,表示set_ydata,所以这里要传入两个参数,两个参数组成一个点。
        # 随着i的变化,这个点的坐标也在变化
        ani.set_data(x[i], y[i])
        return ani,   # 这里是要返回的,但是记住同样是"ani," 不是"ani"
    
    
    # 这里也要赋值,否则动图不会显示
    # fig:绘图对象
    # func:更新动画的函数
    # frames:一共要多少帧,这里是一个数组,也可以直接传入200
    # interval:间隔
    # blit:是否开启渲染
    f = anime.FuncAnimation(
        fig=fig,
        func=update_x_y,
        frames=np.arange(100),
        interval=100,
        blit=True
    )
    
    plt.show()
    

    我们把点的坐标也加上去吧

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.animation as anime
    
    %matplotlib notebook
    fig = plt.figure(figsize=(10, 8))
    plt.grid(color="pink", linestyle="--")
    
    x = np.linspace(0, 2 * np.pi, 100)
    y = np.sin(x)
    
    plt.plot(x, y)
    ani, = plt.plot(x[0], y[0], color="green", marker="o")
    text = plt.text(4, 0.5, "", fontsize=16)
    # 构造函数,用来更新每一帧的x和y的值
    # 参数i表示第i帧
    def update_x_y(i):
        if i % 2 == 0:
            ani.set_marker("*")
            ani.set_markersize(20)
            ani.set_color("pink")
        else:
            ani.set_marker("o")
            ani.set_markersize(14)
            ani.set_color("blue")
        ani.set_data(x[i], y[i])
        text.set_position((x[i], y[i]))
        text.set_text(f"x={round(x[i], 3)} y={round(y[i], 3)}")
        return ani, text
    
    
    f = anime.FuncAnimation(
        fig=fig,
        func=update_x_y,
        frames=np.arange(100),
        interval=100,
        blit=True
    )
    plt.show()
    

    常见问题:

    1.子图重合的时候

    加上plt.tight_layout()即可

    2.当出现中文,显示为乱码的时候

    import numpy as np
    import matplotlib.pyplot as plt
    
    x = np.arange(5)
    y = x + 3
    
    plt.plot(x, y)
    plt.xlabel("我是x轴")
    plt.ylabel("我是y轴")
    plt.show()
    

    可以看到,label无法正常显示

    import numpy as np
    import matplotlib.pyplot as plt
    
    x = np.arange(5)
    y = x + 3
    
    plt.rcParams['font.sans-serif'] = ['SimHei'] # 步骤一(替换sans-serif字体)
    plt.rcParams['axes.unicode_minus'] = False   # 步骤二(解决坐标轴负数的负号显示问题)
    
    plt.plot(x, y)
    plt.xlabel("我是x轴")
    plt.ylabel("我是y轴")
    plt.show()
    

    正常显示

  • 相关阅读:
    python基本数据类型之整型和浮点型
    Java学习路线
    Linux学习笔记之VIM
    Java基础之流程控制
    Linux学习笔记之Shell
    Java基础之数据类型
    论文提交说明
    IDEA安装教程
    Link summary for writing papers
    1 类基础知识
  • 原文地址:https://www.cnblogs.com/traditional/p/11425466.html
Copyright © 2011-2022 走看看