分享

MATLAB使用surf、contour3灵活绘制投影图、等高线图,显示在指定高度平面

 Tall_Tree 2021-11-14

    目标:在设定的高度平面上显示等高线。

    实现如下图所示的效果,在指定的高度(-40)上显示三维曲面和等高线的投影。


    遇到的问题:

    1.使用surfc函数,自带的投影等高线总是绘制在高度数据的最小高度平面上。并不能随用户指定绘制。如下图,等高线投影总是显示在(-25)的高度平面上。


    2.在hold on的情况下,使用contour函数,得到的等高线图总是绘制在高度为0的高度平面上。如下图所示。


    3.考虑contour(ax,...)函数,但是由于能力有限,总是找不到怎么去构建这样的句柄。也考虑了使用从H = surf()或者[c,h] = contour3()中获取的句柄,但是系统总是报错,说句柄的类型不对。总之,目前没有找到方法构建这样的句柄,或许通过修改原有的空间坐标系可以实现吧,也或许很麻烦。(如果有大佬知道了,恳求高抬贵手,救救我这个菜鸟的智商。

    最后,通过分析高度矩阵,干脆自己绘制等高线得了。使用函数plot3(x,y,z)(在某一个平面绘制图线)实现了灵活绘制等高线的需求。当然,对于绘制彩色的投影图,就没有这么复杂了,所以这里简述。

    具体解决方案如下。

    解决方案:

    1.使用surf(X,Y,Z,C)绘制彩色投影图,实现如下图的效果


    文档说明:surf(X,Y,Z,C)uses C to define color. MATLAB performs a lineartransformation on this data to obtain colors from the current colormap.

    所以这个图很容易实现,只要将Z矩阵设置好就行,比如本例。surf(x,y,-40+0*z,z);将z置零,然后移动到(-40)的平面上,即可。   

    2.使用plot3(x,y,z)灵活绘制等高线,实现最终效果


    首先,绘制三维图上的等高线。

    比较简单,直接使用现有的函数。

    contour3(X,Y,Z,n)  n代表的等高线的条数

    contour3(X,Y,Z,v)   v = [k k] 代表限定要显示的高度范围,比如本例只显示(-10)高度,所以使用v = [-10,-10]。

    实现下图效果


     另外一个方面,如果需要美化,按照需求定制图像显示的模式和内容,也就是设置其他属性,比如标注、线条、文字、颜色等等,那么可以参照开发文档,绘图时候使用contour3(...,Name,Value),surf同理。

     当然,还是建议使用句柄来设置,这样更灵活,比如技术文档中写的:

        [C,h]= contour(x,y,z);

        clabel(C,h,'FontSize',15,'Color','red');

    甚至,使用t = clabel(C,h,'manual') returns the text objects created.进一步设置里面的属性。可以使图中的重要信息更加明显突出,提升图像建模质量。

     第二步,在(-40)高度面上绘制等高线

    本来参照surf(X,Y,Z,C),想着contour3(contour)也会有这样的函数接口,可以在指定的高度面绘制等高线。但是并没有。所以方案迅速夭折。经过百般查询,扔未解决,只好用最原始的方法,找数据、分析数据、绘制等高线。

    数据来源于[c,h]= contour3(x,y,z)中的c,具体格式可以参照开发文档。本文也拷贝过来一部分。

Contour Matrix

ContourMatrix — Contour line definitions[] (default) | two-row matrix

This property is readonly.

Contour line definitions,returned as a two-row matrix. Each contour line in the plot has an associateddefinition. If there are a total of N contour linesin the plot, then the contour matrix consists of N definitions:

C = [C(1) C(2)...C(k)...C(N)]

Each contour line definitionfollows this pattern:

C(k) = [level   x(1) x(2)...

        numxy   y(1) y(2)... ]

The firstentry, level, indicates the contour level wherethe contour line is drawn. Beneath the contour level is the number of (x,y)vertices that define the contour line. The remaining columns contain the datafor each of the vertices. If the first and last vertices are the same, then thecontour line is a closed loop. If a particular contour level has multiplecontour lines in the graph, then the matrix contains a separate definition foreach line.

Example

Create a contour plotof values from the peaks function.

[X,Y,Z] = peaks(3);

[C,h] = contour(X,Y,Z);

Access the contourmatrix using either the output argument C or the ContourMatrix property of the contour object (h.ContourMatrix). The contour matrix contains definitions for eachof the seven contour lines. The circles in this matrix show the beginnings ofthe contour line definitions.

The first definitionin the matrix indicates that there is a contour line drawn at the -0.2 level ,consisting of the three vertices (-0.5504,-3), (0,-2.89), and (0.5506,-3). Since the first andlast vertices are not the same, the contour line is not a closed loop. The lastdefinition indicates that there is a closed loop at the 0.8 level.

    文档写的很清晰,还有例子,所以我也就不解释了。主要是分析c中的数据,构造自己需要的[网格数据]和[高度数据](这两个概念是借鉴的,能更好体现MATLAB绘制三维图形算法的本质,所以在此引用),然后使用plot3(Xdata,Ydata,Zdata)绘制即可。当然,每一条线都要绘制一次,所以这个[解析数据]的函数(代码如下,解析高度矩阵c,并绘制等高线)要写得具有通用性才行,算法很简单,分分钟就能写出来。或者直接看我的代码,也很容易理解。

  1. [~,c_list] = size(c);
  2. cc = []; %记录每一次出现后的列数
  3. cishu = 0; %遇到LEVEL的次数
  4. for ii = 1:c_list
  5. if(c(1,ii) == -10 ) %设置寻找标志数据的条件,也可以设置为小于0,条件是通过观察数据得到的
  6. cishu = cishu + 1;
  7. cc(cishu) = ii;
  8. end
  9. end
  10. cc(cishu+1) = c_list+1;
  11. for ii = 1:cishu
  12. Xdata = c(1,cc(ii)+1:cc(ii+1)-1);
  13. Ydata = c(2,cc(ii)+1:cc(ii+1)-1);
  14. Zdata = Xdata*0-40; %设置等高线投影绘制的位置
  15. plot3(Xdata,Ydata,Zdata,'-k','LineWidth',2); %利用数据绘制投影线
  16. end

    另外,简单说几个感想。

    第一,网格数据,往往是两个一维向量,然后可以通过meshgrid()函数构建MATLAB需要的标准的网格数据的格式。只是构建的时候需要注意一些方面。文档有提到。

    SURF(x,y,Z) and SURF(x,y,Z,C), with twovector arguments replacingthe first two matrix arguments, must have length(x) =n and length(y) = m where [m,n] = size(Z). In this case, the vertices of thesurface patches are the triples (x(j), y(i), Z(i,j)). Note that x correspondsto the columns of Z and y corresponds to the rows.

    当然也可能是二维矩阵,这个方面就不介绍了,文档有详细说明。

    第二,三维数据中(x,y,z)中,往往x,y是自变量,z是因变量,当然,也有可能x是自变量,y,z都是因变量。初学者对这个还是要弄清楚的。 

    第三,上图比较粗糙,没有图例也没有坐标轴标识,等高线标识,时间有限,这些内容也很简单,所以略去了。

    大佬们就没必要阅读此文了,本文可以给有功底的菜鸟提供一个解决方案,具体编程很简单,所以就不把代码贴出来了。若是有人需要我的代码,下载也无妨(在csdn下载资源中搜索本文章的名字即可找到)。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多