本文介绍如何用matplotlib将The ONE一组MessageStatsReport仿真结果可视化。
最开始我是用gnuplot,直到我做一个简单图例(legend,字符串数组的变量含有空格,titles = "'With XOR' 'Without XOR'"
),花去了我两个多小时(详情见如何让gnuplot字符串数组中的变量含有空格)。
在使用gnuplot过程中,了解到Python有个matplotlib库是用来绘图的,加之,那会对Python越来越熟悉,所以决定转向matplotlib。转向matplotlib,不得不说让我节省了很多时间,在此期间,也做了一些笔记。
给我感觉,matplotlib作出来的图不是很炫,或者说要得到很炫的图需要花很多时间,不过对于学术文章,我想是够了。
假设我得到了一组仿真结果(详情见The ONE使用笔记:批量仿真),如下(MessageBroadcastStatsReport是我自己定义的Report,跟MessageStatsReport类似):
4 -rw-rw-r-- 1 qiankun qiankun 515 janv. 18 01:52 WithXOR-CDSD-TH-3-10_20_MessageBroadcastStatsReport.txt
4 -rw-rw-r-- 1 qiankun qiankun 515 janv. 18 02:19 WithXOR-CDSD-TH-3-11_20_MessageBroadcastStatsReport.txt
4 -rw-rw-r-- 1 qiankun qiankun 513 janv. 17 22:01 WithXOR-CDSD-TH-3-1_20_MessageBroadcastStatsReport.txt
4 -rw-rw-r-- 1 qiankun qiankun 515 janv. 18 02:47 WithXOR-CDSD-TH-3-12_20_MessageBroadcastStatsReport.txt
4 -rw-rw-r-- 1 qiankun qiankun 515 janv. 18 03:15 WithXOR-CDSD-TH-3-13_20_MessageBroadcastStatsReport.txt
4 -rw-rw-r-- 1 qiankun qiankun 515 janv. 18 03:43 WithXOR-CDSD-TH-3-14_20_MessageBroadcastStatsReport.txt
4 -rw-rw-r-- 1 qiankun qiankun 515 janv. 18 04:11 WithXOR-CDSD-TH-3-15_20_MessageBroadcastStatsReport.txt
4 -rw-rw-r-- 1 qiankun qiankun 515 janv. 18 04:38 WithXOR-CDSD-TH-3-16_20_MessageBroadcastStatsReport.txt
4 -rw-rw-r-- 1 qiankun qiankun 515 janv. 18 05:05 WithXOR-CDSD-TH-3-17_20_MessageBroadcastStatsReport.txt
4 -rw-rw-r-- 1 qiankun qiankun 515 janv. 18 05:32 WithXOR-CDSD-TH-3-18_20_MessageBroadcastStatsReport.txt
4 -rw-rw-r-- 1 qiankun qiankun 513 janv. 17 22:26 WithXOR-CDSD-TH-3-2_20_MessageBroadcastStatsReport.txt
4 -rw-rw-r-- 1 qiankun qiankun 514 janv. 17 22:51 WithXOR-CDSD-TH-3-3_20_MessageBroadcastStatsReport.txt
4 -rw-rw-r-- 1 qiankun qiankun 514 janv. 17 23:16 WithXOR-CDSD-TH-3-4_20_MessageBroadcastStatsReport.txt
4 -rw-rw-r-- 1 qiankun qiankun 514 janv. 17 23:42 WithXOR-CDSD-TH-3-5_20_MessageBroadcastStatsReport.txt
4 -rw-rw-r-- 1 qiankun qiankun 514 janv. 18 00:07 WithXOR-CDSD-TH-3-6_20_MessageBroadcastStatsReport.txt
4 -rw-rw-r-- 1 qiankun qiankun 514 janv. 18 00:34 WithXOR-CDSD-TH-3-7_20_MessageBroadcastStatsReport.txt
4 -rw-rw-r-- 1 qiankun qiankun 514 janv. 18 01:00 WithXOR-CDSD-TH-3-8_20_MessageBroadcastStatsReport.txt
4 -rw-rw-r-- 1 qiankun qiankun 514 janv. 18 01:26 WithXOR-CDSD-TH-3-9_20_MessageBroadcastStatsReport.txt
每一个MessageBroadcastStatsReport文件大概包含如下内容:
Message stats for scenario WithXOR-CDSD-TH-3-4_20
sim_time: 47400.0000
created: 466683
started: 1945912
emissions: 1928668
nrofXor: 17244
relayed: 1945912
aborted: 0
dropped: 0
removed: 1945912
delivered: 52538
delivery_prob: 0.1126
xor_prob: 0.0089
response_prob: 0.0000
overhead_ratio: 36.0382
overheadBc_ratio: 36.7100
lastReceivedTime: 43901.0000
latency_avg: 15836.0662
latency_med: 14265.0000
hopcount_avg: 7.9397
hopcount_med: 8
buffertime_avg: 2197.7907
buffertime_med: 1539.0000
rtt_avg: NaN
rtt_med: NaN
将所需要的指标(比如:delivered
)读到一个数组,源代码如下:
def read_files(filenames, metric):
"""
Read values with a given metric from a batch of files.
Return a list of values
"""
result = list()
for filename in filenames:
with open(filename, 'r') as f:
for line in f:
if line.startswith(metric):
value = float(line.strip().split(':')[1])
result.append(value)
break
return result
def main():
# Step 1: Read files
# Get filenames
list_message_intervals = range(1, 14)
filenames = ['WithXOR-CDSD-TH-3-{interval}_20_MessageBroadcastStatsReport.txt'.format(interval=interval)
for interval in list_message_intervals]
# Read files
metric = 'delivered'
list_delivered = read_files(filenames, metric)
# [47670.0, 49541.0, 50944.0, 52538.0, 53841.0, 55770.0, 57245.0, 58479.0, 58269.0, 58095.0, 58257.0, 61098.0, 62986.0]
有了x
(list_message_intervals
)和y
(list_delivered
)就可以绘图了,源代码如下:
# Step 2: Plot figures
x = list_message_intervals
y = list_delivered
fig, ax = plt.subplots()
ax.plot(x, y, 'r-o', label='With NC', linewidth=2,
markeredgewidth=1, markerfacecolor='white', markersize=8)
# Decoration
plt.ticklabel_format(style='sci', axis='y', scilimits=(0,0))
plt.grid()
plt.xlabel(r'The message creation period $\Delta$', fontsize=15)
plt.ylabel('The number of messages delivered', fontsize=15)
ax.legend(loc='best')
plt.xticks(x, x)
plt.xlim(min(x), max(x))
out_file = 'delivered.png'
plt.savefig(out_file)
plt.show()
运行程序,得到下图:
Fig. 1:The number of delivered messages in different message creation periods.
本文的完整代码已分享到我的Github,在这里的plot_MessageStatsReport.py
。