Logo

郎哥编程

练手:绘制函数图像

2021-02-23 145

快速掌握Matplotlib的绘图技巧和使用方法,最便捷的方法就是在绘图练习中学习,下面是绘制函数图像的几个案例。

1、绘制指数函数

案例代码见课程资源(unit3\case03.py)

import matplotlib.pyplot as plt
import numpy as np
import math
 
# 定义绘图函数
def plotter(ax, data1, data2, param_dict):
    out = ax.plot(data1, data2, **param_dict)
    return out
 
# 定义指数函数
# x:指数 a:底数
def exponential_func(x, a):
  y=math.pow(a, x)
  return y
 
# 程序入口
if __name__ == '__main__':
 
    # 指数函数x数据
    x=np.linspace(-4, 4, 40)
    # 指数函数f(x)=1/3^值
    y=[exponential_func(x,1/3) for x in x]
    fig, ax = plt.subplots(1, 1)
    plotter(ax,x,y,{'color': 'red','label':'f(x) = 1/3^x'})
 
    # 指数函数f(x)=3^x值
    y=[exponential_func(x,3) for x in x]
    plotter(ax,x,y,{'color': 'blue','label':'f(x) = 3^x'})
 
     # 指数函数f(x)=e^x值
    y=[exponential_func(x,math.e) for x in x]
    plotter(ax,x,y,{'color': 'brown','label':'f(x) = e^x'})
 
    #设置图例显示位置
    plt.legend()
    plt.show()

代码解读

函数plotter()是通用绘图函数。参数ax是AxesSubplot对象,可以理解为基于Axes(轴空间)的子图;参数data1和data2为绘制的线条数据;参数param_dict为关键字参数,用于设置线条的绘制样式。

函数exponential_func()调用math库的pow函数计算指数函数值。

06.png

2、  绘制三角函数

案例代码见课程资源(unit3\case04.py)

#导入numpy库
import numpy as np
#导入绘图工具库
import matplotlib.pyplot as plt
# np的linspace函数在指定的间隔范围内返回均匀间隔的一组数值
# 例如:np.linspace(start,end,n=50),在start- end,均匀的返回n个数值
# 定义了一个numpy的数组x,从-2π到2π,共200个值
x=np.linspace(-2*np.pi,2*np.pi,200,endpoint=True)
#对x进行cos计算
cos= np.cos(x)
#设置cos图像的线条颜色、线条粗细和图像标签标签
plt.plot(x,cos,color='red',linewidth=1.5,label='cos')
#对x进行sin计算
sin= np.sin(x)
#设置sin图像的线条颜色、线条粗细和图像标签标签
plt.plot(x,sin,color='blue',lw=2.5,label='sin')
#设置图例显示位置
plt.legend(loc='lower left')
 
#设定x轴范围
plt.xlim(-2*np.pi*1.1,2*np.pi*1.1)
#设定y轴范围
plt.ylim(cos.min()*1.1,cos.max()*1.1)
 
#设置X轴刻度值
plt.xticks(
    [-2*np.pi,-3*np.pi/2,-np.pi,-np.pi/2,0,np.pi/2,np.pi,3*np.pi/2,2*np.pi],
    [r'-$2\pi$',r'-$3\pi/2$',r'-$\pi$',r'-$\pi/2$','0',r'$\pi/2$',r'$\pi$',r'-$3\pi/2$',r'$2\pi$']
        )
 
#设置Y轴刻度值
plt.yticks([-1,0,1])
#通过plt.gca()获取坐标轴对象 然后设置属性
ax=plt.gca()
#隐藏top和right周
ax.spines['top'].set_color("none")
ax.spines['right'].set_color("none")
#把左下设置为0点
ax.spines['left'].set_position(('data',0))
ax.spines['bottom'].set_position(('data',0))
plt.show()

代码解读

程序首先调用Numpy库的linspace()函数,创建绘制三角函数图像需要的数据,即三角函数变量x的取值范围。linspace()函数在指定的间隔范围内返回均匀间隔的一组数值,x的取值范围为-2π到+2π范围,在该范围内均匀取200个数值。

np.cos(x)返回x取不同值时cos的函数值,返回一个存储cos函数值的列表对象。

matplotlib库pyplot模块的plot()函数使用给出的数据在坐标轴上绘制曲线,参数x和cos是要绘制的数据点,color是曲线的颜色,lw是曲线的宽度,label是标识曲线的标签。

pyplot模块的legend()函数设置图例的位置,当需要在一个坐标轴上绘制多条曲线时,显示图例是不错的绘图方法。

pyplot模块的xlim()函数设置坐标轴的取值范围,X轴的取值范围为-2π、-3π/2、π、-π/2、0,π/2、π、3π/2、2π。Y轴的取值范围为cos列表元素的最小值和cos列表元素的最大值,即1和-1。

