NS2簡單又經典的入門教程


2010-07-10 22:06:04|  分類: NS2網絡仿真 |  標籤:ns2  ns  網絡仿真  gnuplot  |字號 訂閱

                                 awk和gnuplot對ns模擬之後.tr文件的處理實驗

1、實驗用網絡拓撲圖爲

這個網絡的環境包含了四個網絡節點(n0,n1,n2,n3)如下圖所示。網絡節點n0到節點n2之間,和節點n1到節點n2之間的網絡頻寬(bandwidth)是2Mbps,延遲時間(propagation delay)是10ms。網絡拓樸中的頻寬瓶頸是在節點n2到節點n3之間,頻寬爲1.7Mbps,延遲的時間爲20ms。每個網絡節都是採用DropTail queue的方式,且在節點n2到節點n3之間的最大隊列長度是10個封包的長度。在節點n0到n3之間會有一條FTP的連線,FTP應用程式是架架在TCP之上,所以在寫模擬環境的描述語言的時候,必需先建立一條TCP的連線,在來源端n0上使用TCP agent產生”tcp”來發送TCP的封包;在目的地端n3使用TCPsink agent產生”sink”來接受TCP的資料、並產生回覆封包(ACK)回傳送端、最後把接收的TCP封包釋放。最後要把這兩個agent連起來(connect),連線才能建立。若是沒有額外的參數設定,TCP封包的長度爲1Kbytes。在這裏順便補充說明一下,對於ns2模擬參數內定值設定是在ns-allinone-2.27\ns-2.27\tcl\lib目錄下的ns-default.tcl,有想要進一步瞭解的人,可以去查看此檔。另外,在節點n1到n3之間有一條固定的傳輸速率的連線(Constant Bit Rate,CBR),CBR應用程式是架架在UDP之上,因此必需在n1使用UDP agent來產生”udp”用來發送UDP封包,在n3上使用Null agent來產生”sink”以接收由n1傳送過來的UDP封包,然後把接收的封包釋放。CBR的傳送速度爲1Mbps,每一個封包大小爲1Kbytes。CBR是在0.1秒開始傳送,在4.5秒結束傳輸;FTP是在1.0秒開始傳送,4.0秒結束傳輸。

 

NS2簡單又經典的入門教程 - 星期八 - 星期八

 

2、程序源代碼
編輯一個四個結點的網絡源文件,保存名爲tool.tcl
# 產生一個模擬的物件
set ns [new Simulator]
#針對不同的資料流定義不同的顏色,這是要給NAM用的

$ns color 1 Blue
$ns color 2 Red

#開啓一個NAM trace file
set nf [open out.nam w]
$ns namtrace-all $nf

#開啓一個trace file,用來記錄封包傳送的過程
set nd [open out.tr w]
$ns trace-all $nd
#定義一個結束的程序
proc finish {} {
        global ns nf nd
        $ns flush-trace
        close $nf
        close $nd 
        #以背景執行的方式去執行NAM
        exec nam out.nam &
        exit 0
}

#產生四個網絡節點
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
set n3 [$ns node]

#把節點連接起來
$ns duplex-link $n0 $n2 2Mb 10ms DropTail
$ns duplex-link $n1 $n2 2Mb 10ms DropTail
$ns duplex-link $n2 $n3 1.7Mb 20ms DropTail

#設定ns2到n3之間的Queue Size爲10個封包大小
$ns queue-limit $n2 $n3 10
#設定節點的位置,這是要給NAM用的
$ns duplex-link-op $n0 $n2 orient right-down
$ns duplex-link-op $n1 $n2 orient right-up
$ns duplex-link-op $n2 $n3 orient right

#觀測n2到n3之間queue的變化,這是要給NAM用的
$ns duplex-link-op $n2 $n3 queuePos 0.5

#建立一條TCP的連線
set tcp [new Agent/TCP]
$tcp set class_ 2
$ns attach-agent $n0 $tcp
set sink [new Agent/TCPSink]
$ns attach-agent $n3 $sink
$ns connect $tcp $sink

