layout: post title: 三维光谱数据绘图 categories:
网上经常有人问起做三维光谱数据图的问题, 这个问题说难不难, 但是需要了解一些做三维图的基础知识. 知道了这些基础知识, 无论用matlab做, 还是用origin做, 都可以.
以一个三维光谱数据绘图为例吧. 一般保存的文件有三列, 如下面这样的
300.000000 0.100000 0.809010
300.000000 0.200000 0.663000
300.000000 0.300000 0.701000
300.000000 0.400000 0.677000
300.000000 0.500000 0.858000
300.000000 0.600000 0.799000
301.000000 0.100000 0.832660
301.000000 0.200000 0.672000
301.000000 0.300000 0.722000
301.000000 0.400000 0.782000
301.000000 0.500000 0.883000
301.000000 0.600000 0.939000
302.000000 0.100000 0.848650
302.000000 0.200000 0.685000
302.000000 0.300000 0.772000
302.000000 0.400000 0.826000
302.000000 0.500000 0.913000
302.000000 0.600000 0.952000
... ... ...
1098.000000 0.100000 0.060100
1098.000000 0.200000 -0.513000
1098.000000 0.300000 -0.458380
1098.000000 0.400000 -0.325000
1098.000000 0.500000 -0.362650
1098.000000 0.600000 -0.459000
1099.000000 0.100000 0.061880
1099.000000 0.200000 -0.514000
1099.000000 0.300000 -0.460040
1099.000000 0.400000 -0.326000
1099.000000 0.500000 -0.364410
1099.000000 0.600000 -0.462000
1100.000000 0.100000 0.062960
1100.000000 0.200000 -0.515000
1100.000000 0.300000 -0.460040
1100.000000 0.400000 -0.326000
1100.000000 0.500000 -0.365000
1100.000000 0.600000 -0.463000
第一列代表扫描波长, 300到1100, 第二列代表浓度, 0.1到0.6, 第三列代表吸收强度. 这三列的含义根据情况可以不同, 但作图时的方法都是一致的, 所以我们这里不考虑每列的具体含义, 假定第一列为x, 第二列为y, 第三列为z, 这样就存在一个函数z=f(x,y). 三维绘图就是做出f(x,y)的图形, 只不过这个f(x,y)是以离散形式给出的.
上面的示例数据中, x和y是按一定的格点给出的, 格点的分布是均匀的, 数据也没有缺失, 这种数据是最理想的, 作图也最简单. 有时候x和y的格点分布不均匀, 或是数据有缺失, 这种数据作图就要麻烦一些, 需要先进行非均匀插值, 然后才能作图. 我们这里只考虑简单情况.
直接利用这种数据格式绘图的matlab脚本如下
<pre class="line-numbers" data-start="0"><code class="language-bash"># Language: matlab clc; [x,y,z]=textread('Spctr3D.dat'); x=300:1:1100; y=0.1:0.1:0.6; [X, Y] = meshgrid(x, y); Z = reshape(z,size(X)); mesh(X,Y,Z) </code></pre>也可以先要把原始数据变成二维格点形式, 即按xy平面上个格点的形式重新排布数据, 排列后大概是这样子
Lambda 0.1 0.2 0.3 0.4 0.5 0.6
300 0.80901 0.663 0.701 0.677 0.858 0.799
301 0.83266 0.672 0.722 0.782 0.883 0.939
302 0.84865 0.685 0.772 0.826 0.913 0.952
303 0.85953 0.789 0.819 0.872 0.95 0.976
304 0.87135 0.792 0.877 0.965 0.985 0.992
305 0.89039 0.796 0.89 0.929 1.018 1.022
306 0.91988 0.798 0.911 1.012 1.034 1.047
... ... ... ... ... ... ...
1097 0.05794 -0.513 -0.45838 -0.325 -0.36147 -0.457
1098 0.0601 -0.513 -0.45838 -0.325 -0.36265 -0.459
1099 0.06188 -0.514 -0.46004 -0.326 -0.36441 -0.462
1100 0.06296 -0.515 -0.46004 -0.326 -0.365 -0.463
第一行给出x数据的含义和y的不同取值, 下面每行列出相应的z值.
有了整理好的数据之后, 就可以作三维图了. 利用origin可以直接导入整理后的数据, 再转换为矩阵直接作图. matlab则可利用下面的脚本
<pre class="line-numbers" data-start="0"><code class="language-bash"># Language: matlab clc; File = '3D.dat'; Data = load(File); [Nlambda, Nspctr] = size(Data); x = Data(2:end, 1); y = Data(1, 2:end); [X, Y] = meshgrid(x, y); Z = Data(2:end, 2:Nspctr)'; mesh(X,Y,Z); </code></pre>想要改变三维图的形式, 可参考MATLAB三维绘图命令基本XYZ立体绘图命令 或是一些matlab的教程.