天天看點

MATLAB使用surf、contour3靈活繪制投影圖、等高線圖,顯示在指定高度平面

    目标:在設定的高度平面上顯示等高線。

    實作如下圖所示的效果,在指定的高度(-40)上顯示三維曲面和等高線的投影。

MATLAB使用surf、contour3靈活繪制投影圖、等高線圖,顯示在指定高度平面

    遇到的問題:

    1.使用surfc函數,自帶的投影等高線總是繪制在高度資料的最小高度平面上。并不能随使用者指定繪制。如下圖,等高線投影總是顯示在(-25)的高度平面上。

MATLAB使用surf、contour3靈活繪制投影圖、等高線圖,顯示在指定高度平面

    2.在hold on的情況下,使用contour函數,得到的等高線圖總是繪制在高度為0的高度平面上。如下圖所示。

MATLAB使用surf、contour3靈活繪制投影圖、等高線圖,顯示在指定高度平面

    3.考慮contour(ax,...)函數,但是由于能力有限,總是找不到怎麼去建構這樣的句柄。也考慮了使用從H = surf()或者[c,h] = contour3()中擷取的句柄,但是系統總是報錯,說句柄的類型不對。總之,目前沒有找到方法建構這樣的句柄,或許通過修改原有的空間坐标系可以實作吧,也或許很麻煩。(如果有大佬知道了,懇求高擡貴手,救救我這個菜鳥的智商。)

    最後,通過分析高度矩陣,幹脆自己繪制等高線得了。使用函數plot3(x,y,z)(在某一個平面繪制圖線)實作了靈活繪制等高線的需求。當然,對于繪制彩色的投影圖,就沒有這麼複雜了,是以這裡簡述。

    具體解決方案如下。

    解決方案:

    1.使用surf(X,Y,Z,C)繪制彩色投影圖,實作如下圖的效果

MATLAB使用surf、contour3靈活繪制投影圖、等高線圖,顯示在指定高度平面

    文檔說明: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)靈活繪制等高線,實作最終效果

MATLAB使用surf、contour3靈活繪制投影圖、等高線圖,顯示在指定高度平面

    首先,繪制三維圖上的等高線。

    比較簡單,直接使用現有的函數。

    contour3(X,Y,Z,n)  n代表的等高線的條數

    contour3(X,Y,Z,v)   v = [k k] 代表限定要顯示的高度範圍,比如本例隻顯示(-10)高度,是以使用v = [-10,-10]。

    實作下圖效果

MATLAB使用surf、contour3靈活繪制投影圖、等高線圖,顯示在指定高度平面

     另外一個方面,如果需要美化,按照需求定制圖像顯示的模式和内容,也就是設定其他屬性,比如标注、線條、文字、顔色等等,那麼可以參照開發文檔,繪圖時候使用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,并繪制等高線)要寫得具有通用性才行,算法很簡單,分分鐘就能寫出來。或者直接看我的代碼,也很容易了解。

[~,c_list] = size(c);
cc = [];  %記錄每一次出現後的列數
cishu = 0; %遇到LEVEL的次數
for ii = 1:c_list
   if(c(1,ii) == -10 )   %設定尋找标志資料的條件,也可以設定為小于0,條件是通過觀察資料得到的
       cishu = cishu + 1;       
       cc(cishu) = ii;
   end
end
cc(cishu+1) = c_list+1;
for ii = 1:cishu
    Xdata = c(1,cc(ii)+1:cc(ii+1)-1);
    Ydata = c(2,cc(ii)+1:cc(ii+1)-1);
    Zdata = Xdata*0-40;   %設定等高線投影繪制的位置
    plot3(Xdata,Ydata,Zdata,'-k','LineWidth',2);  %利用資料繪制投影線
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下載下傳資源中搜尋本文章的名字即可找到)。

繼續閱讀