#在NAM中,TCP的連線會以藍色表示
$tcp set fid_ 1
#在TCP連線之上建立FTP應用程式
set ftp [new Application/FTP]
$ftp attach-agent $tcp
$ftp set type_ FTP

#建立一條UDP的連線
set udp [new Agent/UDP]
$ns attach-agent $n1 $udp
set null [new Agent/Null]
$ns attach-agent $n3 $null
$ns connect $udp $null

#在NAM中,UDP的連線會以紅色表示
$udp set fid_ 2

#在UDP連線之上建立CBR應用程式
set cbr [new Application/Traffic/CBR]
$cbr attach-agent $udp
$cbr set type_ CBR
$cbr set packet_size_ 1000
$cbr set rate_ 1mb
$cbr set random_ false

#設定FTP和CBR資料傳送開始和結束時間
$ns at 0.1 "$cbr start"
$ns at 1.0 "$ftp start"
$ns at 4.0 "$ftp stop"
$ns at 4.5 "$cbr stop"

#結束TCP的連線(不一定需要寫下面的程式來實際結束連線)
$ns at 4.5 "$ns detach-agent $n0 $tcp ; $ns detach-agent $n3 $sink"
#在模擬環境中,5秒後去呼叫finish來結束模擬(這樣要注意模擬環境中
#的5秒並不一定等於實際模擬的時間

$ns at 5.0 "finish"

#執行模擬
$ns run

 

3、運行ns tool.tcl得到下圖

NS2簡單又經典的入門教程 - 星期八 - 星期八
NS2簡單又經典的入門教程 - 星期八 - 星期八

接下來,筆者先簡單介紹awk,然後如何使用awk去分析trace file,以得到Throughput、Delay、Jitter、和Loss Rate。

 

[awk]

A.簡介


         awk是一種程式語言。它具有一般程式語言常見的功能。因awk語言具有某些特點,如:使用直譯器(Interpreter)不需先行編譯;變數無型別之分(Typeless),可使用文字當陣列的註標(Associative Array)等特色。因此,使用awk撰寫程式比起使用其它語言更簡潔便利且節省時間。awk還具有一些內建功能,使得awk擅於處理具資料列(Record),欄位(Field)型態的資料;此外, awk內建有pipe的功能,可將處理中的資料傳送給外部的 Shell命令加以處理, 再將Shell命令處理後的資料傳回awk程式,這個特點也使得awk程式很容易使用系統資源。
 

B. awk是如何運作的

        為便於解釋awk程式架構,以及相關的術語,筆者就以上面trace file為例,來加以介紹。

a.名詞定義:

1.      資料列:awk從資料檔上讀取的基本單位,以trace file為例,awk讀入的

第一筆資料列為 ”+  0.1  1  2  cbr  1000  -------  2  1.0  3.1  0  0”

第二筆資料列為 “-  0.1  1  2  cbr  1000  -------  2  1.0  3.1  0  0”

一般而言,一筆資料列相當於資料檔上的一行資料。

 

2.      欄位(Field):為資料列上被分隔開的子字串。

以資料列”+  0.1  1  2  cbr  1000  -------  2  1.0  3.1  0  0”為例,

十一

十二

0.1

1

2

 

1000

-------

2

1.0

3.1

0

0

一般而言是以空白字元來分隔相鄰的欄位。

 

當awk讀入資料列後,會把每個欄位的值存入欄位變數。

欄位變數

意義

$0

為一字串, 其內容為目前awk所讀入的資料列.

$1

代表 $0 上第一個欄位的資料.

$2

代表 $0 上第二欄個位的資料.

……

……

 

b.程式主要節構:

        Pattern1           { Actions1 }

        Pattern2           { Actions2 }

        ……………………………

        Pattern3           { Actions3 }

 

一般常用”關係判斷式”來當成Pattern。例如:

