SCILAB第二章 二維平面繪圖 撰文者: 1.中央大氣科學系 楊善文 2. (如對本文有貢獻者,記得在此留名)
繪圖前的準備工作 1.調配Scilab存取的記憶體與Swap空間。(因為繪圖這個 動作是很吃資源的。) 2.學習簡單的存取外部的資料檔。 3.rand()的使用。(rand是取隨機亂數,常被拿來作教學 範例使用。) 4.linspace()的使用。(要繪出一個圖,常需要宣告一個範 圍的變數值,這是常用的指令。) 5.size()指令的使用。(部分繪圖指令需要先宣告邊界大 小,故需先使用此指令) (筆者會先講以上的部分,之後才會進入正題。)
調配SCILAB需求的空間 SCILAB程式在啟動時,會預先對硬碟磁區的Swap區抓 取一定量的空間。如果使用者要載入非常龐大的資料量 來繪圖的話,很可能會造成超過啟動時所得到的空間, 因而產生錯誤訊息:記憶體空間不足而不能繪圖。 修改預設存取空間方法:在Scilab的安裝目錄(例如筆者 的是/usr/lib/scilab-4.0/)下,有個檔案:scilab.star 編輯此檔案,在此區域: // Set stack size ================================ 中的newstacksize='你想要的大小'
調配空間注意事項 當完成編輯後,存檔離開,重新啟動Scilab即可。 注意:執行這個動作要非常小心!不要一口氣貪心想調 得非常的大。因為這個空間是一啟動Scilab時就會取下 這樣的大小,不論你的Scilab是否已經在工作。所以取 太大可能會超過系統的Swap空間大小! 各個作業系統對超過記憶體資源負荷的反應不一定相同 ,例如筆者的Solaris系統遇到這種情況是在Scilab還沒 啟動完畢,系統就直接kill掉這支程式。至於其他系統是 否會有意料之外的情形,例如程式掛掉甚至系統整個當 機,這筆者不敢保証會發生什麼事。 所以建議調到適當大小即可。
存取外部的資料檔 在scilab下存取一個普通的資料檔指令是read/write。 存取Binary形式的資料檔指令是load/save。 (注意:這部分跟Matlab不一樣了。) read()的用法是:read('資料檔名(絕對或相對路徑 )',A,B); A與B是要抓取多大範圍的資料來載入矩陣,如果選擇的 範圍超過資料檔大小,則Scilab預設會抓取資料檔的下 一批資料來補齊,如果選擇的範圍超過資料檔內容的數 量(例如資料檔xxx是3x4的資料,使用者下了: read('xxx',7,8);卻取7x8的範圍),則會顯示錯誤訊息。
資料檔的尋找 如果資料檔不在預設的目錄下,可以使用Scilab內預設的指令 (此指令與UNIX下的系統指令類似。) pwd指令:察看目前所在目錄。 cd指令:切換目錄,可以是絕對與相對路徑。例如: --> cd .. <===切換到上一層目錄 --> cd /usr/local/bin <==切換到/usr/local/的bin/目錄下(絕 對路徑)。 ls指令:察看該目錄下有哪些檔案。 mkdir/rmdir [目錄名]:製造/刪除 目錄。 以上指令,如果你是一個UNIX/Linux使用者,或許會覺得很 熟悉。但是如果你是Windows或是其他非UNIX類OS的使用 者,筆者就建議你要多多練習這部分的操作了。
read/write 1 假設有一個資料檔檔名:data,檔案內包含了以下資料: 14 27 36 12 22 13.36 14.13 7 14 27 36 12 22 13.36 14.13 7 15 13.12 6.893 27 17.1 15.2 7.85 24 讀取它並存進一個矩陣的語法如下: --> A=read('data',4,4); --> A Ans = 當將資料讀入矩陣後,就可以開始使用這些資料了。
read/write 2 想將Scilab上已經處理完的矩陣資料,可以使用write()指 令輸出存檔。 --> write('data2',B); <==把b的資料存成data2 這時你就可以在目前的目錄下找到data2這個檔案,利用 vi等編輯器開啟它,就會發現資料已經在裡面了。 讀檔的小秘訣:如果資料量非常龐大,你不確定要載入 多大的矩陣才能完全載入,可以使用vi編輯器,開檔時 會有顯示行數,或者在終端機上使用'wc -l 資料檔名'也 是個辦法。
save/load 這是存取Binary形式的資料,在做資料處理時會比較少用到 。 儲存的例子:save('data3',B); <==使用之前的B矩陣 這時如果你用vi等編輯器開啟data3檔案,就會發現裡面是亂 碼。 讀取它:load('data3'); --> B <==因為之前是存B,故load時你只能用B來讀出它 Ans = 1. 2. 3. 4. 5. 6. 7. 8. 9. (save指令在儲存時,除了儲存資料外,也會將資料所屬的矩 陣名一併記下來。)
亂數產生指令rand() 使用rand()指令可以產生一個-1到1之間的亂數矩陣。 語法rand(A,B); <==產生一個AxB的亂數矩陣 例子:--> Z=rand(2,2) Z = - 0.2207715 0.4621729 - 0.2972244 - 0.8631775
取變數的區域範圍:linspace() 用法:變數=linspace(下界,上界,等份點數); 在繪圖時,自變數X常是以此方式宣告,而應變數Y就會 隨著X的變化而變動。 例子:t=linspace(0,2*%pi,300); <==0到2π取300個等 份點。 例子2:x=linspace(1,10); <=在1到10之間取100點
size指令的使用 size()指令可以用來判斷矩陣的大小。 例子: --> A=[1 2 3 4;5 6 7 8;9 10 11 12] A = 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. --> size(A) Ans = 3. 4. (學會了這些之後,就可以進入正題了。)
基本二維繪圖plot plot指令可以用來繪製一般的曲線圖。 範例(對sin函數繪圖): --> t=linspace(0,2*%pi); <==取0到2π的範圍 --> y=sin(t); --> plot(y);
範例2(任意函數): --> x=linspace(0,40,300); <==0到40之間取300個點 --> y=3*x^2-4*cos(x)-exp(x); --> plot(y); (plot(y)也可以寫成plot(x,y),如果你希望將x,y軸對調,可以 寫成plot(y,x)。) 注意:plot(y)跟plot(x,y)仍然還是有差別。當寫成plot(y)時,x 座標軸是以y有多少筆資料來決定,例如之前的x雖然是0到40 ,但是切了300等分。故plot(y)時,x軸是0到300。但是 plot(x,y)時,x軸就是以0到40來顯示了。
將X,Y軸對調後(plot(y,x))
多重曲線繪圖的方式 例子: --> x=-2:0.01:2; <==這是linspace外的另一種定義變數方 式 ,從-2到2,間距0.01。 --> y1=sin(x); --> y2=exp(x); --> y3=sin(x)+cos(x); --> X=[x;x;x]; --> Y=[y1,y2,y3]; --> plot(X',Y'); <==也可以用plot2d()指令,用法差不多。
另一種在同張圖上繪製多條曲線方式 由於Scilab在繪圖時,若同時多次下達繪圖指令,且不 指定要新增繪圖視窗時,預設會讓圖形疊在同一張圖中 。而不會每下一次繪圖指令,圖就刷新一次。除非繪完 一張圖,就關一次繪圖視窗。 例如:plot(y1);plot(y2);plot(y3); 這時就可以在同張圖中,同時看到y1,y2,y3曲線了。 (這種方式的優點是,你可以比較容易為每條曲線做不同 的處理,而不會互相影響到(簡單明暸)。筆者在繪製多 重曲線圖時,反而比較常使用這種方式。)
修改圖形的線標(Marker) 在plot()指令中宣告曲線y之後的欄位,可以加上'線標樣 式'的參數,例如:'.' , '+' , 'x' , 'o'.......... 如果要調整線標大小,可以加上:'marksize',大小數值 例如: --> plot(x,y,'.','marksize',1); <==打點圖,點大小1 如果要條整線標的顏色,可以加上參數:'color',[R G B] R,G,B的範圍是0到1,例如紅色:[1 0 0],綠色:[0 1 0] ,藍色:[0 0 1]。我們可以從[ ]之中三個值用0到1之間 的數字來混出其他色彩,例如:[0.7 0.5 0.2]
例子: --> t=linspace(0,2*%pi,50); --> y=sin(t); --> plot(t,y,'.','marksize',4,'color',[1 0 0]); --> plot(t,y+1,'+','marksize',4,'color',[0.7 0.3 0]); --> plot(t,y+2,'x','marksize',4,'color',[0 0 1]); --> plot(t,y+3,'o','marksize',4,'color',[0.8 0.4 0.6]);
為圖片加上標示文字 在scilab下,在圖的座標軸旁與圖上方可以加上裝飾或 是注解的文字,是使用xtitle()指令。 用法:xtitle('標題','x軸注解','y軸注解'); 例如: --> t=linspace(0,2*%pi,50); --> y=sin(t); --> plot(t,y); --> xtitle('sin function','t','sin(t)');
為圖片加上網格線 讓圖表加上網格線,更可以輕易看出資料點的位置。加 入網格線的指令是:xgrid 通常xgrid()不需加入參數即可使用。 例子:將之前的sin函數圖加上網格線。 原來的語法之下再加入xgrid();即可。
離散資料打點圖 例如:有兩個資料檔A,B裡面的資料分別是: 資料A:3.3 4.2 11 13 5.6 8 --> x=read('A',1,6); --> y=read('B',1,6); <==分別將A,B資料存入矩陣 --> plot(x,y,'.'); 必須注意的是,在plot()中必須要加入'.'這個參數,如果 不加的話,Scilab會將這些點連起來。
向量場圖champ champ顧名思義,在法文中即是場之意。champ()指令 即是用來畫向量場(champ de vecteurs)。向量場常用於 大氣風場、流體流場等用途。 用法:champ(t1,t2,X,Y); t1:y方向(垂直方向)範圍 t2:x方向(水平方向)範圍 X:全域x方向的大小矩陣 Y:全域y方向的大小矩陣
向量場示意圖
champ使用範例 t1=1:4; t2=1:3; X=[1 1 1;1 1 1;1 1 1;1 1 1]; Y=[0 1 1;1 2 1;1 1 1;1 1 1]; champ(t1,t2,X,Y);