本实训围绕实际应用场景中的数组计算与曲线绘制的需求展开,旨在培养学生学习和掌握如何更高效的处理数值序列(用数组array替代列表list,并通过向量化操作数组),以及如何绘制函数曲线(使用 Python 中的 matplotlib 模块)
任务描述
本关任务:请编写代码完成sin函数曲线绘制。完成图应如下图所示:
相关知识
课程视频《数组计算与曲线绘制 - 绘制Sin函数》
绘图模块 matplotlib
所谓“一图胜千言”,很多时候都需要通过可视化的方式查看、分析数据。Python 中有很多可视化工具,其中最著名的当属 matplotlib 绘图模块。matplotlib 的 pyplot 子模块,提供了和 Matlab 类似的绘图 API,方便用户快速绘制二维图表,导入方式如下:
#第一种:导入调用函数需要加 plt 前缀
import matplotlib.pyplot as plt
#第二种:直接导入 pyplot 下的所有函数
from matplotlib.pyplot import *
pyplot 下常用的绘制函数如下所示:
采用plot函数绘制折线图;
采用subplot函数绘制多幅图表;
采用imshow函数展示图片;
采用hist函数绘制直方图;
采用pie绘制饼图;
采用legend绘制图例;
其他的函数可参见官方文档,具体函数的调用方式、参数配置也可参见该文档。
plot函数
plot函数可用于绘制线条,调用方式如下:
#单条线:
plot([x], y, [fmt], data=None, **kwargs)
#多条线一起画
plot([x], y, [fmt], [x2], y2, [fmt2], …, **kwargs)
参数x和y表示具体坐标点,可以是序列数据或是标量。可选参数[fmt]是一个字符串用于定义图的基本属性,如:颜色( color ),点型( marker ),线型( linestyle ),具体形式为:fmt = ‘[color][marker][line]’,fmt接收的是每个属性的单个字母缩写,例如:
plot(x, y) # 默认配置
plot(x, y, ‘.’) # 绘制点状标记
plot(x, y, ‘bo-’) # 绘制蓝色圆点实线
plot(x, y, ‘g–’) # 绘制绿色虚线
更详细的参数设置可参见官方文档
编程要求
已知坐标数据:
x = [0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330, 360]
y= [0, 0.5, 0.866, 1, 0.866, 0.5, 0, -0.5, -0.866, -1, -0.866, -0.5, 0]
请你绘制sin函数曲线,图的marker 类型采用点状标记。
提示:只需绘制图像,并将图像保存为文件,不用展示图像(show()),程序会进行验证。
测试说明
平台将运行用户补全的代码文件,并将存储的 picture/step0/fig0.png 图像与标准答案图像比较,然后判断用户编写代码是否正确。
若画图正确,测试集将输出:祝贺!图片与预期输出一致;
否则,测试集将输出:图片与预期输出不一致,请继续努力!。
开始你的任务吧,祝你成功!
# 请绘制sin函数曲线
import matplotlib
matplotlib.use("Agg") # 设置平台绘图环境,勿删
import matplotlib.pyplot as plt
# 请在此添加代码实现函数细节 #
# ********** Begin *********#
x = [0,30,60,90,120,150,180,210,240,270,300,330,360]
y = [0,0.5,0.866,1,0.866,0.5,0,-0.5,-0.866,-1,-0.866,-0.5,0]
plt.plot(x,y,'.')
plt.show()
# ********** End **********#
plt.savefig('picture/step0/fig0.png') #存储输出图像,勿删
任务描述
本关任务:请编写代码完成抛物线函数曲线绘制。完成图如下图所示:
相关知识
课程视频《数组计算与曲线绘制 - 绘制任意曲线》
为了完成本关任务,你还需要掌握savefig函数。
savefig函数
pyplot 中的savefig()函数可用于存储输出的图像,调用方式如下:
savefig(fname, dpi=None, facecolor=‘w’, edgecolor=‘w’,
orientation=‘portrait’, papertype=None, format=None,
transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=None, metadata=None)
最简单的调用方式是plt.savefig(fname),即以默认配置存储图像,图像名字为fname。存储sin(x)正弦曲线图的代码示例如下:
import matplotlib.pyplot as plt #导入matplotlib库
from math import sin, radians #导入数学计算库
x = range(0, 361) #创建 0-360 的整数列表
y = [sin(radians(e)) for e in x] #获得 x 对应的正弦值,以列表存储
plt.plot(x, y) #plot函数绘制曲线
plt.savefig(‘sin.png’) #将图像存储至sin.png中
存储的sin.png如下图所示:
更详细的参数设置可参见 官方文档。
编程要求
请你绘制抛物线函数曲线,x的区间为 [0,50] ,间隔为 1 ,抛物线公式如下:
y=3x
2
+2x+1
请用函数f(x)封装函数细节,然后绘制曲线(线段类型为红色虚线),最后存储输出图像(图像存储名为 picture/step1/fig1.png )。
测试说明
平台将运行用户补全的代码文件,并将存储的 picture/step1/fig1.png 图像与标准答案图像比较,然后判断用户编写代码是否正确。
若画图正确,测试集将输出:祝贺!图片与预期输出一致;
否则,测试集将输出:图片与预期输出不一致,请继续努力!。
开始你的任务吧,祝你成功!
# 请绘制抛物线曲线
import matplotlib
matplotlib.use("Agg")
def f(x):
# 请在此添加代码实现函数细节 #
# ********** Begin1 *********#
x = list(range(0,51,1))
y = []
for i in range(0,len(x)):
y.append(3*(v[i]**2) + 2*(v[i]) + 1)
return y
# ********** End1 **********#
# 请在此添加代码绘制曲线并存储图像#
# ********** Begin2 *********#
import matplotlib.pyplot as plt
x = list(range(0,51,1))
y = []
for i in range(0,len(x)):
y.append(3*(x[i]**2) + 2*(x[i]) + 1)
plt.plot(x,y,'r--')
plt.show()
plt.savefig('picture/step1/fig1.png')
# ********** End2 **********#
任务描述
本关任务:请编写代码完成函数曲线绘制,要求采用数组存储序列,并对曲线上的点坐标进行向量计算。完成图如下图所示:
相关知识
为了完成本关任务,你需要掌握:
数组的基本概念;
数组计算;
向量化。
数组的基本概念
在数学概念里,一个向量是一个 n 元组:
v=(v 0 ,…,v n−1 )
数组可以看做是向量的一般形式,可以有多个维度,如下图所示:
A 是一个二维数组,而向量是一维数组。
数组和列表的主要差别如下:
列表可以包含任意类型的对象,一个数组只能包含同一类型的对象;
当成员是整数、浮点数或复数时,使用数组会更加高效。
数组计算
Python 中的数组运算主要依赖 numpy 模块,它包括ndarray多维数组对象以及一些数组处理函数。
创建数组最简单的方法就是使用array函数,它接收一切序列型的对象(包括其他数组),然后产生一个新的含有传入数据的numpy数组,示例如下:
import numpy as np
ndarray1 = np.array([1, 2, 3, 4])
除了np.array外,还有一些函数也可以新建数组,常用函数如下表所示,具体的参数配置可参见官方文档。
函数 功能
arange() 类似于 Python 内置的 range 函数,但返回值是一个 ndarray 而不是列表
linspace() 返回在指定区间均匀间隔的数组,常用于创建等差数列
zeros() 根据指定形状创建一个全 0 数组
zeros_like() 根据传入数组的形状创建一个全 0 数组
ones() 根据指定形状创建一个全 1 数组
ones_like() 根据传入数组的形状创建一个全 1 数组
示例如下:
ndarray2 = np.zeros((3, 3)) #产生33的数值为 0 的二维数组
ndarray3 = np.ones_like(ndarray2) # 按照 ndarray2 的形状创建数值为 1 的 33 数组
ndarray4 = np.arange(10) #产生 0-9 共 10 个元素
ndarray5 = np.arange(10, 20, 2) #产生数组 array([10, 12, 14, 16, 18]), 间隔为2
ndarray6 = np.linspace(2.0, 3.0, num=5) # 产生数组 array([ 2. , 2.25, 2.5 , 2.75, 3. ])
常用的作用于数值x的函数f(x)一般对数组也有效,numpy 包含许多数组处理函数,且运算速度非常快。
数学操作:包括add(), subst\fract(),multiply(),divide(), exp()等等;
三角函数:包括sin(),cos(),tan()等等;
比较函数:包括greater(),greater_equal(),less(),less_equal()等等;
…
向量化
向量化指的是将需要循环才能操作数组的 Python 函数转化为直接操作整个数组的函数。向量化能够使得程序更短、可读性更好,且程序的运行速度更快。
在上一关卡中的抛物线函数绘制,通过向量化可变换如下:
import numpy as np
import matplotlib.pyplot as plt
def f(x):
result = 3 * x ** 2 + 2 * x + 1
return result
x = np.linspace(0, 51, 51)
y = f(x)
plt.plot(x, y, ‘r–’)
plt.savefig(‘fig.png’)
编程要求
请你绘制函数曲线,具体公式如下:
y=t 2e −t 2
具体要求如下:
以数组形式存储数据,t是个等差数列的一维数组,区间为 [0,3] ,样本数为 50 ;
使用数组计算得到y;
绘制曲线的线段类型为默认设置;
需存储输出图像,图像名字为 picture/step2/fig2.png 。
提示: numpy 包中有求e的函数可以调用。
测试说明
平台将运行用户补全的代码文件,并将存储的 picture/step2/fig2.png 图像与标准答案图像比较,然后判断用户编写代码是否正确。
若画图正确,测试集将输出:祝贺!图片与预期输出一致;
否则,测试集将输出:图片与预期输出不一致,请继续努力!。
开始你的任务吧,祝你成功!
# 请绘制函数曲线
import matplotlib
matplotlib.use("Agg")
# 请在此添加实现代码 #
# ********** Begin *********#
import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(0,3,50)
y = t**2*np.exp(-t**2)
plt.plot(t,y)
plt.show()
plt.savefig('picture/step2/fig2.png')
# ********** End **********#
任务描述
本关任务:请编写代码在同一坐标系中绘制两条曲线,并设置图例、坐标参数等装饰。完成图如下图所示:
相关知识
课程视频《数组计算与函数绘制 - 曲线绘制的其他内容》
为了完成本关任务,你需要掌握:
设置图例;
设置坐标轴及标题;
绘制多条曲线。
设置图例
在 matplotlib 中,可通过legend函数设置图例,调用方式如下:
legend() #以默认形式设置图例
legend(labels) #标记已有的绘图
legend(handles, labels) #明确定义图例中的元素
代码示例如下:
#标记已有的绘图
plt.plot([1, 2, 3])
plt.legend([‘A simple line’])
plt.show()
#明确定义图例中的元素
line1, = plt.plot([1,2,3], linestyle=’–’)
line2, = plt.plot([3,2,1], linewidth=4)
plt.legend([line1,line2], [“Line 1”,“Line 2”])
plt.show()
可通过loc参数设置图例位置,通过fontsize设置字体大小,通过title参数设置图例标题,详细的参数配置可参见官方文档。
设置坐标轴及标题
在使用 matplotlib 模块画坐标图时,往往需要对坐标轴设置很多参数,这些参数包括横纵坐标轴范围、坐标轴刻度大小、坐标轴名称等等,在 matplotlib 中包含了很多函数,用来对这些参数进行设置。
plt.xlim、plt.ylim用于设置横纵坐标轴范围;
plt.xlabel、plt.ylabel用于设置坐标轴名称;
plt.xticks、plt.yticks用于设置坐标轴刻度;
plt.title用于设置图像标题。
上面的plt表示 matplotlib.pyplot 模块,即在程序中以import matplotlib.pyplot as plt方式导入 matplotlib.pyplot 模块。
绘制多条曲线
绘制多条曲线有两种情况:
第一种是在同一坐标系上绘制多条曲线,能够清楚地看到多条曲线的对比情况。可通过直接叠加使用plot进行绘制。
示例如下:
import matplotlib.pyplot as plt
from math import sin, cos, radians
x = range(0, 360)
y1 = [sin(radians(e)) for e in x]
y2 = [cos(radians(e)) for e in x]
plt.plot(x, y1, ‘b-’)
plt.plot(x, y2, ‘r–’)
plt.legend([‘sin(x)’, ‘cos(x)’], loc=‘upper center’)
plt.xlabel(‘x’) #设置 x 轴文字标记
plt.ylabel(‘sin/cos’) #设置 y 轴文字标记
plt.axis([0, 360, -1.0, 1.0]) #设置坐标范围
plt.show()
上述代码展示图像如下所示:
第二种是在不同子图上画图,多用于呈现不同内容的曲线。需要用到subplot函数,它主要用于创建子图,具体调用方式可参见官方文档。
示例如下:
import numpy as np
import matplotlib.pyplot as plt
x1 = np.linspace(0.0, 5.0)
x2 = np.linspace(0.0, 2.0)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
y2 = np.cos(2 * np.pi * x2)
plt.subplot(2, 1, 1) # 开始绘制子图 1
plt.plot(x1, y1, ‘o-’)
plt.title(‘A tale of 2 subplots’)
plt.ylabel(‘Damped oscillation’)
plt.subplot(2, 1, 2) # 开始绘制子图 2
plt.plot(x2, y2, ‘.-’)
plt.xlabel(‘time (s)’)
plt.ylabel(‘Undamped’)
plt.show()
上述代码展示图像如下所示:
编程要求
请你在同一坐标系中绘制两条函数曲线,具体公式如下:
y1=t
2
e
−t
2
y2=t
4
e
−t
2
具体要求如下:
以数组形式存储数据,定义域t是个等差数列的一维数组,区间为 [0,3] ,样本数为 50 ;
使用数组计算得出y;
y1的线段类型为红色虚线,y2的线段类型为蓝色圆点实线;
添加x轴(标签为’t’)、y轴(标签为’y’)标记,设置图像标题为’Plotting two curves in the same plot’;
添加图例,标记分别为’y1’和’y2’,其余参数以默认形式;
需存储输出图像,图像名字为 picture/step3/fig3.png ;
测试说明
平台将运行用户补全的代码文件,并将存储的 picture/step3/fig3.png 图像与标准答案图像比较,然后判断用户编写代码是否正确。
若画图正确,测试集将输出:祝贺!图片与预期输出一致;
否则,测试集将输出:图片与预期输出不一致,请继续努力!。
开始你的任务吧,祝你成功!
#请在同一坐标系中绘制两条曲线
import matplotlib
matplotlib.use("Agg")
# 请在此添加实现代码 #
# ********** Begin *********#
import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(0,3,50)
y1 = t**2*np.exp(-t**2)
y2 = t**4*np.exp(-t**2)
plt.plot(t,y1,'r--')
plt.plot(t,y2,'b-o')
plt.title('Plotting two curves in the same plot')
plt.xlabel('t')
plt.ylabel('y')
plt.legend(['y1','y2'])
plt.savefig('picture/step3/fig3.png')
# ********** End **********#
任务描述
本关任务:编程实现向量化函数,并绘制函数曲线。完成图如下图所示:
相关知识
为了完成本关任务,你需要掌握向量化函数的相关知识。
向量化函数
向量化函数,即将需要循环才能操作数组的 Python 函数转化为直接操作整个数组的函数。具体包括以下三种向量化方法,以向量化阶跃函数为例。
阶跃函数常用于工程和科学领域,公式如下:
H(x)={
0,
1,
x<0
x≥0
Python 实现代码如下:
def H(x):
return (0 if x < 0 else 1)
上述代码只能处理数值型数据,处理数组时会报ValueError错误,向量化函数能够解决该问题。
def H1(x):
r = np.zeros(len(x)) # or r = x.copy()
for i in range(len(x)):
r[i] = H(x[i])
return r
2. 使用自动向量化vectorize函数
H2 = np.vectorize(H)
3. 使用where替换if检测
def H3(x):
return np.where(x<0, 0.0, 1.0)
将if语句替换为where的语法形式如下所示:
def f(x):
if condition:
x =
else:
x =
return x
def f_vectorized(x):
x1 =
x2 =
r = np.where(condition, x1, x2)
return r
使用以上任意一种方法都可以完整的绘制出阶跃函数曲线,完整代码示例如下:
import numpy as np
import matplotlib.pyplot as plt
def H3(x):
return np.where(x<0, 0.0, 1.0)
x = np.linspace(-10, 10, 100) # few points (simple curve)
y = H3(x)
plt.plot(x, y)
plt.show()
输出图像如下所示:
编程要求
请编写代码实现向量化函数并绘制函数曲线,函数公式如下:
具体编程要求如下:
采取任一种向量化方法实现函数;
x的区间为 [-3,5] ,样本数为 1000 ;
绘制的线段类型为蓝色实线;
设置图像标题为’Plotting hat func in this plot’;
存储输出图像,图像名字为 picture/step4/fig4.png 。
测试说明
平台将运行用户补全的代码文件,并将存储的 picture/step4/fig4.png 图像与标准答案图像比较,然后判断用户编写代码是否正确。
若画图正确,测试集将输出:祝贺!图片与预期输出一致;
否则,测试集将输出:图片与预期输出不一致,请继续努力!。
开始你的任务吧,祝你成功!
# 请编写代码实现向量化帽函数并绘制函数曲线
import matplotlib
matplotlib.use("Agg")
# 请在此添加实现代码 #
# ********** Begin *********#
import numpy as np
import matplotlib.pyplot as plt
def H3(x):
return np.where(x<0,0,(np.where(x<1,x,(np.where(x<2,2-x,0)))))
x = np.linspace(-3,5,1000)
y = H3(x)
plt.title('Plotting hat func in this plot')
plt.plot(x,y,'b-')
plt.show()
plt.savefig('picture/step4/fig4.png')
# ********** End **********#