x > 3 用來判斷變數x是否大於3

x == 5  用來判斷變數x是否等於5

awk提供c語言常見的關係運算元,如:>、<、>=、<=、==、!=等等

 

Actions是由許多awk指令所構成,而awk的指令與c語言中的指令非常類似。

IO指令:print 、 printf( ) 、getline ......

流程控制指令 : if ( ...) {...} else {…}、 while(…){…} ……

 

在awk程式的流程為先判斷Pattern的結果,若為真True則執行相對應的Actions,若為假False則不執行相對的Actions。若是處理的過程中沒有Pattern,awk會無條件的去執行Actions。

 

c.工作流程: 執行awk時, 它會反複進行下列四步驟。

1. 自動從指定的資料檔中讀取一筆資料列。

2. 自動更新(Update)相關的內建變數之值。

3. 逐次執行程式中 所有 的 Pattern { Actions } 指令。

4. 當執行完程式中所有 Pattern { Actions }時,若資料檔中還有未讀取的料,則反覆執行步驟1到步驟4。

 

awk會自動重覆進行上述的四個步驟,所以使用者不須在程式中寫這個迴圈。

 

[End-to-End Delay]

筆者把量測CBR封包端點到端點間延遲時間的awk程式,寫在檔案measure-delay.awk檔案中,讀者可以參考此範例,修改成符合讀者需求的程式。

 
BEGIN {
#程式初始化,設定一變數以記錄目前最高處理封包的ID。
     highest_packet_id = 0;
}
{
   action = $1;
   time = $2;
   node_1 = $3;
   node_2 = $4;
   type = $5;
   flow_id = $8; 
   node_1_address = $9;
   node_2_address = $10; 
   seq_no = $11;
   packet_id = $12;
 
#記錄目前最高的packet ID
   if ( packet_id > highest_packet_id )
                highest_packet_id = packet_id;
 
#記錄封包的傳送時間
   if ( start_time[packet_id] == 0 )  
               start_time[packet_id] = time;
 
#記錄CBR (flow_id=2) 的接收時間
   if ( flow_id == 2 && action != "d" ) {
      if ( action == "r" ) {
         end_time[packet_id] = time;
      }
   } else {
#把不是flow_id=2的封包或者是flow_id=2但此封包被drop的時間設為-1
      end_time[packet_id] = -1;
   }
}                                                                                                           
END {
#當資料列全部讀取完後,開始計算有效封包的端點到端點延遲時間 
    for ( packet_id = 0; packet_id <= highest_packet_id; packet_id++ ) {
       start = start_time[packet_id];
       end = end_time[packet_id];
       packet_duration = end - start;
 
#只把接收時間大於傳送時間的記錄列出來
       if ( start < end ) printf("%f %f\n", start, packet_duration);
   }
}
 
執行方法: ($為shell的提示符號)
$awk -f measure-delay.awk out.tr
 
若是要把結果存到檔案,可使用導向的方式。(把結果存到cbr_delay檔案中)
$awk -f measure-delay.awk out.tr > cbr_delay
 
執行結果:
0.100000 0.038706
0.108000 0.038706
0.116000 0.038706
0.124000 0.038706
0.132000 0.038706
………………………

 

[Jitter]

Jitter就是延遲時間變化量delay variance,由於網路的狀態隨時都在變化,有時候流量大,有時候流量小,當流量大的時候,許多封包就必需在節點的佇列中等待被傳送,因此每個封包從傳送端到目的地端的時間不一定會相同,而這個不同的差異就是所謂的Jitter。Jitter越大,則表示網路越不穩定。筆者把量測CBR flow的Jitter的awk寫在檔案measure-jitter.awk內。

 

BEGIN {

#程式初始化

   old_time=0;

   old_seq_no=0;

   i=0;

}