pyplot模块的xticks()函数设置X轴刻度的显示样式,若不设置显示样式,matplotlib会把X轴刻度显示为数值,这里希望显示为弧度。“-$\pi$”为laText排版系统的语法,在python中使用laText,需要在文本的前后加上$符号,pi是π,matplotlib会自动解析laText内容并排版输出。

最后调用pyplot模块的gca()函数获取轴对象,隐藏top和right轴,matplotlib在绘图时默认会有4个轴,两个横轴和两个竖轴。

07.png

3、  绘制参数动态变化的图像

中国古代数学家刘徽在求圆周率时用到割圆术,用来计算圆的周长,当内接正多边形的面积与圆的面积非常相近时,内接正多边形的周长就可以表示圆的周长,这个方法也称为割圆术。割圆术是用圆内接正多边形的面积去无限逼近圆面积,并以此求圆周长的方法。

一幅图胜过千言万语,要理解割圆术与极限思想,可以编写一个Python程序,来动态展示圆内接正多边形边数不断增大时,内接正多边形的面积逼近圆面积的过程。

案例代码见课程资源(unit3\case05.py)

import numpy as np
import matplotlib.pyplot as plt
# 导入matplotlib库的交互组件
from matplotlib.widgets import Slider,Button
# 绘制内接正多边形
# r:半径  sidenum:正多边形边数
def polygon(r,sidenum):
    # 0~360范围内均匀创建sidenum个数据点  
    data = np.linspace(0,2*np.pi,sidenum,False)
    # 计算边数为sidenum正多边形顶点x坐标
    x = r * np.sin(data)
    # 正多边形顶点首尾相连
    x = np.append(x,x[0])
    # 计算边数为sidenum正多边形顶点y坐标
    y = r * np.cos(data)
    # 正多边形顶点首尾相连
    y = np.append(y,y[0])
    return (x,y)
 
# 绘制正多边形的外接圆
def circle(r):
    # 0~360范围内均匀创建200个数据点
    data = np.linspace(0, 2 * np.pi, 200)
    # 计算圆周点x坐标
    x =  r * np.cos(data)
    # 计算圆周点y坐标
    y =  r * np.sin(data)
    return (x,y)
 
 
# 程序入口
if __name__ == '__main__':
 
    # 调整绘图区域,让底部容纳Slider组件
    plt.subplots_adjust(bottom=0.25)
    # 获取正多边边形数据
    # r:20  sidenum:6
    x,y = polygon(20,6)
    # 绘制正多边形
    # plot函数返回存储Line2D绘图实例对象的列表
    figure, = plt.plot(x,y,color='blue',linewidth=1.5,label='polygon')
    # 获取正多边形外接圆数据
    # r:20
    x1,y1 = circle(20)
    # 绘制正多边形外接圆
    plt.plot(x1,y1,color='r',linestyle='-')
    plt.plot(x1,-y1,color='r',linestyle='-')
    # 绘制圆心
    plt.scatter(0,0,c='r',marker='o')
    # 调整坐标轴,使坐标轴各轴数据单位相同
    plt.axis("equal")
    # 设置Slider组件绘图区域
    s_area = plt.axes([0.1,0.1,0.75,0.03])
    # 创建Slider组件
    slider_control = Slider(s_area,'slider',0,30,6)
 
    # 定义更新绘图函数
    def update(var):
        # 获取slider_control的当前数值  
        num = int(slider_control.val)
        # 获取正多边形数据
        x,y = polygon(20,num)
        # 设置Line2D绘图实例对象的数据
        figure.set_data(x,y)
        # 按照设置的数据绘制正多边形
        plt.draw()
    # 绑定Slider组件on_changed事件
    slider_control.on_changed(update)
    plt.show()

圆内接正多边形为6条边的效果图。圆内接正多边形的面积和圆的面积还是有很大差距的。

08.png

圆内接正多边形为12条边的效果图。观察图像可以发现,内接正多边形的面积离圆的面积愈来愈近了。

09.png

圆内接正多边形为24条边的效果图。内接正多边形的面积几乎和圆的面积重合了。

10.png

圆内接正多边形为48条边的效果图。仔细观察图像,还稍微能看出正多边形的痕迹,在这种情况下,内接正多边形的面积已经非常逼近圆的面积了。

11.png

圆内接正多边形为96条边的效果图,几乎看不到内接正多边形的痕迹了。

12.png

从割圆术可以理解极限思想,极限是一个动态逼近的过程,从内接正六边形到内接正九十六边形,再到内接正n边形,内接正多边形的面积随着边数的不断增大,会愈来愈近似于圆的面积,在经过无限增大过程后,多边形就会变换为圆,多边形面积便转化为圆面积。

代码在线纠错(通义千问 qwen-max)

支持粘贴多个代码文件,提交后由阿里云通义千问自动分析代码漏洞、语法错误、逻辑问题并给出修改建议。
您已解锁 AI 代码纠错功能,可正常使用!

评论区

登录 后发表评论
暂无评论