/bin/plot.py

https://bitbucket.org/6tisch/simulator
Python | 157 lines | 107 code | 26 blank | 24 comment | 18 complexity | e0676a239134383434232e0b25dc50c2 MD5 | raw file
  1. """
  2. Plot a stat over another stat.
  3. Example:
  4. python plot.py --inputfolder simData/numMotes_50/ -x chargeConsumed --y aveLatency
  5. """
  6. from __future__ import print_function
  7. # =========================== imports =========================================
  8. # standard
  9. from builtins import range
  10. import os
  11. import argparse
  12. import json
  13. import glob
  14. from collections import OrderedDict
  15. import numpy as np
  16. # third party
  17. import matplotlib
  18. matplotlib.use('Agg')
  19. import matplotlib.pyplot as plt
  20. # ============================ defines ========================================
  21. KPIS = [
  22. 'latency_max_s',
  23. 'latency_avg_s',
  24. 'latencies',
  25. 'lifetime_AA_years',
  26. 'sync_time_s',
  27. 'join_time_s',
  28. 'upstream_num_lost'
  29. ]
  30. # ============================ main ===========================================
  31. def main(options):
  32. # init
  33. data = OrderedDict()
  34. # chose lastest results
  35. subfolders = list(
  36. [os.path.join(options.inputfolder, x) for x in os.listdir(options.inputfolder)]
  37. )
  38. subfolder = max(subfolders, key=os.path.getmtime)
  39. for key in options.kpis:
  40. # load data
  41. for file_path in sorted(glob.glob(os.path.join(subfolder, '*.kpi'))):
  42. curr_combination = os.path.basename(file_path)[:-8] # remove .dat.kpi
  43. with open(file_path, 'r') as f:
  44. # read kpi file
  45. kpis = json.load(f)
  46. # init data list
  47. data[curr_combination] = []
  48. # fill data list
  49. for run in kpis.values():
  50. for mote in run.values():
  51. if key in mote:
  52. data[curr_combination].append(mote[key])
  53. # plot
  54. try:
  55. if key in ['lifetime_AA_years', 'latencies']:
  56. plot_cdf(data, key, subfolder)
  57. else:
  58. plot_box(data, key, subfolder)
  59. except TypeError as e:
  60. print("Cannot create a plot for {0}: {1}.".format(key, e))
  61. print("Plots are saved in the {0} folder.".format(subfolder))
  62. # =========================== helpers =========================================
  63. def plot_cdf(data, key, subfolder):
  64. for k, values in data.items():
  65. # convert list of list to list
  66. if type(values[0]) == list:
  67. values = sum(values, [])
  68. values = [None if value == 'N/A' else value for value in values]
  69. # compute CDF
  70. sorted_data = np.sort(values)
  71. yvals = np.arange(len(sorted_data)) / float(len(sorted_data) - 1)
  72. plt.plot(sorted_data, yvals, label=k)
  73. plt.xlabel(key)
  74. plt.ylabel("CDF")
  75. plt.legend()
  76. savefig(subfolder, key + ".cdf")
  77. plt.clf()
  78. def plot_box(data, key, subfolder):
  79. plt.boxplot(list(data.values()))
  80. plt.xticks(list(range(1, len(data) + 1)), list(data.keys()))
  81. plt.ylabel(key)
  82. savefig(subfolder, key)
  83. plt.clf()
  84. def savefig(output_folder, output_name, output_format="png"):
  85. # check if output folder exists and create it if not
  86. if not os.path.isdir(output_folder):
  87. os.makedirs(output_folder)
  88. # save the figure
  89. plt.savefig(
  90. os.path.join(output_folder, output_name + "." + output_format),
  91. bbox_inches = 'tight',
  92. pad_inches = 0,
  93. format = output_format,
  94. )
  95. def parse_args():
  96. # parse options
  97. parser = argparse.ArgumentParser()
  98. parser.add_argument(
  99. '--inputfolder',
  100. help = 'The simulation result folder.',
  101. default = 'simData',
  102. )
  103. parser.add_argument(
  104. '-k','--kpis',
  105. help = 'The kpis to plot',
  106. type = list,
  107. default = KPIS
  108. )
  109. parser.add_argument(
  110. '--xlabel',
  111. help = 'The x-axis label',
  112. type = str,
  113. default = None,
  114. )
  115. parser.add_argument(
  116. '--ylabel',
  117. help = 'The y-axis label',
  118. type = str,
  119. default = None,
  120. )
  121. parser.add_argument(
  122. '--show',
  123. help = 'Show the plots.',
  124. action = 'store_true',
  125. default = None,
  126. )
  127. return parser.parse_args()
  128. if __name__ == '__main__':
  129. options = parse_args()
  130. main(options)