{

   action = $1;

   time = $2;

   node_1 = $3;

   node_2 = $4;

   type = $5;

   flow_id = $8;

   node_1_address = $9;

   node_2_address = $10;

   seq_no = $11;

   packet_id = $12;

 

#判斷是否為n2傳送到n3,且封包型態為cbr,動作為接受封包

   if(node_1==2 && node_2==3 && type=="cbr" && action=="r") {

#求出目前封包的序號和上次成功接收的序號差值

               dif=seq_no-old_seq_no;

 

#處理第一個接收封包

        if(dif==0) 

          dif=1;

 

#求出jitter

         jitter[i]=(time-old_time)/dif;

         seq[i]=seq_no;

                               i=i+1;

         old_seq_no=seq_no;

         old_time=time;

   }    

}

END {

   for (j=1; j <i ;j++)

    printf("%d\t%f\n",seq[j],jitter[j]);

}

 

執行方法: ($為shell的提示符號)
$awk -f measure-jitter.awk out.tr
 
若是要把結果存到檔案,可使用導向的方式。(把結果存到cbr_jitter檔案中)
$awk -f measure-jitter.awk out.tr > cbr_jitter
 
執行結果:
1             0.008000
2             0.008000
3             0.008000
4             0.008000
……………………
 
[另一種計算Jitter的方法---更精確的方式

# ================================================================================

# NormalJitter.awk

# Version now: 0.1

# Last Modified Date: 2004-10-23,19:39:54

# == Usage ==

# awk -f NormalJitter.awk out.tr

# == Programed By ==

# 查輝(ZHA HUI), Wuhan, China, Email: zhahui AT gmail.com

# == Description ==

# 本awk程式給出了另外一種jitter的計算方法,這種方法中jitter的計算是基於以下公式:

# jitter =((recvtime(j)-sendtime(j))-(recvtime(i)-sendtime(i)))/(j-i), 其中 j>i 。

# == Attention ==

# NormalJitter.awk中關於jitter的計算完全基於柯志亨博士的measure-delay.awk程式中delay的

# 計算。而measure-delay.awk在柯博士網頁中的ns2類比例子中是正確的,但是對於不同的例子需要根

# 據情況進行一定的修改,並可能需要加入某些魯棒性處理代碼(例如對於第一個包的處理,對於丟包的處

# 理等)。

# == Reference ==

# http://140.116.72.80/~smallko/ns2/ns2.htm

# == Feedback ==

# 如有任何關於本程式jitter計算的問題,請致信

# 柯志亨(ChihHeng, Ke)博士 smallko2001 AT pchome.com.tw 或者與本人聯繫。

# == Acknowledgements ==

# Dr. ChihHeng, Ke provided valuable documents and awk files upon my requests.

# ================================================================================

 

BEGIN {

#程式初始化,設定一變數以記錄目前最高處理封包的ID。

     highest_packet_id = 0;

}

{

   action = $1;

   time = $2;

   node_1 = $3;

   node_2 = $4;

   type = $5;

   flow_id = $8;

   node_1_address = $9;

   node_2_address = $10;

   seq_no = $11;

   packet_id = $12;

 

#記錄目前最高的packet ID

   if ( packet_id > highest_packet_id ) {

           highest_packet_id = packet_id;

        }

 

#記錄封包的傳送時間

   if ( start_time[packet_id] == 0 )  {

           # 記錄下包的seq_no -- ZHA

           pkt_seqno[packet_id] = seq_no;

           start_time[packet_id] = time;

   }

 

#記錄CBR (flow_id=2) 的接收時間

   if ( flow_id == 2 && action != "d" ) {

      if ( action == "r" ) {

         end_time[packet_id] = time;

      }

   } else {

#把不是flow_id=2的封包或者是flow_id=2但此封包被drop的時間設為-1

      end_time[packet_id] = -1;

   }

}                                                       

END {

        # 初始化jitter計算所需變量 -- ZHA

        last_seqno = 0;

        last_delay = 0;

        seqno_diff = 0;

#當資料列全部讀取完後,開始計算有效封包的端點到端點延遲時間

    for ( packet_id = 0; packet_id <= highest_packet_id; packet_id++ ) {

       start = start_time[packet_id];

       end = end_time[packet_id];

       packet_duration = end - start;

 

#只把接收時間大於傳送時間的記錄列出來

       if ( start < end ) {

               # 得到了delay值(packet_duration)後計算jitter -- ZHA

               seqno_diff = pkt_seqno[packet_id] - last_seqno;

               delay_diff = packet_duration - last_delay;

               if (seqno_diff == 0) {

                       jitter =0;

               } else {

                       jitter = delay_diff/seqno_diff;

               }

               printf("%f %f\n", start, jitter);

               last_seqno = pkt_seqno[packet_id];

               last_delay = packet_duration;

       }

    }

}

[Loss]

筆者把量測CBR Packet Loss的情況寫在檔案measure-drop.awk內。

 

BEGIN {

#程式初始化,設定一變數記錄packet被drop的數目

               fsDrops = 0;

               numFs = 0;

}

{

   action = $1;

   time = $2;

   node_1 = $3;

   node_2 = $4;

   src = $5;

   flow_id = $8;

   node_1_address = $9;

   node_2_address = $10;

   seq_no = $11;

   packet_id = $12;

 

#統計從n1送出多少packets

               if (node_1==1 && node_2==2 && action == "+")

                               numFs++;

              

#統計flow_id為2,且被drop的封包

               if (flow_id==2 && action == "d")

                               fsDrops++;

}

END {

               printf("number of packets sent:%d lost:%d\n", numFs, fsDrops);

}

 

執行方法: ($為shell的提示符號)
$awk -f measure-drop.awk out.tr
 
執行結果:

number of packets sent: 550  lost:8

這代表CBR送出了550個封包,但其中8個封包丟掉了。

 

[Throughput]

筆者把量測CBR Throughput的情況寫在檔案measure-throughput.awk內。在這裡的Throughput是指average throughput。

 

BEGIN {

               init=0;

               i=0;

}

{

               action = $1;

            time = $2;

            node_1 = $3;

            node_2 = $4;

            src = $5;

            pktsize = $6;

            flow_id = $8;

            node_1_address = $9;

            node_2_address = $10;

            seq_no = $11;

            packet_id = $12;

  

              if(action=="r" && node_1==2 && node_2==3 && flow_id==2) {

                              pkt_byte_sum[i+1]=pkt_byte_sum[i]+ pktsize;

                              

                               if(init==0) {

                                              start_time = time;

                                              init = 1;

                               }

                              

                               end_time[i] = time;

                               i = i+1;

               }

}

END {

#為了畫圖好看,把第一筆記錄的throughput設為零,以表示傳輸開始

               printf("%.2f\t%.2f\n", end_time[0], 0);

              

               for(j=1 ; j<i ; j++){

                               th = pkt_byte_sum[j] / (end_time[j] - start_time)*8/1000;

                               printf("%.2f\t%.2f\n", end_time[j], th);

               }

#為了畫圖好看,把第後一筆記錄的throughput再設為零,以表示傳輸結束

               printf("%.2f\t%.2f\n", end_time[i-1], 0);

}

 

執行方法: ($為shell的提示符號)
$awk -f measure-throughput.awk out.tr
 
若是要把結果存到檔案,可使用導向的方式。(把結果存到cbr_throughput檔案中)
$awk -f measure-throughput.awk out.tr > cbr_throughput
 
執行結果:
0.14        0.00
0.15        1000.00
0.15        1000.00
0.16        1000.00
……………………

 

介紹完了如何量測End-to-End Delay、Jitter、Packet Loss、和Throughput後,最後就是要把量測的數據畫出來。這裡筆者介紹xgraph和gnuplot,但是xgraph畫出來的圖真的有點醜,所以就不仔細介紹。筆者會把重心放在gnuplot。

 

[xgraph]

在Shell的提示符號後輸入startxwin.bat,接著會出現一個新的視窗,在此視窗輸入xgraph cbr_delay,就可以把前面所存下來的檔案畫出來。xgraph的運作是把第一排當作x軸的資料,第二排當作是y軸的資料,然後把圖給畫出來。

 

cbr-delay的圖

NS2簡單又經典的入門教程 - 星期八 - 星期八
 

在一剛開始的時候,由於只有CBR的封包,所以End-to-End Delay Time都是固定的,但在1.0秒後,網路多了FTP的封包,這使得CBR封包和FTP封包必須互相的搶奪網路的資源,因此End-to-End Delay Time變得不在固定,但等到FTP傳輸結束後,CBR封包的End-to-End Delay Time又變成是固定值了。< xmlnamespace prefix ="o" ns ="urn:schemas-microsoft-com:office:office" />

 

cbr-jitter的圖:

NS2簡單又經典的入門教程 - 星期八 - 星期八

 

 

Jitter的變化情況跟End-to-End的原因是相同的,都是由於FTP封包的加入才會指得End-to-End Delay Time會產生變化。

 

cbr-throughput的圖:

NS2簡單又經典的入門教程 - 星期八 - 星期八
 

從圖可以很清楚地看出,從0.1秒到4.5秒,CBR的傳輸速率大都維持在1Mbps。

 

看了上面這三張圖,不知道讀者是否有一種感覺,就是真的有點醜。是不是想換個工具呢?用Excel嗎?筆者認為還是一樣醜,所以筆者強力推薦使用接下來要介紹的gnuplot。

 

[gnuplot]

A.     簡介

gnuplot 是一個命令導向的交談式繪圖程式(command-driven interactive function plotting program)。使用者輸入的每一項命令,可以逐步設定或

修改繪圖環境。它以圖形表達數據或涵數,使我們可以藉由圖形做更進一步的分析。

 

B.     如何使用gnuplot  ($為cygwin shell的提示符號)

a.       $ startxwin.bat

 

NS2簡單又經典的入門教程 - 星期八 - 星期八

 

 

b.      在新開出來的視窗輸入gnuplot

$gnuplot

NS2簡單又經典的入門教程 - 星期八 - 星期八

 

 

c.       執行 GNUPLOT 程式時,GNUPLOT 首先檢查是否設定環境參數 DISPLAY, 若有則依其設定。當其確定為 X 環境時,將輸出模式設定為 X11。筆者以cbr_delay為例,先簡單示範如何把圖給畫出來。畫圖的指令是plot,要畫的檔案cbr_delay。

gnuplot> plot “cbr_delay”

NS2簡單又經典的入門教程 - 星期八 - 星期八

 

 

圖是畫出來了,但是筆者要的不是把數據用打點的方式畫出來,而是要把這些點連起來。沒關係,接下來,只要學著修改環境變數,就可以畫出理想的圖了。

 

C.     修改環境變數

a.座標軸(Axis):繪圖參數在設定座標軸方面的參數可分為變數名稱、標點、網格、顯示範圍、 座標軸顯示方式與顯示與否等六方面的設定。不過筆者只介紹幾個常用的設定,詳細的設定可以參考http://phi.sinica.edu.tw/aspac/reports/94/94002/

 

功能

繪圖參數名稱

標點設定

xtics,ydtics

網格設定

grid

座標顯示方式

logscale

顯示範圍設定

autoscale,xrange,yrange

座標軸顯示與否

xzeroaxis,yzeroaxis 

  

說明:

1.      xtics是對 X 座標軸上的標點做設定。如起始點、結束點、間隔或在軸上特定點放特定的名稱。其語法為:

set xtics { {<start>, <incr>{, <end>}} |
                       {({"<label>"} <pos> {, {"<label>"} <pos>}...)} }
unset xtics   # 不標示任何 X 軸上的標點。
show xtics   # 顯示 X 軸標點的狀況。

              

               例:

               (原本) gnuplot > plot sin(x)

NS2簡單又經典的入門教程 - 星期八 - 星期八
 

在x軸上的標點設定是以5為單位。若是覺得想要把標點距離設小一點,例如設為1,可以使用

gnuplot > set xtics -10, 1, 10

gnuplot > plot sin(x)

 

NS2簡單又經典的入門教程 - 星期八 - 星期八
 

ytics與 xtics相似,不同點是作用在y軸上。

 

2.      網格設定 : 在 XY 座標平面上依刻度畫上方格子。

gnuplot> set grid

gnuplot> plot sin(x)

 

NS2簡單又經典的入門教程 - 星期八 - 星期八

 

 

若是想要把網格拿掉,只要在下unset grid即可。

 

3.      座標顯示方式 : 分為線性與對數兩種。 一般為前者,若要改為對數方式,其語法為:

set logscale <axes> <base>

其中 axes 為 X 軸、Y 軸、Z 軸的任意組合。base 預設為 10。

              

4.      顯示範圍設定:改變各軸的顯示範圍。autoscale 參數設定後 gnuplot自動調整顯示範圍。而xrange、yrange則是可以由使用者設定該軸的範圍。以 xrange 為例,其語法為:

    set xrange [{<xmin> : <xmax>}]

其中參數 <xmin> 與 <xmax> 代表 X 軸的起點與終點,可以是數字或數學式子。

例:

gnuplot> set xrange [0:10]

gnuplot> plot sin(x)

NS2簡單又經典的入門教程 - 星期八 - 星期八
 

5.      座標軸顯示與否設定 : 設定是否要畫出座標軸,以 X 軸為例:

set xzeroaxis       # 設定顯示 X 座標軸

unset xzeroaxis     # 設定不顯示 X 座標軸

show xzeroaxis     # 檢查 X 座標軸顯示與否

 

gnuplot> set  xzeroaxis

gnuplot> plot sin(x)

 

NS2簡單又經典的入門教程 - 星期八 - 星期八

 

若是要把xzeroaxis拿掉,只要下unset xzeroaxis即可。

 

         b.標示(Label):GNUPLOT 除了繪出圖形外,尚可加入註解做為輔助說明。這註解包括文字與線條兩方面,其提供的設定有

            

功能

繪圖參數名稱

線條

arrow

文字註解

key,label,title,xlabel,ylabel

            

             說明:

1.      線條:在圖上畫一線段 可以選擇有無箭頭。其語法為

set arrow {<tag>} {from <sx>,<sy>{,<sz>}}
                 {to <ex>,<ey>{,<ez>}} {{no}head}
unset arrow {<tag>}      # 刪除一線條
show arrow             # 顯示線條使用情況

其中參數 <tag> 是給該條線條一個整數名稱,若不設定則為最小可用整數。此線條由座標(sx, sy, sz)到(ex, ey, ez)(在2D中為 (sx, sy)到(ex, ey))。參數 nohead 為畫沒有箭頭的線段,參數 head 或沒有 nohead 為畫有箭頭的線段。

#畫一帶有箭頭的線條由原點到 (1,2)。

gnuplot> set arrow to 1,2

 

#畫一名為3的帶箭頭線條由(0.4, 0.3 ) 到 (0.2, 0.1)。

gnuplot> set arrow 3 from 0.4, 0.3 to 0.2, 0.1

 

         #刪除名為3的線條。
         gnuplot>unset arrow 3
 
         #刪除所有線條。
         guplot> unset arrow
 
1.                             文字註解:分為設定標頭(title)和標示(label)。
標頭(title):設定為在圖的正上方加上說明本圖的文字。其語法為:
     set title {"<title-text>"} {<xoff>}{,<yoff>}

show title

其中設定參數 <xoff> 或 <yoff> 為微調標頭放置的位址。 xlabel, ylabel的語法與title相同,其各自描述一座標軸。

 

標示 (label):為在圖上任一位置加上文字說明,一般與線條一併使用。

     set label {<tag>} {"<label_text>"}
             {at <x>,<y>{,<z>}}{<justification>}
         unset label {<tag>}          # 刪除一標示
show label                # 顯示標示使用情況

其中參數<tag>與"線條" (arrow) 中<tag>意義相同,用以區別不同的 label。參數 <justification> 是調整文字放置的位置,可以是 left,right 或 center。

 

        # 將 y=x 放在座標 (1,2) 之處。

gnuplot> set label “y=x”at 1,2

 

         # 將 y=x^2 放在座標 (2,3) 之處,並命名為 3。
         gnuplot> set label 3 "y=x^2" at 2,3 right
 
         # 將名為 3 的標示居中放置。
     gnuplot> set label 3 center

 

# 刪除名為3的標示。

gnuplot> unset label 3

 

# 刪除所有標示。

gnuplot> unsel label

 

一般繪一圖形後,gnuplot會將函數名稱或圖形檔案名稱置於右上角。 key參數設定可改變名稱放置位置。其語法為:

         set key
               set key <x>,<y>{,<z>}           #其中參數 <x>, <y>, <z> 設定名稱放置位置。
               unset key                               #不顯示名稱
        show key               #再度顯示名稱

 

[例]

gnuplot> set title “cbr_delay”

gnuplot> set xlabel “simulation time”

gnuplot> set ylabel “delay time”

               gnuplot> unset key

               gnuplot> set label “constant delay= 0.038706 sec”at 0.1, 0.05

               gnuplot> set arrow from 0.5, 0.05 to 0.5, 0.04

 

NS2簡單又經典的入門教程 - 星期八 - 星期八
 
 

c.圖樣(Style):gnuplot描繪數據資料圖形是以讀入檔案中的座標值後,以圖樣繪上。而描繪函數圖形是計算若干點的函數值後,以某種圖樣將函數值繪上。一般是取樣 100 點及採取線條作為圖樣。GNUPLOT 可提供 9 種圖樣,分別是

1.      lines : 將相鄰的點以線條連接。如
plot sin(x) with lines

2.      points : 將每一點以一符號繪上。如
plot sin(x) with points

3.      linespoints : 同時具有 lines 及 points 的功能。如
plot sin(x) with linespoints

4.      impulses : 將每一點畫一垂直線至 X 軸。如
plot sin(x) with impulses

5.      dots : 將每一點繪一細點。如 plot sin(x) with dots。

6.      steps : 以垂直線及水平線各一條來連接兩點,形成梯形。如連接 (x1,y1),(x2,y2)兩點,以(x1,y1)到(x2,y1)和(x2,y1)到(x2,y2) 兩線段連接。如 plot sin(x) with steps。


7.     
errorbars : 對每一點座標值 (x,y),畫一由 (x,ylow) 至 (x,yhigh) 的線段。並在線段兩端做上 tic mark。如
plot sin(x) with errorbars。

8.      boxes : The boxes style draws a box centred about the given x coordinate from the yaxis to the given y coordinate.如
plot sin(x) with boxes

9.      boxerrorbars : 組合 errorbars 與 boxes 兩者功能。如
plot sin(x) with boxerrorbars

         [例] 把cbr_delay中的數據用lines和points連起來。

         gnuplot> plot “cbr_delay” with linespoints

 

NS2簡單又經典的入門教程 - 星期八 - 星期八
 
 

這個圖有沒有比用xgraph畫出來的圖好看呢?

 

d.輸出(Output):GNUPLOT 的輸出參數設定有
terminal,output。不過在這裡筆者只介紹如何把畫出來的圖存成Gif格式。

#把輸出設成存成gif格式,內定為X11 terminal


gnuplot> set terminal gif


 


#把輸出的檔名設為cbr_delay.gif


gnuplot> set output “cbr_delay.gif”


 


#把資料重新繪一次


gnuplot> replot


 


然後就會產生一個cbr_delay.gif的圖檔了

NS2簡單又經典的入門教程 - 星期八 - 星期八
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章