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