Matplotlib绘图速成

前言

matplotlib.pyplot是matplotlib中最常用的子库之一,它主要用来绘制二维的数据图。

本文中会涉及到一些numpy的相关知识,如果有不懂的地方大家可以看看我的这篇文章快速了解:Numpy库快速入门;没有讲到的,本文会进行说明。

折线图

我们先来学习折线图的画法:

import matplotlib.pyplot as plt
plt.plot([1,2,3,4,5],[2,5,3,4,7])
plt.show()

首先要知道,plot(x,y)的功能是把一对对的x y所代表的坐标点显示出来。

  • 第一个列表是x的五个取值,第二个列表是对应于y的五个取值
    plt.plot([1,2,3,4,5],[2,5,3,4,7])
    

请添加图片描述
我们可以进行一些优化:

  • 使用title方法给图像起个名字——“坐标系”;
    plt.title('坐标系')
    
  • 使用xlable给横轴起名,使用ylable给纵轴起名。
    plt.xlabel("时间(s)")
    plt.ylabel("位移(m)")
    

如果中文或者负号显示是乱码,那么需要加上下面这两行代码:

这里设置默认字体为黑体

plt.rcParams['font.sans-serif']=['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号

将上述代码整合:

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
plt.plot([1,2,3,4,5],[2,5,3,4,7])
plt.title('坐标系')
plt.xlabel("时间(s)")
plt.ylabel("位移(m)")
plt.show()

请添加图片描述

离散数据“连续化”

上面是离散数据的画法,如果想画出连续函数的图表,我们需要加入numpy

import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(-1,1,50)
y=3*x+1
print(x)
print(y)
  • np.linspace的含义是从-1~1平均分成50个区间得到50个x的值,

    x=np.linspace(-1,1,50)
    
  • 再代入一次函数 y = 3 x + 1 y=3x+1 y=3x+1从而得到相应的50个y的值

    y=3*x+1
    
  • 通过print(x)、print(y)查看x和y的值。

      	[-1.         -0.95918367 -0.91836735 -0.87755102 -0.83673469 -0.79591837
       -0.75510204 -0.71428571 -0.67346939 -0.63265306 -0.59183673 -0.55102041
       -0.51020408 -0.46938776 -0.42857143 -0.3877551  -0.34693878 -0.30612245
       -0.26530612 -0.2244898  -0.18367347 -0.14285714 -0.10204082 -0.06122449
       -0.02040816  0.02040816  0.06122449  0.10204082  0.14285714  0.18367347
        0.2244898   0.26530612  0.30612245  0.34693878  0.3877551   0.42857143
        0.46938776  0.51020408  0.55102041  0.59183673  0.63265306  0.67346939
        0.71428571  0.75510204  0.79591837  0.83673469  0.87755102  0.91836735
        0.95918367  1.        ]
      [-2.         -1.87755102 -1.75510204 -1.63265306 -1.51020408 -1.3877551
       -1.26530612 -1.14285714 -1.02040816 -0.89795918 -0.7755102  -0.65306122
       -0.53061224 -0.40816327 -0.28571429 -0.16326531 -0.04081633  0.08163265
        0.20408163  0.32653061  0.44897959  0.57142857  0.69387755  0.81632653
        0.93877551  1.06122449  1.18367347  1.30612245  1.42857143  1.55102041
        1.67346939  1.79591837  1.91836735  2.04081633  2.16326531  2.28571429
        2.40816327  2.53061224  2.65306122  2.7755102   2.89795918  3.02040816
        3.14285714  3.26530612  3.3877551   3.51020408  3.63265306  3.75510204
        3.87755102  4.        ]
    

一次函数和二次函数

import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(-1,1,50)
y=3*x+1
plt.plot(x,y)
plt.show()

在这里插入图片描述

通过一次函数表达式我们能绘制出一次函数图像,而绘制二次函数图像只要替换刚才的函数表达式即可得到。

import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(-1,1,50)
y=3*x*x-2*x+1
plt.plot(x,y)
plt.show()

这是二次函数的曲线图,虽然看上去是连续的线,但是其中的(x,y)是一个个离散的坐标点,x的取值密集一点,看起来就会非常的连贯和平滑,最后使用show来展示。

在这里插入图片描述

多函数的绘制

接下来我们尝试把两个函数画在一张图表中,我们只要在plot的时候分别调用两个函数:

import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(-1,1,50)
y1=2*x-1
y2=2*x*x-x-1
plt.plot(x,y1)
plt.plot(x,y2)

在这里插入图片描述

我们可以加入两组参数:

  • plt.figure中的两个参数,num=1表示figure的序号,figsize=(8,5)设置figure图的大小:8英寸*5英寸;

    plt.figure(num=1,figsize=(8,5))
    
  • color=‘red’是设置线的颜色,linewidth=1.0设置线的宽度,linestyle=’–'设置线的样式为虚线

    - 实线 \quad - - 虚线 \quad -. 点划线 \quad : 点线

    plt.plot(x,y2,color="red",linewidth=1.0,linestyle='--')
    
import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(-1,1,50)
y1=2*x-1
y2=2*x*x-x-1
plt.figure(num=1,figsize=(8,5))
plt.plot(x,y1)
plt.plot(x,y2,color="red",linewidth=1.0,linestyle='--')

在这里插入图片描述

我们还可以加入更多的内容:

  • xlim和ylim分别设置x轴和y轴的取值范围;

    plt.xlim(-2,4) # x的取值范围
    plt.ylim(0,8) # y的取值范围
    

    如果出现报错:TypeError: ‘tuple’ object is not callable,可以参考这篇文章:关于利用matplotlib画图的时候出现的’tuple’ object is not callable?问题

  • xlable和ylable用来设置x轴和y轴的标签并显示在图中;

    plt.xlabel("x坐标轴") # x坐标的名称
    plt.ylabel("y坐标轴") # y坐标的名称
    
  • xticks可以设置x轴刻度的位置的标签和值,其中第一个列表参数用来表示x轴的特殊值,第二个列表参数表示其对应的具体的标签内容。

    plt.xticks([-1,0,1,2,3],['$First$','$Second$','$Third$','$Fourth$','$Fifth$'])
    

    大家可以看到,第二个列表中每个字符串的前后都添加了 $ 符号,表示matplotlib的这些字符串会使用其内置的Latex排版引擎来绘制数学公式。

    关于Latex中数学公式的排版,大家可以自行学习,也可以关注我有时间的话我会出关于Latex排版的教程或文章。

import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
x=np.linspace(-3,3,50)
y1=3*x+1
y2=3*x*x-2*x+1
plt.figure(num=1,figsize=(8,5))
plt.plot(x,y1)
plt.plot(x,y2,color="red",linewidth=1.0,linestyle='--')
plt.xlim(-2,6) # x的取值范围
plt.ylim(-1,8) # y的取值范围
plt.xlabel("x坐标轴") # x坐标的名称
plt.ylabel("y坐标轴") # y坐标的名称
plt.xticks([1,2,3,4,5],['$First$','$Second$','$Third$','$Fourth$','$Fifth$'])
plt.show()

在这里插入图片描述

接下来给figure加上图例,即legend

  • 先在figure中添加lable的内容,是两个函数的Latex数学公式;

    plt.plot(x,y1,label='$y=3x+1$')
    plt.plot(x,y2,color="red",linewidth=1.0,linestyle='--',label='$y=3x^2-2x+1$')
    
  • loc属性是图例的位置locate,本例使用的是best,它会帮助我们选择一个合适的空位置来放置图例;

    loc属性:best、upper right、upper left、lower left、lower right、right、center left、center right、lower center、upper center、center。

    关于legend的其它用法可以参考这篇文章:matplotlib-legend 位置属性 loc 使用

    plt.legend(loc="best")
    
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
x=np.linspace(-3,3,50)
y1=3*x+1
y2=3*x*x-2*x+1
plt.figure(num='一',figsize=(8,5))
plt.plot(x,y1,label='$y=3x+1$')
plt.plot(x,y2,color="red",linewidth=1.0,linestyle='--',label='$y=3x^2-2x+1$')
plt.xlim(-2,6) # x的取值范围
plt.ylim(-1,8) # y的取值范围
plt.xlabel("x坐标轴") # x坐标的名称
plt.ylabel("y坐标轴") # y坐标的名称
plt.xticks([1,2,3,4,5],['$First$','$Second$','$Third$','$Fourth$','$Fifth$'])
plt.legend(loc="best")
plt.show()

在这里插入图片描述

复杂函数图像的绘制

接下来我们来尝试绘制复杂函数的图像,这里以函数 y = cos ⁡ 3 { 2 π [ 1 − ( x − 1 ) 2 ] } y=\cos^3\{2\pi[1-(x-1)^2]\} y=cos3{2π[1(x1)2]}为例。

  • 首先,设置x的取值从0~6平均划分出100个间隔相同的值;

    x=np.linspace(0,6,100)
    
  • 设置y的计算公式;

    y=np.cos(2*np.pi*(1-(x-1)**2))**3
    
  • 设置图的大小:8英寸*8英寸;

    y=np.cos(2*np.pi*(1-(x-1)**2))**3
    
  • 设置线的样式及标签;

    plt.plot(x,y,color ='red',linewidth=3,label='$y=\cos^3\{2\pi[1-(x-1)^2]\}$')
    
  • 设置图例,loc属性默认为best。

    plt.legend()
    
import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(0,6,100)
y=np.cos(2*np.pi*(1-(x-1)**2))**3
plt.figure(figsize=(8,8))
plt.plot(x,y,color ='red',linewidth=3,label='$y=\cos^3\{2\pi[1-(x-1)^2]\}$')
plt.legend()
plt.show()

在这里插入图片描述

我们继续来优化这张图:

  • axis是用来设置数据轴的取值范围,作用与xlim、ylim相同;-1和7是x轴的取值,-1.2和1.2是y轴的取值;
    plt.axis([-1,7,-1.2,1.2])
    

下面我们将设置一个积分区域的绘制:

  • ix=(x>0.5) & (x<1.5)设置变量ix的取值范围,这是要单独设置积分区域背景在x轴上的取值范围;

    ix=(x>0) & (x<2)
    
  • fill_between用来设置其覆盖的颜色,x和y表示覆盖的数轴,0表示函数图像与y=0这条直线围成覆盖区域,where条件就是覆盖区域的取值范围,这里代入了ix;

  • facecolor='grey’表示覆盖区的颜色是灰色;

  • alpha为覆盖区的透明度范围[0,1],其值越大,表示越不透明。

    plt.fill_between(x,y,0,where=ix,facecolor='grey',alpha=0.2)
    
  • 接下来的plt.text用来绘制这个积分公式 ∫ a b f ( x ) d x \int_a^b f(x)\mathrm{d}x abf(x)dx

  • 0.5*(0+2),0.1则是放置积分公式的行列坐标的位置;

  • 第三个参数用来显示Latex公式的积分格式;

  • horizontalalignment是水平对齐方式,现在是center,即中置。

    plt.text(0.5*(0+2),0.1,'$\int_a^b f(x)\mathrm{d}x$',horizontalalignment='center')
    
import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(0,6,100)
y=np.cos(2*np.pi*(1-(x-1)**2))**3
plt.figure(figsize=(8,8))
plt.plot(x,y,color ='r',linewidth=3,label='$y=\cos^3\{2\pi[1-(x-1)^2]\}$')
plt.axis([-1,7,-1.2,1.2])
ix=(x>0) & (x<2)
plt.fill_between(x,y,0,where=ix,facecolor='grey',alpha=0.2)
plt.text(0.5*(0+2),0.1,'$\int_a^b f(x)\mathrm{d}x$',horizontalalignment='center')
plt.legend()
plt.show()

在这里插入图片描述

散点图

上面绘制的那些图只是matplotlib中的一种折线图,接下来我们来画一个散点图。

  • 首先,为了让我们的图片上的散点分布的更为随机,我们使用random.normal来随机生成均值为0、标准差为1的500个随机数;normal表示生成符合高斯分布,也就是正态分布概率密度的随机数;
    x=np.random.normal(0,1,500) # 生成高斯分布的概率密度随机数
    y=np.random.normal(0,1,500)
    
  • 由于生成的随机数中会含有负数,所以我们还要加上下面这行代码便于正常显示负号;
    plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
    
  • t=np.arctan2(y,x)是对 y x \frac yx xy求反正切;这行代码主要是使得散点的颜色的取值更多,颜色更为丰富,可以尝试把c=t 换成c=x或者c=y来看看效果;

    注:np.arctan2()不同于np.arctan(),具体解释可以看看这两篇文章:Numpy中arctan和arctan2的区别np.arctan,或者看看NumPy库的官方文档:numpy.arctan2

    t=np.arctan2(y,x)
    
  • 这一句是画散点图的关键的一句,x和y分别指定横轴和纵轴;
  • s指定散点的大小;
  • c指定散点的颜色,即从色系图片中取出值为t值的颜色;
  • alpha指定散点的透明度;
  • cmap 即colormap 指定色系图谱。

    cmap可以指定的色系图谱还有:Greys、Purples、Blues、Greens、Oranges、Reds等,更多内容可以查看Matplotlib库官方文档:Colormap reference

    plt.scatter(x,y,s=70,c=t,alpha=0.5,cmap='rainbow')
    
import matplotlib.pyplot as plt 
import numpy as np
x=np.random.normal(0,1,500) # 生成高斯分布的概率密度随机数
y=np.random.normal(0,1,500)
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
t=np.arctan2(y,x) 
plt.scatter(x,y,s=70,c=t,alpha=0.5,cmap='rainbow')
plt.show()

在这里插入图片描述

柱状图

接下来我们尝试绘制柱状图。

  • x的取值是0~9;
    x=np.arange(10)
    
  • y1和y2都是取的100~1000范围内的整数,共10组数;
    y1=np.random.randint(100,1000,size=10)
    y2=np.random.randint(100,1000,size=10)
    
  • tick_lable是用来给横轴坐标标识数据名称;
    tick_label=['A','B','C','D','E','F','G','H','I','J']
    
  • 这一句放置了x轴的ticks标签,代入了上面的tick_label;
    plt.xticks(x+bar_width/2,tick_label)
    
  • barwidth用来设置柱状图里的每个柱子的宽度;
    bar_width=0.35
    
  • 这两句是用来绘制两组数据,第二组数据为了和第一组数据并排,x的位置向后调整了x+barwidth的宽度;
    plt.bar(x,y1,bar_width,color='red',align='center',label='数据y1',alpha=0.5)
    plt.bar(x+bar_width,y2,bar_width,color='blue',align='center',label='数据y2',alpha=0.5)
    
  • 这句循环是给红色的数据柱加上标签值, ha即horizontalalignment,表示水平对齐方式,这里指定center;va即verticalalignment垂直对齐方式,这里指定bottom;
    for x_value,y1_value in zip(x,y1):
        plt.text(x_value,y1_value+0.05,y1_value,ha='center',va='bottom')
    
  • 这句循环是给蓝色的数据柱加上标签值,同样地,x_value+bar_width是为了让标签值与数据柱在同一竖直线上。
    for x_value,y2_value in zip(x,y2):
    	plt.text(x_value+bar_width,y2_value+0.05,y2_value,ha='center',va='bottom')
    
import matplotlib.pyplot as plt 
import numpy as np
plt.rcParams['font.sans-serif']=['SimHei'] 
x=np.arange(10)
y1=np.random.randint(100,1000,size=10)
y2=np.random.randint(100,1000,size=10)
tick_label=['A','B','C','D','E','F','G','H','I','J']
plt.xticks(x+bar_width/2,tick_label)
bar_width=0.35
plt.bar(x,y1,bar_width,color='red',align='center',label='数据y1',alpha=0.5)
plt.bar(x+bar_width,y2,bar_width,color='blue',align='center',label='数据y2',alpha=0.5)
plt.legend()
for x_value,y1_value in zip(x,y1):
    plt.text(x_value,y1_value+0.05,y1_value,ha='center',va='bottom')
for x_value,y2_value in zip(x,y2):
    plt.text(x_value+bar_width,y2_value+0.05,y2_value,ha='center',va='bottom')
plt.show()

在这里插入图片描述

三维图

最后我们尝试绘制一个三维图。

  • 首先需要引入三维图的绘图包mpl_toolkits.mplot3d,它是matplotlib里专门用来画三维图的工具包;
    import matplotlib.pyplot as plt 
    import numpy as np
    from mpl_toolkits.mplot3d import Axes3D 
    
  • 设置正常显示负号;
    plt.rcParams['axes.unicode_minus'] =False 
    
  • 这两句的作用是定义一个三维的figure窗口ax;
    fig=plt.figure() 
    ax = plt.axes(projection='3d')
    
  • 已知变量x y,x和y的取值是-4~4之间的连续点;
    x=np.arange(-4,4,0.25)
    y=np.arange(-4,4,0.25) 
    
  • 使用np.meshgrid把每一个x和y生成网格点坐标矩阵,即将给定的x轴和y轴上所有的点放到x和y这两个数组里进行迪卡尔乘积,从而得到所有的点,简而言之就是将x和y数组转换为网格状的二维数组,这是为了在3D图形中创建一个平面网格
    x,y=np.meshgrid(x,y) 
    
  • 函数是 z = x 2 + y 2 z=x^2+y^2 z=x2+y2
    z=x*x+y*y
    
  • plot_surface用来绘制三维图,rstride=1设置x向的条纹间隔为1个x向的间隔即0.25,cstride=1设置y向的条纹间隔为1个y向的间隔即0.25;将横向和纵向条纹间隔设为3,能明显看出两者的差异。
    ax.plot_surface(x,y,z,rstride=1,cstride=1,cmap="PuBu")
    # ax.plot_surface(x,y,z,rstride=3,cstride=3,cmap="PuBu")
    
import matplotlib.pyplot as plt 
import numpy as np
from mpl_toolkits.mplot3d import Axes3D 
plt.rcParams['axes.unicode_minus'] =False 
fig=plt.figure() 
ax = plt.axes(projection='3d')
x=np.arange(-4,4,0.25)
y=np.arange(-4,4,0.25) 
x,y=np.meshgrid(x,y) 
z=x*x+y*y
ax.plot_surface(x,y,z,rstride=1,cstride=1,cmap="PuBu")
# ax.plot_surface(x,y,z,rstride=3,cstride=3,cmap="PuBu")
  • 横向和纵向条纹间隔设为1时:
    在这里插入图片描述
  • 横向和纵向条纹间隔设为3时:
    在这里插入图片描述
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Corone

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值