用给定的离散点绘制三维曲面,例如给下列数据:
% x y z
1 2 3
1 5 2
2 3 4
3 8 5
...
1.数据不是等间隔的格网数据
在这种情况下无法直接使用mesh
、surf
等函数,因为这些函数要求的数据格式为格网形式,每个点是等间隔的,就像这样:
实际情况确不是这样(实际无规则,可以在后面的图中看到),所以需要插值生成格网数据。
2.生成格网数据
既然原始数据不规则,那么就想办法让它规则,举个例子,原始数据是这样的:
格网化的目的就是使网格节点上有数据(插值生成的蓝色点,不对边界进行插值,画图的时候红色的点就不要了):
可以先用plot3
和scatter
看看离散的点:
% 清理命令和变量,以免内存不够
clc;clear;
% 读数据
% 数据格式:x,y,z
data = load('hv_re.txt');
x1 = data(:, 1);
y1 = data(:, 2);
z1 = data(:, 3);
% 抽稀,以免内存不够
count = 1; % 新变量计数器
interval = 10000; % 抽稀间隔
for i = 1 : interval : length(x1)
x(count, 1) = x1(i, 1);
y(count, 1) = y1(i, 1);
z(count, 1) = z1(i, 1);
count = count + 1;
end
% plot3
figure;
plot3(x, y, z, '*');
view(0, 90); % 视角,从上往下看
% 散点图
figure;
scatter(x, y, 25, z, 'filled'); % 散点大小可调
colorbar;
plot3:
scatter:
原始数据为三列,分别为x,y,z。要想画三维曲面图就需要matlab认识的格网数据。所以,要先进行插值。先用meshgrid
结合min
、max
函数产生网格坐标(这样就是原来的x,y从最小值到最大值均匀间隔的点),再用griddata
函数对这些点上的Z值进行插值(因为这些点上不一定有数据,需要插值得到),最后用surf
画图(mesh、pcolor也可以)。参考 : Matlab 之meshgrid, interp, griddata 用法和实例(转)
% 清理命令和变量,以免内存不够
clc;clear;
% 读数据
% 数据格式:x,y,z
data = load('hv_re.txt');
x1 = data(:, 1);
y1 = data(:, 2);
z1 = data(:, 3);
% 抽稀,以免内存不够
count = 1; % 新变量计数器
interval = 1000; % 抽稀间隔
for i = 1 : interval : length(x1)
x(count, 1) = x1(i, 1);
y(count, 1) = y1(i, 1);
z(count, 1) = z1(i, 1);
count = count + 1;
end
%确定网格坐标(x和y方向的步长均取0.1)
[X,Y]=meshgrid(min(x):0.1:max(x),min(y):0.1:max(y));
%在网格点位置插值求Z,注意:不同的插值方法得到的曲线光滑度不同
Z=griddata(x,y,z,X,Y,'v4');
%绘制曲面
figure(1)
surf(X,Y,Z);
shading interp;
colormap(jet);
% view(0, 90);
colorbar;
print(gcf, '-djpeg', 'xyz.jpg'); % save picture
结果:
3d:
flat:
1.格网化的目的:产生规则化的数据,matlab才能识别、作图。所以问题是:matlab有没有这样的函数:直接读取不规则的数据,自动生成网格数据、作图,而不需要用户来做这些事?我没有找到。。。
2.用plot3
和scatter
可以看离散的点。
3.插值绘图:meshgrid
:生成格网,griddata
:插值,surf
:绘图。
4.色标的问题:由于数据中存在一些有问题的点,比如特别大和特别小,图本来应该是有起伏变化的,就是因为这些点,整个图看上去非常平坦,所以有两种做法:
1)改色标。随手百度了一个可以在图画出来以后改,参考:matlab如何自定义colorbar。至于如何用代码或者cpt文件之类的方法还没有去搜过。
2)去除有问题的点。
2017/8/27注
进一步参考:matlab插值小记,对插值有一个更好的理解。