Home | History | Annotate | Download | only in test
      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