make_graphs.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. #!/usr/bin/env python3
  2. import os
  3. import sys
  4. import json
  5. from math import sqrt
  6. import numpy as np
  7. import matplotlib.pyplot as plt
  8. from scipy.optimize import curve_fit
  9. from contextlib import contextmanager
  10. PLOT_OPTIONS = {
  11. "workload": {
  12. "all": {
  13. "legend": 'Workload: "all"',
  14. "marker": '^',
  15. "color": "red"
  16. },
  17. "half": {
  18. "legend": 'Workload: "half"',
  19. "marker": 'X',
  20. "color": "green"
  21. },
  22. "no": {
  23. "legend": 'Workload: "none"',
  24. "marker": '*',
  25. "color": "blue"
  26. },
  27. "hbcall": {
  28. "legend": 'Workload: "all"',
  29. "marker": '^',
  30. "color": "red"
  31. },
  32. "hbchalf": {
  33. "legend": 'Workload: "half"',
  34. "marker": 'X',
  35. "color": "green"
  36. },
  37. "hbcno": {
  38. "legend": 'Workload: "none"',
  39. "marker": '*',
  40. "color": "blue"
  41. }
  42. },
  43. "numServers": {
  44. 2: {
  45. "legend": "2 servers",
  46. "marker": '^',
  47. "color": "red"
  48. },
  49. 3: {
  50. "legend": "3 servers",
  51. "marker": 'X',
  52. "color": "blue"
  53. },
  54. 4: {
  55. "legend": "4 servers",
  56. "marker": '*',
  57. "color": "green"
  58. },
  59. 5: {
  60. "legend": "5 servers",
  61. "marker": 'h',
  62. "color": "orange"
  63. }
  64. },
  65. "numClients": {
  66. 5: {
  67. "legend": "5 clients",
  68. "marker": "^",
  69. "color": "red"
  70. },
  71. 10: {
  72. "legend": "10 clients",
  73. "marker": "v",
  74. "color": "green"
  75. },
  76. 15: {
  77. "legend": "15 clients",
  78. "marker": ">",
  79. "color": "blue"
  80. },
  81. 20: {
  82. "legend": "20 clients",
  83. "marker": "<",
  84. "color": "orange"
  85. },
  86. 25: {
  87. "legend": "25 clients",
  88. "marker": "X",
  89. "color": "magenta"
  90. },
  91. 30: {
  92. "legend": "30 clients",
  93. "marker": "*",
  94. "color": "pink"
  95. },
  96. 40: {
  97. "legend": "40 clients",
  98. "marker": "h",
  99. "color": "cyan"
  100. },
  101. 50: {
  102. "legend": "50 clients",
  103. "marker": ".",
  104. "color": "black"
  105. }
  106. },
  107. "lambda": {
  108. 40: {
  109. "legend": "Lambda: 40",
  110. "marker": "^",
  111. "color": "red"
  112. },
  113. 50: {
  114. "legend": "Lambda: 50",
  115. "marker": "X",
  116. "color": "green"
  117. },
  118. 64: {
  119. "legend": "Lambda: 64",
  120. "marker": "*",
  121. "color": "blue"
  122. }
  123. }
  124. }
  125. LOGLOG_FIT_OPTIONS = {
  126. "workload": {
  127. "overall_epoch_cpu": {
  128. "0": 64,
  129. "50": 32
  130. },
  131. "overall_epoch_total": {
  132. "0": 256,
  133. "50": 256
  134. }
  135. },
  136. "lambda": {
  137. "overall_epoch_cpu": 32,
  138. "overall_epoch_total": 256
  139. },
  140. "numServers": {
  141. "overall_epoch_cpu": 32,
  142. "overall_epoch_total": 128
  143. }
  144. }
  145. def SetPlotRC():
  146. #If fonttype = 1 doesn't work with LaTeX, try fonttype 42.
  147. plt.rc('pdf',fonttype = 42)
  148. plt.rc('ps',fonttype = 42)
  149. def ApplyFont(ax):
  150. ticks = ax.get_xticklabels() + ax.get_yticklabels()
  151. text_size = 14.0
  152. for t in ticks:
  153. t.set_fontname('Times New Roman')
  154. t.set_fontsize(text_size)
  155. txt = ax.get_xlabel()
  156. txt_obj = ax.set_xlabel(txt)
  157. txt_obj.set_fontname('Times New Roman')
  158. txt_obj.set_fontsize(text_size)
  159. txt = ax.get_ylabel()
  160. txt_obj = ax.set_ylabel(txt)
  161. txt_obj.set_fontname('Times New Roman')
  162. txt_obj.set_fontsize(text_size)
  163. txt = ax.get_title()
  164. txt_obj = ax.set_title(txt)
  165. txt_obj.set_fontname('Times New Roman')
  166. txt_obj.set_fontsize(text_size)
  167. ##
  168. # This functionality allows us to temporarily change our working directory
  169. #
  170. # @input newdir - the new directory (relative to our current position) we want to be in
  171. @contextmanager
  172. def cd(newdir, makenew):
  173. prevdir = os.getcwd()
  174. directory = os.path.expanduser(newdir)
  175. if not os.path.exists(directory) and makenew:
  176. os.makedirs(directory)
  177. os.chdir(directory)
  178. try:
  179. yield
  180. finally:
  181. os.chdir(prevdir)
  182. def genericCube(x, a, b, c, d):
  183. return a * (x * x * x) + b * (x * x) + c * x + d
  184. def onlyCube(x, a):
  185. return a * (x * x * x)
  186. def onlySquare(x, a):
  187. return a * (x * x)
  188. def readData(dataDirectory):
  189. serverData = {}
  190. clientData = {}
  191. realDirectory = os.path.expanduser(dataDirectory)
  192. for test in os.listdir(realDirectory):
  193. if not test.startswith('.') and not test.endswith('.tar.gz') and test.find("default") == -1:
  194. testParts = test.split("-")
  195. if not testParts[0] in serverData:
  196. serverData[testParts[0]] = {}
  197. if not testParts[0] in clientData:
  198. clientData[testParts[0]] = {}
  199. if not testParts[1] in serverData[testParts[0]]:
  200. serverData[testParts[0]][testParts[1]] = {}
  201. if not testParts[1] in clientData[testParts[0]]:
  202. clientData[testParts[0]][testParts[1]] = {}
  203. if not testParts[2] in serverData[testParts[0]][testParts[1]]:
  204. serverData[testParts[0]][testParts[1]][testParts[2]] = {}
  205. if not testParts[2] in clientData[testParts[0]][testParts[1]]:
  206. clientData[testParts[0]][testParts[1]][testParts[2]] = {}
  207. if not testParts[3] in serverData[testParts[0]][testParts[1]][testParts[2]]:
  208. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]] = {}
  209. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_wall'] = []
  210. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_cpu'] = []
  211. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_recv'] = []
  212. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_sent'] = []
  213. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_total'] = []
  214. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_wall'] = []
  215. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_cpu'] = []
  216. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_recv'] = []
  217. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_sent'] = []
  218. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_total'] = []
  219. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_wall'] = []
  220. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_cpu'] = []
  221. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_recv'] = []
  222. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_sent'] = []
  223. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_total'] = []
  224. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_wall'] = []
  225. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_cpu'] = []
  226. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_recv'] = []
  227. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_sent'] = []
  228. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_total'] = []
  229. if not testParts[3] in clientData[testParts[0]][testParts[1]][testParts[2]]:
  230. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]] = {}
  231. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_wall'] = []
  232. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_cpu'] = []
  233. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_recv'] = []
  234. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_sent'] = []
  235. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_total'] = []
  236. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_wall'] = []
  237. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_cpu'] = []
  238. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_recv'] = []
  239. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_sent'] = []
  240. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_total'] = []
  241. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_wall'] = []
  242. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_cpu'] = []
  243. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_recv'] = []
  244. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_sent'] = []
  245. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_total'] = []
  246. for test in os.listdir(realDirectory):
  247. if not test.startswith('.') and not test.endswith('.tar.gz') and test.find("default") == -1:
  248. testParts = test.split("-")
  249. for whichEntity in os.listdir(os.path.join(realDirectory, test)):
  250. if whichEntity.startswith('s') or whichEntity.startswith('d'):
  251. try:
  252. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'overallEpoch.out')), 'r') as overallEpochFile:
  253. for line in overallEpochFile:
  254. lineParts = line.rstrip().split(',')
  255. wallTime = float(lineParts[0])
  256. cpuTime = float(lineParts[1])
  257. dataRecv = float(lineParts[2])
  258. dataSent = float(lineParts[3])
  259. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_wall'].append(wallTime)
  260. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_cpu'].append(cpuTime)
  261. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_recv'].append(dataRecv)
  262. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_sent'].append(dataSent)
  263. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_total'].append(dataRecv + dataSent)
  264. except FileNotFoundError as e:
  265. pass
  266. try:
  267. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'epochUp.out')), 'r') as epochUpFile:
  268. for line in epochUpFile:
  269. lineParts = line.rstrip().split(',')
  270. wallTime = float(lineParts[0])
  271. cpuTime = float(lineParts[1])
  272. dataRecv = float(lineParts[2])
  273. dataSent = float(lineParts[3])
  274. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_wall'].append(wallTime)
  275. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_cpu'].append(cpuTime)
  276. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_recv'].append(dataRecv)
  277. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_sent'].append(dataSent)
  278. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_total'].append(dataRecv + dataSent)
  279. except FileNotFoundError as e:
  280. pass
  281. try:
  282. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'epochDown.out')), 'r') as epochDownFile:
  283. for line in epochDownFile:
  284. lineParts = line.rstrip().split(',')
  285. wallTime = float(lineParts[0])
  286. cpuTime = float(lineParts[1])
  287. dataRecv = float(lineParts[2])
  288. dataSent = float(lineParts[3])
  289. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_wall'].append(wallTime)
  290. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_cpu'].append(cpuTime)
  291. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_recv'].append(dataRecv)
  292. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_sent'].append(dataSent)
  293. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_total'].append(dataRecv + dataSent)
  294. except FileNotFoundError as e:
  295. pass
  296. try:
  297. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'voteUpdate.out')), 'r') as voteUpdateFile:
  298. for line in voteUpdateFile:
  299. lineParts = line.rstrip().split(',')
  300. wallTime = float(lineParts[0])
  301. cpuTime = float(lineParts[1])
  302. dataRecv = float(lineParts[2])
  303. dataSent = float(lineParts[3])
  304. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_wall'].append(wallTime)
  305. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_cpu'].append(cpuTime)
  306. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_recv'].append(dataRecv)
  307. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_sent'].append(dataSent)
  308. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_total'].append(dataRecv + dataSent)
  309. except FileNotFoundError as e:
  310. pass
  311. elif whichEntity.startswith('c'):
  312. try:
  313. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'vote.out')), 'r') as repVerifierFile:
  314. for line in repVerifierFile:
  315. lineParts = line.rstrip().split(',')
  316. wallTime = float(lineParts[0])
  317. cpuTime = float(lineParts[1])
  318. dataRecv = float(lineParts[2])
  319. dataSent = float(lineParts[3])
  320. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_wall'].append(wallTime)
  321. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_cpu'].append(cpuTime)
  322. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_recv'].append(dataRecv)
  323. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_sent'].append(dataSent)
  324. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_total'].append(dataRecv + dataSent)
  325. except FileNotFoundError as e:
  326. pass
  327. try:
  328. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'repProver.out')), 'r') as repProverFile:
  329. for line in repProverFile:
  330. lineParts = line.rstrip().split(',')
  331. if not ('*' in lineParts[0]):
  332. wallTime = float(lineParts[0])
  333. cpuTime = float(lineParts[1])
  334. dataRecv = float(lineParts[2])
  335. dataSent = float(lineParts[3])
  336. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_wall'].append(wallTime)
  337. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_cpu'].append(cpuTime)
  338. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_recv'].append(dataRecv)
  339. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_sent'].append(dataSent)
  340. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_total'].append(dataRecv + dataSent)
  341. except FileNotFoundError as e:
  342. pass
  343. try:
  344. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'repVerifier.out')), 'r') as repVerifierFile:
  345. for line in repVerifierFile:
  346. lineParts = line.rstrip().split(',')
  347. wallTime = float(lineParts[0])
  348. cpuTime = float(lineParts[1])
  349. dataRecv = float(lineParts[2])
  350. dataSent = float(lineParts[3])
  351. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_wall'].append(wallTime)
  352. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_cpu'].append(cpuTime)
  353. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_recv'].append(dataRecv)
  354. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_sent'].append(dataSent)
  355. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_total'].append(dataRecv + dataSent)
  356. except FileNotFoundError as e:
  357. pass
  358. return serverData, clientData
  359. def plotComparison(data, dataParts, xVariable, lineVariable, whichGraph, **kwargs):
  360. z_star = kwargs['z_star'] if 'z_star' in kwargs else 1.96
  361. title = kwargs['title'] if 'title' in kwargs else ''
  362. xLabel = kwargs['xLabel'] if 'xLabel' in kwargs else ''
  363. yLabel = kwargs['yLabel'] if 'yLabel' in kwargs else ''
  364. yUnit = kwargs['yUnit'] if 'yUnit' in kwargs else ''
  365. fileNameStr = kwargs['fileNameStr'] if 'fileNameStr' in kwargs else f"basic-{xVariable}-{lineVariable}-{whichGraph}"
  366. legendLoc = kwargs['legendLoc'] if 'legendLoc' in kwargs else "best"
  367. legendBBoxAnchor = kwargs['legendBBoxAnchor'] if 'legendBBoxAnchor' in kwargs else (0, 1)
  368. extraFit = kwargs['extraFit'] if 'extraFit' in kwargs else False
  369. loglog = kwargs['loglog'] if 'loglog' in kwargs else False
  370. loglinear = kwargs['loglinear'] if 'loglinear' in kwargs else False
  371. yLim = kwargs['yLim'] if 'yLim' in kwargs else False
  372. aspect = kwargs['aspect'] if 'aspect' in kwargs else None
  373. ignoreWorkload = kwargs['ignoreWorkload'] if 'ignoreWorkload' in kwargs else False
  374. SetPlotRC()
  375. fig = plt.figure()
  376. ax = fig.gca()
  377. whichLines = 0
  378. lineSelection = []
  379. legendStart = ""
  380. legendEnd = ""
  381. if lineVariable == 'workload':
  382. whichLines = 0
  383. lineSelection = [str(x) for x in data.keys() if x != "rep" and x != "vote"]
  384. lineSelection.sort()
  385. ignoreWorkload = False
  386. elif lineVariable == 'numServers':
  387. whichLines = 1
  388. lineSelection = [int(x) for x in data['all'].keys()]
  389. lineSelection.sort()
  390. elif lineVariable == 'numClients':
  391. whichLines = 2
  392. lineSelection = [int(x) for x in data['all']['2'].keys()]
  393. lineSelection.sort()
  394. elif lineVariable == 'lambda':
  395. whichLines = 3
  396. if dataParts[3] == "":
  397. lineSelection = [int(x) for x in data['all']['2']['5'].keys()]
  398. lineSelection.sort()
  399. else:
  400. lineSelection = [int(dataParts[3])]
  401. lineSelection.sort()
  402. whichX = 0
  403. xSelection = []
  404. if xVariable == 'workload':
  405. whichX = 0
  406. xSelection = data.keys()
  407. ignoreWorkload = False
  408. elif xVariable == 'numServers':
  409. whichX = 1
  410. xSelection = [int(x) for x in data['all'].keys()]
  411. xSelection.sort()
  412. elif xVariable == 'numClients':
  413. whichX = 2
  414. xSelection = [int(x) for x in data['all']['2'].keys()]
  415. xSelection.sort()
  416. elif xVariable == 'lambda':
  417. whichX = 3
  418. xSelection = [int(x) for x in data['all']['2']['5'].keys()]
  419. xSelection.sort()
  420. loglogLineFit = False
  421. for selection in lineSelection:
  422. xs = []
  423. xTicks = []
  424. ys = []
  425. additionalYs = []
  426. yErrs = []
  427. additionalYErrs = []
  428. legend = PLOT_OPTIONS[lineVariable][selection]['legend']
  429. marker = PLOT_OPTIONS[lineVariable][selection]['marker']
  430. color = PLOT_OPTIONS[lineVariable][selection]['color']
  431. dataParts[whichLines] = str(selection)
  432. for x in xSelection:
  433. dataParts[whichX] = str(x)
  434. try:
  435. curr_data = []
  436. if ignoreWorkload == False:
  437. curr_data = data[dataParts[0]][dataParts[1]][dataParts[2]][dataParts[3]][whichGraph]
  438. else:
  439. for workload in ['all', 'half', 'no']:
  440. try:
  441. curr_data.extend(data[workload][dataParts[1]][dataParts[2]][dataParts[3]][whichGraph])
  442. except KeyError as e:
  443. pass
  444. if len(curr_data) == 0:
  445. continue
  446. dividing_factor = 1
  447. if yUnit == 'KB':
  448. dividing_factor = 1024.0
  449. if yUnit == 'MB':
  450. dividing_factor = 1024.0 * 1024.0
  451. if lineVariable == 'numServers':
  452. dividing_factor = dividing_factor * selection
  453. else:
  454. dividing_factor = dividing_factor * int(dataParts[1])
  455. used_data = [x / dividing_factor for x in curr_data]
  456. mean = np.mean(used_data)
  457. std = np.std(used_data)
  458. sqrt_len = sqrt(len(used_data))
  459. xs.append(x)
  460. ys.append(mean)
  461. yErrs.append(z_star * std / sqrt_len)
  462. except KeyError as e:
  463. pass
  464. if len(xs) > 1:
  465. line, _, _ = ax.errorbar(xs, ys, yerr=yErrs, capsize=7.0, label=legend, marker=marker, linestyle='-', color=color)
  466. if extraFit:
  467. popt, pcov = curve_fit(genericCube, xs, ys)
  468. beyondXs = np.linspace(xs[-1], 300, 50)
  469. ax.plot(beyondXs, genericCube(beyondXs, *popt), linestyle='--', color=color)
  470. if loglog and not loglogLineFit and dataParts[3] != '0':
  471. popt, pcov = curve_fit(onlyCube, xs, ys)
  472. moreXs = np.linspace(5, 50, 45)
  473. labelString = "Line of best fit with slope = 3"
  474. ax.plot(moreXs, onlyCube(moreXs, *popt), label=labelString, color="black")
  475. loglogLineFit = True
  476. if loglog and not loglogLineFit and dataParts[3] == '0':
  477. popt, pcov = curve_fit(onlySquare, xs, ys)
  478. moreXs = np.linspace(5, 50, 45)
  479. labelString = "Line of best fit with slope = 2"
  480. ax.plot(moreXs, onlySquare(moreXs, *popt), label=labelString, color="black")
  481. loglogLineFit = True
  482. ax.set_title(title, fontsize='x-large')
  483. ax.set_xlabel(xLabel, fontsize='large')
  484. ax.set_ylabel(yLabel, fontsize='large')
  485. if loglog:
  486. ax.set_yscale("log")
  487. ax.set_xscale("log")
  488. ax.set_xticks([5, 10, 20, 30, 40, 50])
  489. ax.set_xticklabels(["5", "10", "20", "30", "40", "50"])
  490. if loglinear:
  491. ax.set_xscale("log")
  492. ax.set_xticks([5, 10, 20, 30, 40, 50])
  493. ax.set_xticklabels(["5", "10", "20", "30", "40", "50"])
  494. else:
  495. bottom, top = ax.get_ylim()
  496. bottom = (0 if bottom > 0 else bottom)
  497. ax.set_ylim(bottom=bottom)
  498. if top > 100000:
  499. yTickLabels = ['{:2g}'.format(x) for x in ax.get_yticks().tolist()]
  500. ax.set_yticklabels(yTickLabels)
  501. if yLim:
  502. ax.set_ylim(bottom=yLim[0], top=yLim[1])
  503. if aspect:
  504. ax.set_aspect(aspect, adjustable='box')
  505. legend = ax.legend(loc=legendLoc, bbox_to_anchor=legendBBoxAnchor, fontsize='large')
  506. ApplyFont(ax)
  507. with cd('../plt/', True):
  508. fig.savefig(f"{fileNameStr}.pdf", bbox_inches='tight')
  509. plt.close(fig)
  510. def main(dataDirectory, plotOptionsFile):
  511. serverData, clientData = readData(dataDirectory)
  512. plotOptions = []
  513. with open(plotOptionsFile, 'r') as options:
  514. plotOptions = json.load(options)
  515. for option in plotOptions:
  516. try:
  517. data = serverData if (option['data'].lower() == "server" or option['data'].lower() == "s") else clientData
  518. dataParts = option['dataParts']
  519. xVariable = option['xVariable']
  520. lineVariable = option['lineVariable']
  521. whichGraph = option['whichGraph']
  522. except KeyError as e:
  523. continue
  524. kwargs = {}
  525. if "z_star" in option:
  526. kwargs["z_star"] = option["z_star"]
  527. if "title" in option:
  528. kwargs["title"] = option["title"]
  529. if "xLabel" in option:
  530. kwargs["xLabel"] = option["xLabel"]
  531. if "yLabel" in option:
  532. kwargs["yLabel"] = option["yLabel"]
  533. if "yUnit" in option:
  534. kwargs["yUnit"] = option["yUnit"]
  535. if "extraFit" in option:
  536. kwargs["extraFit"] = option["extraFit"]
  537. if "fileNameStr" in option:
  538. kwargs["fileNameStr"] = option["fileNameStr"]
  539. if "legendLoc" in option:
  540. kwargs["legendLoc"] = option["legendLoc"]
  541. if "legendBBoxAnchor" in option:
  542. anchor = (option["legendBBoxAnchor"][0], option["legendBBoxAnchor"][1])
  543. kwargs["legendBBoxAnchor"] = anchor
  544. if "loglog" in option:
  545. kwargs["loglog"] = option["loglog"]
  546. if "loglinear" in option:
  547. kwargs["loglinear"] = option["loglinear"]
  548. if "yLim" in option:
  549. kwargs["yLim"] = option["yLim"]
  550. if "aspect" in option:
  551. kwargs["aspect"] = option["aspect"]
  552. if "ignoreWorkload" in option:
  553. kwargs["ignoreWorkload"] = option["ignoreWorkload"]
  554. plotComparison(data, dataParts, xVariable, lineVariable, whichGraph, **kwargs)
  555. if __name__ == "__main__":
  556. main("../out", "../plt/plots.json")