一 直接使用Gnuplot工具
以NS3自带的例子程为例来说明。
进行NS安装目录,下面有/examples/tutorial目录下,有一个拥塞窗口的例子 fifth.cc
cd NS3/ cd ns-allinone-3.25/ cd ns-3.25 ./waf --run examples/tutorial/fifth >fifth.dat 2>&1则在后台完成对fifth.cc的运行并把结果存在ns-3.25目录下的fifth.dat中 解释: > 表示输出重定向。 >fifth.dat 把执行的结果存入到文件。一般情况下,输出重定向到当前屏幕,>fifth.dat表示输出重定向到该文件。 2>&1 在shell中,文件描述符通常是:STDIN,STDOUT,STDERR,即:0,1,2, &表示在后台执行, 2>&1 表示,把错误信息stderr也放到stdout中输出. 在dat所在目录下进入GNUPLOT gnuplot set terminal png size 640,480 set output "fifth.png" plot "fifth.dat" using 1:2 title "Congestion Window" with linespoints 会发现在ns-3.25目录下产生fifth.png图解释:
set termianl png //设置输出图片格式,如png,gif,jpg等
set size width,height //设备图片宽度,高度
set output "图片名称" //设置保存图片名称。
plot title "标题名" //设置图片标题名称,一般用英文,有时不支持中文字符
plot "数据.dat" using 1:2 with linespoints //把数据文件"数据.dat"输出图像, using 1:2,使用第1,2列数据输出.
with linespoints //点用符号,点与点之间用线连接
a plot "数据.dat" //只输出数据点
b plot "数据.dat" with lines //把点连起来,成线。
c plot "数据.dat" with linespoints //点用符号,点与点之间用线连接
d plot 'file.dat' using 1:3 with linespoints //使用1,3列绘图
e plot 'file.dat' using 1:($3/2) with linespoints //使用第一列与第三列的二分之一绘图
二 NS3自带的Gnuplot类作为中间接口间接调用Gnuplot工具
NS3为了能生成gnuplot图,提供了2个和gnuplot相关的类,包含在头文件"ns3/gnuplot.h"中:
1 Gnuplot类:是NS3与gnuplot工具之间的接口,其功能包括:设置文件名,设置坐标,设置标题,添加数据集合,生成最终文件具体见Doxygen。
2 GnuplotDataset类:一个数据集合,存储数据供gnuplot使用,是一个抽象基类,派生了4大类:Gnuplot2dDataset Gnuplot2dFunction Gnuplot3dDataset Gnuplot3dFunction
使用NS3提供的类画图过程:
i 仿真代码加入Gnuplot类及其函数;
ii 运行代码,生成Gnuplot控制文件;
iii 使用Gnuplot控制文件调用Gnuplot工具
使用example/tutorial/gnuplot-example.cc举例如下:
#include <fstream> #include "ns3/gnuplot.h" using namespace ns3; namespace { //=========================================================================== // Function: Create2DPlotFile // // // This function creates a 2-D plot file. //=========================================================================== void Create2DPlotFile () { std::string fileNameWithNoExtension = "plot-2d";//没有扩展名的文件名 std::string graphicsFileName = fileNameWithNoExtension + ".png";//图片文件名 std::string plotFileName = fileNameWithNoExtension + ".plt";//Gnuplot控制文件名 std::string plotTitle = "2-D Plot";//图片标题 std::string dataTitle = "2-D Data";//数据标题 // Instantiate the plot and set its title. Gnuplot plot (graphicsFileName); plot.SetTitle (plotTitle); // Make the graphics file, which the plot file will create when it // is used with Gnuplot, be a PNG file. plot.SetTerminal ("png");//设置图片格式 // Set the labels for each axis. plot.SetLegend ("X Values", "Y Values");//设置坐标标签 // Set the range for the x axis. plot.AppendExtra ("set xrange [-6:+6]"); // Instantiate the dataset, set its title, and make the points be // plotted along with connecting lines. Gnuplot2dDataset dataset; dataset.SetTitle (dataTitle); dataset.SetStyle (Gnuplot2dDataset::LINES_POINTS);//线型 double x; double y; // Create the 2-D dataset. for (x = -5.0; x <= +5.0; x += 1.0) { // Calculate the 2-D curve // // 2 // y = x . // y = x * x;//图形函数 // Add this point. dataset.Add (x, y);//向对象数据添加坐标点 } // Add the dataset to the plot. plot.AddDataset (dataset);//把数据对象添加到gnuplot对象 // Open the plot file. std::ofstream plotFile (plotFileName.c_str()); // Write the plot file. plot.GenerateOutput (plotFile); // Close the plot file. plotFile.close (); } //=========================================================================== // Function: Create2DPlotWithErrorBarsFile // // // This function creates a 2-D plot with error bars file. //=========================================================================== void Create2DPlotWithErrorBarsFile () { std::string fileNameWithNoExtension = "plot-2d-with-error-bars"; std::string graphicsFileName = fileNameWithNoExtension + ".png"; std::string plotFileName = fileNameWithNoExtension + ".plt"; std::string plotTitle = "2-D Plot With Error Bars"; std::string dataTitle = "2-D Data With Error Bars"; // Instantiate the plot and set its title. Gnuplot plot (graphicsFileName); plot.SetTitle (plotTitle); // Make the graphics file, which the plot file will create when it // is used with Gnuplot, be a PNG file. plot.SetTerminal ("png"); // Set the labels for each axis. plot.SetLegend ("X Values", "Y Values"); // Set the range for the x axis. plot.AppendExtra ("set xrange [-6:+6]"); // Instantiate the dataset, set its title, and make the points be // plotted with no connecting lines. Gnuplot2dDataset dataset; dataset.SetTitle (dataTitle); dataset.SetStyle (Gnuplot2dDataset::POINTS);//点型 // Make the dataset have error bars in both the x and y directions. dataset.SetErrorBars (Gnuplot2dDataset::XY); double x; double xErrorDelta; double y; double yErrorDelta; // Create the 2-D dataset. for (x = -5.0; x <= +5.0; x += 1.0) { // Calculate the 2-D curve // // 2 // y = x . // y = x * x; // Make the uncertainty in the x direction be constant and make // the uncertainty in the y direction be a constant fraction of // y's value. xErrorDelta = 0.25; yErrorDelta = 0.1 * y; // Add this point with uncertainties in both the x and y // direction. dataset.Add (x, y, xErrorDelta, yErrorDelta); } // Add the dataset to the plot. plot.AddDataset (dataset); // Open the plot file. std::ofstream plotFile (plotFileName.c_str()); // Write the plot file. plot.GenerateOutput (plotFile); // Close the plot file. plotFile.close (); } //=========================================================================== // Function: Create3DPlotFile // // // This function creates a 3-D plot file. //=========================================================================== void Create3DPlotFile () { std::string fileNameWithNoExtension = "plot-3d"; std::string graphicsFileName = fileNameWithNoExtension + ".png"; std::string plotFileName = fileNameWithNoExtension + ".plt"; std::string plotTitle = "3-D Plot"; std::string dataTitle = "3-D Data"; // Instantiate the plot and set its title. Gnuplot plot (graphicsFileName); plot.SetTitle (plotTitle); // Make the graphics file, which the plot file will create when it // is used with Gnuplot, be a PNG file. plot.SetTerminal ("png"); // Rotate the plot 30 degrees around the x axis and then rotate the // plot 120 degrees around the new z axis. plot.AppendExtra ("set view 30, 120, 1.0, 1.0"); // Make the zero for the z-axis be in the x-axis and y-axis plane. plot.AppendExtra ("set ticslevel 0"); // Set the labels for each axis. plot.AppendExtra ("set xlabel \"X Values\""); plot.AppendExtra ("set ylabel \"Y Values\""); plot.AppendExtra ("set zlabel \"Z Values\""); // Set the ranges for the x and y axis. plot.AppendExtra ("set xrange [-5:+5]"); plot.AppendExtra ("set yrange [-5:+5]"); // Instantiate the dataset, set its title, and make the points be // connected by lines. Gnuplot3dDataset dataset; dataset.SetTitle (dataTitle); dataset.SetStyle ("with lines"); double x; double y; double z; // Create the 3-D dataset. for (x = -5.0; x <= +5.0; x += 1.0) { for (y = -5.0; y <= +5.0; y += 1.0) { // Calculate the 3-D surface // // 2 2 // z = x * y . // z = x * x * y * y; // Add this point. dataset.Add (x, y, z); } // The blank line is necessary at the end of each x value's data // points for the 3-D surface grid to work. dataset.AddEmptyLine (); } // Add the dataset to the plot. plot.AddDataset (dataset); // Open the plot file. std::ofstream plotFile (plotFileName.c_str()); // Write the plot file. plot.GenerateOutput (plotFile); // Close the plot file. plotFile.close (); } } // anonymous namespace int main (int argc, char *argv[]) { // Create a 2-D plot file. Create2DPlotFile(); // Create a 2-D plot with error bars file. Create2DPlotWithErrorBarsFile(); // Create a 3-D plot file. Create3DPlotFile(); return 0; }把它复制到scratch目录下,运行例子:
./waf --run scratch/gnuplot-example 会在安装目录ns3-3.25下存在以下gnuplot控制文件:plot-2d.plt plot-2d-with-error-bars.plt plot-3d.plt
直接使用gnuplot处理这些控制文件:
gnuplot plot-2d.plt gnuplot plot-2d-with-error-bars.plt gnuplot plot-2d-with-error-bars.plt 会产生这些图形文件:plot-2d.png plot-2d-with-error-bars.png plot-3d.png
实际上,这只是利用例程里给定函数如y=x*x产生的数据进而画图,而实际应用中要选择需要统计的网络数据放在相应的gnuplot数据对象里即可。