• Matplotlib:科研绘图利器(写论文、数据可视化必备)


    前言

    我们知道Matlab是一个非常强大的数学计算工具,功能齐全,很多从事数学专业以及计算机科学相关的人员都比较喜欢使用,但是脱离了Matlab我们该怎么办呢?我自己是做深度学习的,平时使用Python居多,对于Matlab不是很熟,所以在平时对实验数据进行可视化时就需要借助一些第三方库来替代,而Python很贴心地为我们准备了一切,我们通过使用第三方库:Numpy+Scipy+Matplotlib基本可以替代Matlab。虽然之前也经常使用Matplotlib进行数据可视化,但一直未系统研究过,遇到一些问题只能疯狂百度,这篇文章我的目的是系统研究绘图组件并展示常见的一些图类型的绘制(这个会持续更新,具体根据科研需求)。
    matplotlib官网:https://matplotlib.org/stable/users/getting_started/

    1.安装方式

    pip install matplotlib
    
    • 1

    conda install matplotlib
    
    • 1

    2.Matplotlib绘图组件介绍

    通过对下图中的各个组件进行理解,可让我们清晰使用该方法绘图的结果具体包括哪些部件,这些部件代表什么含义以及根据需求该如何设置这些组件。
    在这里插入图片描述

    部件名含义
    figurefigure相当于给我们绘图提供了一块画板,可以自定义画板的大小
    axes在figure上绑定的一个控制所有坐标轴的对象,后续绘图可通过调用axes的方法或属性去设置
    axisaxes对象的元素,分别对应一个坐标轴,可用于设置坐标轴的比例、限度并生成刻度
    title所绘图的名字
    label每个坐标轴对应的标签名
    legend用于区分同一幅图中绘制的不同数据
    marker指定使用那种符号表示数据
    tick坐标轴上的刻度
    tick_label刻度的标签
    grid是否在图中展示网格

    我在这里对各个部件的含义做了简单解释,图中的ax即为我所说的axes对象,关于这些部件的设置完全根据图中的方法即可。
    获取axes对象最简单、最方便的方法如下:

    # 产生一个空白画板,并产生一个控制坐标轴的对象axes,后续绘图可通过调用axes的方法或属性去设置
    figure,axes=plt.subplots(figsize=(12,12)) 
    
    • 1
    • 2

    # 产生一个空白画板,并产生2行2列共4个控制坐标轴的对象axes,后续绘图可通过分别调用axes的方法或属性去设置
    figure,axes=plt.subplots(2,2,figsize=(12,12))
    
    • 1
    • 2

    3.举个例子

    我这里先举个例子,让大家对上面介绍的组件有更清晰的认识!

    import numpy as np
    from matplotlib import pyplot as plt
    
    x=np.random.randint(10,size=(10))
    y1=x
    y2=2*x
    figure,axes=plt.subplots()
    axes.set_title('time-speed')
    axes.set_ylabel('speed')
    axes.set_xlabel('time')
    axes.grid()
    axes.plot(x,y1)
    axes.plot(x,y2)
    axes.legend(['y=x','y=2x'])
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述

    绘图相关的基本介绍就到这里,接下来我们看看常见的几种图该如何绘制!!

    一、基本类型

    1.折线图/曲线图

    在绘制折线图或者曲线图时,主要使用plot()函数:

    import math
    
    import numpy as np
    from matplotlib import pyplot as plt
    from matplotlib.font_manager import FontProperties
    
    font=FontProperties(fname='./Fonts/simkai.ttf',size=14)
    
    # 1.折线图
    # x=[1, 2, 3, 4]
    # y=[5, 2, 7, 4]
    # figure,axes=plt.subplots()
    # axes.set_title('折线图',fontproperties=font)
    
    # 2.曲线图
    x=np.linspace(start=0,stop=10)
    # print(x)
    y=[2*math.pow(i,2)+i+1 for i in x]  # 2x*x+x+1
    # print(y)
    figure,axes=plt.subplots()
    axes.set_title('曲线图',fontproperties=font)
    
    axes.plot(x,y)
    axes.set_ylabel('y sequence')
    axes.set_xlabel('x sequence')
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    在这里插入图片描述
    在这里插入图片描述

    2.散点图

    绘制散点图时使用函数scatter(),该函数可以绘制散点图,其中点的大小和颜色既可以相同也可以不同:
    1)大小、颜色不同

    # 大小、颜色可以不同
    x=[1, 2, 3, 4,5,7,9]
    y=[5, 2, 7, 4,3,5,7]
    s=np.random.randint(105,200,size=len(x))
    c=np.random.randint(10,20,size=len(x))
    figure,axes=plt.subplots()
    axes.set_title('散点图',fontproperties=font)
    
    axes.scatter(x,y,s=s,c=c,)
    axes.set_ylabel('y sequence')
    axes.set_xlabel('x sequence')
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述
    2)大小、颜色相同

    x=[1, 2, 3, 4,5,7,9]
    y=[5, 2, 7, 4,3,5,7]
    s=np.random.randint(105,200,size=len(x))
    c=np.random.randint(10,20,size=len(x))
    figure,axes=plt.subplots()
    axes.set_title('散点图',fontproperties=font)
    
    axes.scatter(x,y,s=13,c='m',marker='D')
    axes.set_ylabel('y sequence')
    axes.set_xlabel('x sequence')
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    更多的标记类型、颜色类型可查看https://www.runoob.com/matplotlib/matplotlib-marker.html

    3.条形图/柱形图

    绘制柱形图时使用函数bar():

    x=['GDP_A', 'GDP_B', 'GDP_C', 'GDP_D']
    y=[5, 2, 7, 4]
    figure,axes=plt.subplots()
    axes.set_title('条形图/柱形图',fontproperties=font)
    
    axes.bar(x,y,width=0.5,align='center')  # 每个柱形宽度为0.5,中心对齐
    axes.set_ylabel('y sequence')
    axes.set_xlabel('x sequence')
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    二、统计数据绘制

    1.直方图

    绘制直方图时使用函数hist():

    x=np.random.randint(20,size=20)
    print(x)
    figure,axes=plt.subplots()
    axes.set_title('直方图',fontproperties=font)
    bins=[0,5,7.5,11,15]
    # axes.hist(x,bins=4,linewidth=0.5,edgecolor='black')
    axes.hist(x,bins=bins,linewidth=0.5,edgecolor='black')
    axes.set_ylabel('y sequence')
    axes.set_xlabel('x sequence')
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    大家知道直方图用来做数据统计,bins其实就是设定的划分条件,而x是输入的数据,在x中统计每个bins划分的区间中共有多少满足条件的数据。这里x=[ 9 19 7 14 16 19 6 18 14 19 2 7 14 18 3 4 19 17 16 14]一共20个数据,bins=[0,5,7.5,11,15]表示依次分为[0,5)、[5,7.5)等四个区间,然后对应统计出每个区间有几条数据即可,比如[0,5)区间一共有2、3、4这三个数据。注意,当bins为一个整数是没比如bins=4他会依据输入数据中最大、最小值自动对进行区间划分,并各自统计对应的数据量。
    在这里插入图片描述

    三、常见问题

    1.中文显示

    matplotlib默认是不支持中文字体显示的,但有时候架不住任务需要,这里我介绍一种方法供大家参考,设置中文显示分四步:
    1)下载需要的中文字体,这里使用的是楷体(可直接去C:/Windows/Fonts目录中复制);
    2)导入所需包:

    from matplotlib.font_manager import FontProperties
    
    • 1

    3)导入所需中文字体:

    font=FontProperties(fname='F:/Pycharm_Workspace/SummerJune/Matplot/Fonts/simkai.ttf',size=12)  # 加载字体
    
    • 1

    4)在设置title等时使用fontproperties属性进行设置;
    全部代码如下:

    import numpy as np
    from matplotlib import pyplot as plt
    from matplotlib.font_manager import FontProperties
    
    
    # 楷体
    font=FontProperties(fname='F:/Pycharm_Workspace/SummerJune/Matplot/Fonts/simkai.ttf',size=12)  # 加载字体
    
    x=np.random.randint(10,size=(10))
    y1=x
    y2=2*x
    figure,axes=plt.subplots()
    axes.set_title('时速图',fontproperties=font)
    axes.set_ylabel('速度',fontproperties=font)
    axes.set_xlabel('时间',fontproperties=font)
    axes.plot(x,y1)
    axes.plot(x,y2)
    axes.legend(['y=x','y=2x'])
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    2.坐标轴坐标范围、刻度以及刻度比例设置

    我相信大家之前绘图对于如何使坐标轴按照自己期望的刻度以及最大、最小值的显示都存在一些问题,这里就是解决这个问题:
    1)设置轴坐标范围

    # 设置轴坐标范围
    axes.set_ylim(bottom=-5,top=5)
    axes.set_xlim(left=-5,right=5)
    
    • 1
    • 2
    • 3

    2)设置坐标轴刻度比例

    # 设置坐标轴刻度比例:y轴每个刻度显示长度/x轴每个刻度显示长度
    axes.set_aspect(0.5)
    
    • 1
    • 2

    3)设置坐标轴刻度:分为主刻度和次刻度
    刻度定位通过Locator控制,刻度显示格式通过Formatter控制,这里以MultipleLocator和StrMethodFormatter举例,其他的见附图。

    # 此处仅以设置y轴为例,x轴设置类似
    axes.yaxis.set_major_locator(MultipleLocator(2.5))
    axes.yaxis.set_minor_locator(MultipleLocator(1))
    axes.yaxis.set_major_formatter(StrMethodFormatter('{x:.1f}'))
    axes.yaxis.set_minor_formatter(StrMethodFormatter('{x:.3f}'))
    
    • 1
    • 2
    • 3
    • 4
    • 5

    附图:
    不同Locator控制结果
    在这里插入图片描述
    不同Formatter控制结果
    在这里插入图片描述

    全部代码:

    from matplotlib import pyplot as plt
    import numpy as np
    from matplotlib.ticker import *
    
    # x=[2,5 ,7, 5 ,1, 2 ,8, 4 ,3 ,0]
    x=[ -5 , 9 , 8 ,-3  ,9 , 7,  2 , 1, -2 , 8]
    y1=[i for i in x]
    y2=[2*i for i in x]
    
    figure,axes=plt.subplots()
    axes.plot(x,y1)
    axes.plot(x,y2)
    # 设置轴坐标范围
    axes.set_ylim(bottom=-5,top=5)
    axes.set_xlim(left=-5,right=5)
    # 设置坐标轴刻度比例:y轴每个刻度显示长度/x轴每个刻度显示长度
    # axes.set_aspect(0.5)
    # 设置轴刻度:主刻度、次刻度
    axes.yaxis.set_major_locator(MultipleLocator(2.5))
    axes.yaxis.set_minor_locator(MultipleLocator(1))
    axes.yaxis.set_major_formatter(StrMethodFormatter('{x:.1f}'))
    axes.yaxis.set_minor_formatter(StrMethodFormatter('{x:.3f}'))
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    下图为仅设置了坐标范围的绘图结果:
    在这里插入图片描述
    在上图基础上我们对y轴的刻度以及其显示格式进行设置,结果如下:
    在这里插入图片描述

    参考:

    1)https://github.com/jakevdp/pythondatasciencehandbook/
    2)https://matplotlib.org/stable/users/getting_started/
    3)http://news.sohu.com/a/566946634_121118999
    明天开学了,写的略显粗糙,回学校接着补充!!加油哇大家!!
    奥对,每一个函数的其他参数大家可以查看他们对应的源码,也可以查看官网,都有解释!

  • 相关阅读:
    振南技术干货集:振南当年入门C语言和单片机的那些事儿(5)
    leetcode 1562. 查找大小为 M 的最新分组
    驱动基石之异步通知
    请使用java完成以下实验
    攻防世界-web-file_include
    双11的大型电商活动服务器崩溃是怎么回事?
    Redis-核心数据结构
    数据结构与算法------栈和队列
    Linux学习笔记(12) -- 登录、注销及关机
    DeepMind 发了篇论文,把我看笑了
  • 原文地址:https://blog.csdn.net/qq_43665602/article/details/126870205