yanshw

SciPy - 插值

插值方法很多,本文只是总结下 scipy 库中插值用法

 

一维插值 - 拉格朗日插值

import numpy as np
from scipy import interpolate
import matplotlib.pylab as plt
import pylab as mpl

mpl.rcParams[\'font.sans-serif\'] = [\'FangSong\']   # 指定默认字体
mpl.rcParams[\'axes.unicode_minus\'] = False      # 解决保存图像是负号\'-\'显示为方块的问题

##################################### 一维数据插值 拉格朗日插值
x = np.linspace(0, 2*np.pi+np.pi/4, 10)
y = np.sin(x)
f_linear = interpolate.lagrange(x, y)           # 拉格朗日插值

x_new = np.linspace(0, 2*np.pi+np.pi/4, 100)

plt.plot(x, y, "o",  label=u"原始数据")
plt.plot(x_new, f_linear(x_new), label=u"拉格朗日插值")

plt.xlabel(u\'安培/A\')
plt.ylabel(u\'伏特/V\')
plt.legend()
plt.show()

输出

 

一维插值 - B样条插值

并且与 线性插值 做了对比

x = np.linspace(0, 2*np.pi+np.pi/4, 10)
y = np.sin(x)
f_linear = interpolate.interp1d(x, y)           # 线性插值
tck = interpolate.splrep(x, y)                  # B-spline插值

x_new = np.linspace(0, 2*np.pi+np.pi/4, 100)
y_bspline = interpolate.splev(x_new, tck)

plt.plot(x, y, "o",  label=u"原始数据")
plt.plot(x_new, f_linear(x_new), label=u"线性插值")
plt.plot(x_new, y_bspline, label=u"B-spline插值")

plt.xlabel(u\'安培/A\')
plt.ylabel(u\'伏特/V\')
plt.legend()
plt.show()

输出

 

一维插值 - 其他插值汇总

由于用法一样,这里统一记录

x = np.linspace(0, 10, 11)
y = np.sin(x)

plt.figure(figsize=(12,9))
plt.plot(x, y, \'ro\')

#建立插值数据点
xnew = np.linspace(0, 10, 101)
for kind in ["nearest","zero","slinear","quadratic","cubic","linear"]:#插值方式
    #"nearest","zero"为阶梯插值
    #slinear 线性插值
    #"quadratic","cubic" 为2阶、3阶B样条曲线插值
    f = interpolate.interp1d(x, y, kind = kind)
    ynew = f(xnew)#计算插值结果
    plt.plot(xnew, ynew, label = str(kind))

plt.xticks(fontsize=20)
plt.yticks(fontsize=20)
plt.legend(loc = \'lower right\')
plt.show()

输出

 

 

二维插值 - 样条插值

这里只是拿 样条 做个 demo,其他类型的插值 类似

def func(x, y):
    return (x+y)*np.exp(-5.0*(x**2 + y**2))

# X-Y轴分为15*15的网格
y, x = np.mgrid[-1:1:15j, -1:1:15j]
fvals = func(x,y) # 计算每个网格点上的函数值  15*15的值
print(len(fvals[0]))

# 三次样条二维插值
newfunc = interpolate.interp2d(x, y, fvals, kind=\'cubic\')       # x y z

# 计算100*100的网格上的插值
xnew = np.linspace(-1,1,100)#x
ynew = np.linspace(-1,1,100)#y
fnew = newfunc(xnew, ynew)#仅仅是y值   100*100的值

##### 绘图
# 为了更明显地比较插值前后的区别,使用关键字参数interpolation=\'nearest\'
# 关闭 imshow()内置的插值运算
plt.subplot(121)
im1 = plt.imshow(fvals, extent=[-1,1,-1,1], cmap=mpl.cm.hot, interpolation=\'nearest\', origin="lower") # pl.cm.jet
# extent=[-1,1,-1,1]为x,y范围
plt.colorbar(im1)

plt.subplot(122)
im2 = plt.imshow(fnew, extent=[-1,1,-1,1], cmap=mpl.cm.hot, interpolation=\'nearest\', origin="lower")
plt.colorbar(im2)

plt.show()

输出

 

二维插值 - 三维展示

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.cm as cm

def func(x, y):
    return (x+y)*np.exp(-5.0*(x**2 + y**2))

# X-Y轴分为20*20的网格
x = np.linspace(-1, 1, 20)
y = np.linspace(-1,1,20)
x, y = np.meshgrid(x, y) # 20*20的网格数据
fvals = func(x,y) # 计算每个网格点上的函数值  15*15的值

fig = plt.figure(figsize=(9, 6))
ax = plt.subplot(1, 2, 1,projection = \'3d\')
surf = ax.plot_surface(x, y, fvals, rstride=2, cstride=2, cmap=cm.coolwarm,linewidth=0.5, antialiased=True)
ax.set_xlabel(\'x\')
ax.set_ylabel(\'y\')
ax.set_zlabel(\'f(x, y)\')
plt.colorbar(surf, shrink=0.5, aspect=5)# 标注

##### 二维插值
newfunc = interpolate.interp2d(x, y, fvals, kind=\'cubic\')   # newfunc为一个函数

# 计算100*100的网格上的插值
xnew = np.linspace(-1,1,100)#x
ynew = np.linspace(-1,1,100)#y
fnew = newfunc(xnew, ynew)#仅仅是y值   100*100的值  np.shape(fnew) is 100*100
xnew, ynew = np.meshgrid(xnew, ynew)

ax2 = plt.subplot(1, 2, 2,projection = \'3d\')
surf2 = ax2.plot_surface(xnew, ynew, fnew, rstride=2, cstride=2, cmap=cm.coolwarm,linewidth=0.5, antialiased=True)
ax2.set_xlabel(\'xnew\')
ax2.set_ylabel(\'ynew\')
ax2.set_zlabel(\'fnew(x, y)\')
plt.colorbar(surf2, shrink=0.5, aspect=5)#标注

plt.show()

输出

 

 

参考资料:

https://www.cnblogs.com/xiuercui/p/12292563.html

发表于 2020-04-13 14:08  努力的孔子  阅读(686)  评论(0编辑  收藏  举报
 

分类:

技术点:

相关文章: