【matlab】matlab使用排序和插值绘制四种不同的插值图像
在上关于matlab的课时，老师留了一道题目，题目内容如下：根据所给的数据文件input.mat，以变量x为自变量，y为因变量，分别使用四种插值方式求出自变量为X时因变量的值Y，把图形窗口分割为四个区域，在每个区域分别画出四种不同插值方式时，插值前后的数据曲线。这一道题目全班没有几个人做出来，但是我做出来了~ 于是我来分享一下我的经验~一、怎么求插值？先学习一下插值函数interp1，interp1的函数的语法如下：vq = interp1(x , y , xq , method)其中的x是原数据的X值（可以理解为横坐标的位置）；y是原数据的Y值（也是纵坐标的位置）；xq是你要插值的数据的X值；method是插值方式，可以省略。插值方式有很多，比如linear，nearest，next，previous，pchip，cubic，v5cubic，makima，spline等，如果省略就是默认值linear（线性插值）举个例子，我这里有一个从0到6的向量x，这个数字沿着y=sin(x)路径走……>> x = 0:1:6 x = 0 1 2 3 4 5 6 >> y = sin(x) y = 0 0.8415 0.9093 0.1411 -0.7568 -0.9589 -0.2794 >> 在图上显示是这样的……如果我想知道当使用线性插值时，x为0.5、2.5、4.5对应Y值。于是我可以这么的使用函数Y=interp(x,y,X)……>> X = [0.5,2.5,4.5] X = 0.5000 2.5000 4.5000 >> Y = interp1(x,y,X); >> Y Y = 0.4207 0.5252 -0.8579 >> 于是我就可以知道了当X为0.5、2.5、4.5时，线性插值Y就是0.4207、0.5252、-0.8579二、然后知道怎么排序首先我们先学习一个函数sort，这个函数是一个排序函数，可以按照要求将数字、文本进行升序或者降序排序~ sort的语法如下：[ B , I ] = sort( A )其中，A中填入的可以是矩阵，也可以是向量，因为我们做的题目是和插值相关的，所以用向量就足够了；B是将矩阵/向量A排序以后返回的结果；I是返回排序后的值在原来向量中的索引。我们举个例子，我先准备了一串向量A，向量A的值如下：A = [9,8,7,6,5,4,3,2,1,0];然后我们将向量A里面的数据升序排序，我可以这么使用函数：[B,I]=sort(A);之后我们使用matlab分别查看B和I的值……>> [B,I]=sort(A); >> B B = 0 1 2 3 4 5 6 7 8 9 >> I I = 10 9 8 7 6 5 4 3 2 1 >> 我们可以发现，B里面的值就是向量A升序排序以后的结果；我们再看I，I里面第一个数字10是什么呢？我们看看B里面的第一个数字0在向量A里面的索引……正好就是数字10！我们再看其他数字，排序过的数字的索引在原来的向量A里面都可以找到那个数字唉~ 于是我们就知道了，这个向量I里面的记的数字，正好就是对于原来的向量中数字的索引的位置！三、融合在一起我们先用我们第一部分的数据做个例子，我们目前有四个变量，分别是x,y,X,Y四个变量。>> x x = 0 1 2 3 4 5 6 >> y y = 0 0.8415 0.9093 0.1411 -0.7568 -0.9589 -0.2794 >> X X = 0.5000 2.5000 4.5000 >> Y Y = 0.4207 0.5252 -0.8579 >> 我们再看一看我们之前展示的一张图片……观察图片，我们发现X轴的数字从左往右看是从小到大排列的，我们正好就可以使用之前的sort函数来将原数据和插值数据重新从小到大排序~我们先要将原数据和插值数据放在一个向量里面，这个简单，我们可以这样……>> xlist = [x,X] xlist = 0 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 0.5000 2.5000 4.5000 >> 然后将这个向量进行排序……这样的话，我们X轴就排列好了~>> [xsort,I] = sort(xlist); >> xsort xsort = 0 0.5000 1.0000 2.0000 2.5000 3.0000 4.0000 4.5000 5.0000 6.0000 >> 然后我们再把原始数据y和插值数据Y合并创建一个向量ylist，我们可以这样：>> ylist = [y,Y]; >> ylist ylist = 0 0.8415 0.9093 0.1411 -0.7568 -0.9589 -0.2794 0.4207 0.5252 -0.8579 >> 我们可以对X轴采用升序排列，但是我们不能对Y轴同样按照这种方式排列啊！这样的话，重新排列以后就是一条递增的数了……但是我们不要忘了一个数列I，它可以保存排序过的数字在原来向量的索引，我们可以利用向量I来找到对应位置的数字在原向量中的位置，我们可以这样：>> I I = 1 8 2 3 9 4 5 10 6 7 >> ysort = ylist(I) ysort = 0 0.4207 0.8415 0.9093 0.5252 0.1411 -0.7568 -0.8579 -0.9589 -0.2794 >> 于是，我们的X和Y就成功的排列完成啦~ 鼓掌！！我们看一下使用插值以后的效果，蓝线是插值以前的数据，圆圈是插值以后的数据。因为线性插值的方式是取该点左右最近的点，取左右中间的点，所以圆圈在线上面……四、实践上手根据所给的数据文件input.mat，以变量x为自变量，y为因变量，分别使用四种插值方式求出自变量为X时因变量的值Y，把图形窗口分割为四个区域，在每个区域分别画出四种不同插值方式时，插值前后的数据曲线。我们先导入数据……假设我们把数据文件和matlab原文件放在一起，因为在一个文件夹里面，所以我们可以直接load进数据……load input.mat然后，我们把插值Y求出来Y = interp1(x,y,X,'linear');之后，将原始值和插值合并在一起……xlist = [x,X]; ylist = [y,Y];我们将X轴排序，将排序以后的值放入xsort[xsort,I]=sort(xlist);之后，将I用于Y的排序……ysort = ylist(I);到此，重点讲完了，我们就可以选择画图位置来画图了，我喜欢将排序前的数据打红虚线，排序后的数据变成蓝色的带有X符号的线……subplot(2,2,1) plot(xsort,ysort,'-bx',x,y,'-.r') title("使用linear模式绘图") legend("使用后","使用前");将上述内容总结在一起，我们就可以画出其中一种插值了……load input.mat %% 使用linear模式绘图 Y = interp1(x,y,X,'linear'); xlist = [x,X]; ylist = [y,Y]; [xsort,I]=sort(xlist); ysort = ylist(I); subplot(2,2,1) plot(xsort,ysort,'-bx',x,y,'-.r') title("使用linear模式绘图") legend("使用后","使用前");我们可以将插值到绘图的部分复制粘贴为四份，把interp1中间的变量'linear'改一下。我们就可以用四种模式来绘图了。load input.mat %% 使用linear模式绘图 Y = interp1(x,y,X,'linear'); xlist = [x,X]; ylist = [y,Y]; [xsort,I]=sort(xlist); ysort = ylist(I); subplot(2,2,1) plot(xsort,ysort,'-bx',x,y,'-.r') title("使用linear模式绘图") legend("使用后","使用前"); %% 使用next模式绘图 Y = interp1(x,y,X,'next'); xlist = [x,X]; ylist = [y,Y]; [xsort,I]=sort(xlist); ysort = ylist(I); subplot(2,2,2) plot(xsort,ysort,'-bx',x,y,'-.r') title("使用next模式绘图") legend("使用后","使用前"); %% 使用spline模式绘图 Y = interp1(x,y,X,'spline'); xlist = [x,X]; ylist = [y,Y]; [xsort,I]=sort(xlist); ysort = ylist(I); subplot(2,2,3) plot(xsort,ysort,'-bx',x,y,'-.r') title("使用spline模式绘图") legend("使用后","使用前"); %% 使用pchip模式绘图 Y = interp1(x,y,X,'pchip'); xlist = [x,X]; ylist = [y,Y]; [xsort,I]=sort(xlist); ysort = ylist(I); subplot(2,2,4) plot(xsort,ysort,'-bx',x,y,'-.r') title("使用pchip模式绘图") legend("使用后","使用前");结果如下：