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 14 import matplotlib 15 import matplotlib.pyplot as plt 16 import numpy 17 import re 18 import sys 19 20 # Change this to True to save the figure to a file. Look below for details. 21 save_figure = False 22 23 class 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 71 def 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 124 def 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 165 if __name__ == '__main__': 166 main() 167