zoukankan      html  css  js  c++  java
  • 【Matlab】离散点绘制三维曲面方法小结

    任务

    用给定的离散点绘制三维曲面,例如给下列数据:

    % x y z
    1 2 3
    1 5 2
    2 3 4
    3 8 5
    ...

    分析

    1.数据不是等间隔的格网数据

    在这种情况下无法直接使用meshsurf等函数,因为这些函数要求的数据格式为格网形式,每个点是等间隔的,就像这样:

    grid

    实际情况确不是这样(实际无规则,可以在后面的图中看到),所以需要插值生成格网数据。

    2.生成格网数据

    既然原始数据不规则,那么就想办法让它规则,举个例子,原始数据是这样的:

    notgrid

    格网化的目的就是使网格节点上有数据(插值生成的蓝色点,不对边界进行插值,画图的时候红色的点就不要了):

    isgrid

    实战

    大概查看

    可以先用plot3scatter看看离散的点:

    % 清理命令和变量,以免内存不够
    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:

    plot3

    scatter:

    scatter

    插值绘图

    原始数据为三列,分别为x,y,z。要想画三维曲面图就需要matlab认识的格网数据。所以,要先进行插值。先用meshgrid结合minmax函数产生网格坐标(这样就是原来的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:

    3d

    flat:

    flat

    小结

    1.格网化的目的:产生规则化的数据,matlab才能识别、作图。所以问题是:matlab有没有这样的函数:直接读取不规则的数据,自动生成网格数据、作图,而不需要用户来做这些事?我没有找到。。。

    2.用plot3scatter可以看离散的点。

    3.插值绘图:meshgrid:生成格网,griddata:插值,surf:绘图。

    4.色标的问题:由于数据中存在一些有问题的点,比如特别大和特别小,图本来应该是有起伏变化的,就是因为这些点,整个图看上去非常平坦,所以有两种做法:

    1)改色标。随手百度了一个可以在图画出来以后改,参考:matlab如何自定义colorbar。至于如何用代码或者cpt文件之类的方法还没有去搜过。

    2)去除有问题的点。

    2017/8/27注

    进一步参考:matlab插值小记,对插值有一个更好的理解。

  • 相关阅读:
    div标签的闭合检查
    jquery easyui 显示和关闭数据加载的遮罩
    codeforces 446A DZY Loves Sequences
    android高速开发框架xUtils
    Android-spinner
    遗传算法优化策略
    面向对象的勾勾画画
    Android studio 解决setText中文乱码问题
    CAS—改动默认登录页
    android 使用post 提交
  • 原文地址:https://www.cnblogs.com/shanchuan/p/8150279.html
Copyright © 2011-2022 走看看