1#!/usr/bin/env python 2# Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 3# 4# Use of this source code is governed by a BSD-style license 5# that can be found in the LICENSE file in the root of the source 6# tree. An additional intellectual property rights grant can be found 7# in the file PATENTS. All contributing project authors may 8# be found in the AUTHORS file in the root of the source tree. 9 10# This script is used to plot simulation dynamics. 11# Able to plot each flow separately. Other plot boxes can be added, 12# currently one for Throughput, one for Latency and one for Packet Loss. 13 14import matplotlib 15import matplotlib.pyplot as plt 16import numpy 17import re 18import sys 19 20# Change this to True to save the figure to a file. Look below for details. 21save_figure = False 22 23class Variable(object): 24 def __init__(self, variable): 25 self._ID = variable[0] 26 self._xlabel = variable[1] 27 self._ylabel = variable[2] 28 self._subplot = variable[3] 29 self._y_max = variable[4] 30 self.samples = dict() 31 32 def getID(self): 33 return self._ID 34 35 def getXLabel(self): 36 return self._xlabel 37 38 def getYLabel(self): 39 return self._ylabel 40 41 def getSubplot(self): 42 return self._subplot 43 44 def getYMax(self): 45 return self._y_max 46 47 def getNumberOfFlows(self): 48 return len(self.samples) 49 50 51 def addSample(self, line): 52 groups = re.search(r'_(((\d)+((,(\d)+)*))_(\D+))#\d@(\S+)', line) 53 54 # Each variable will be plotted in a separated box. 55 var_name = groups.group(1) 56 alg_name = groups.group(8) 57 58 alg_name = alg_name.replace('_', ' ') 59 60 if alg_name not in self.samples.keys(): 61 self.samples[alg_name] = {} 62 63 if var_name not in self.samples[alg_name].keys(): 64 self.samples[alg_name][var_name] = [] 65 66 sample = re.search(r'(\d+\.\d+)\t([-]?\d+\.\d+)', line) 67 68 s = (sample.group(1), sample.group(2)) 69 self.samples[alg_name][var_name].append(s) 70 71def plotVar(v, ax, show_legend, show_x_label): 72 if show_x_label: 73 ax.set_xlabel(v.getXLabel(), fontsize='large') 74 ax.set_ylabel(v.getYLabel(), fontsize='large') 75 76 for alg in v.samples.keys(): 77 78 for series in v.samples[alg].keys(): 79 80 x = [sample[0] for sample in v.samples[alg][series]] 81 y = [sample[1] for sample in v.samples[alg][series]] 82 x = numpy.array(x) 83 y = numpy.array(y) 84 85 line = plt.plot(x, y, label=alg, linewidth=4.0) 86 87 colormap = {'Available0':'#AAAAAA', 88 'Available1':'#AAAAAA', 89 'GCC0':'#80D000', 90 'GCC1':'#008000', 91 'GCC2':'#00F000', 92 'GCC3':'#00B000', 93 'GCC4':'#70B020', 94 'NADA0':'#0000AA', 95 'NADA1':'#A0A0FF', 96 'NADA2':'#0000FF', 97 'NADA3':'#C0A0FF', 98 'NADA4':'#9060B0',} 99 100 flow_id = re.search(r'(\d+(,\d+)*)', series) # One or multiple ids. 101 key = alg + flow_id.group(1) 102 103 if key in colormap: 104 plt.setp(line, color=colormap[key]) 105 elif alg == 'TCP': 106 plt.setp(line, color='#AAAAAA') 107 else: 108 plt.setp(line, color='#654321') 109 110 if alg.startswith('Available'): 111 plt.setp(line, linestyle='--') 112 plt.grid(True) 113 114 # x1, x2, y1, y2 115 _, x2, _, y2 = plt.axis() 116 if v.getYMax() >= 0: 117 y2 = v.getYMax() 118 plt.axis((0, x2, 0, y2)) 119 120 if show_legend: 121 plt.legend(loc='upper center', bbox_to_anchor=(0.5, 1.40), 122 shadow=True, fontsize='large', ncol=len(v.samples)) 123 124def main(): 125 variables = [ 126 ('Throughput_kbps', "Time (s)", "Throughput (kbps)", 1, 4000), 127 ('Delay_ms', "Time (s)", "One-way Delay (ms)", 2, 500), 128 ('Packet_Loss', "Time (s)", "Packet Loss Ratio", 3, 1.0), 129 # ('Sending_Estimate_kbps', "Time (s)", "Sending Estimate (kbps)", 130 # 4, 4000), 131 ] 132 133 var = [] 134 135 # Create objects. 136 for variable in variables: 137 var.append(Variable(variable)) 138 139 # Add samples to the objects. 140 for line in sys.stdin: 141 if line.startswith("[ RUN ]"): 142 test_name = re.search(r'\.(\w+)', line).group(1) 143 if line.startswith("PLOT"): 144 for v in var: 145 if v.getID() in line: 146 v.addSample(line) 147 148 matplotlib.rcParams.update({'font.size': 48/len(variables)}) 149 150 # Plot variables. 151 fig = plt.figure() 152 153 # Offest and threshold on the same plot. 154 n = var[-1].getSubplot() 155 i = 0 156 for v in var: 157 ax = fig.add_subplot(n, 1, v.getSubplot()) 158 plotVar(v, ax, i == 0, i == n - 1) 159 i += 1 160 161 if save_figure: 162 fig.savefig(test_name + ".png") 163 plt.show() 164 165if __name__ == '__main__': 166 main() 167