make_graphs.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  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: "no"',
  24. "marker": '*',
  25. "color": "blue"
  26. }
  27. },
  28. "numServers": {
  29. 2: {
  30. "legend": "2 servers",
  31. "marker": '^',
  32. "color": "red"
  33. },
  34. 3: {
  35. "legend": "3 servers",
  36. "marker": 'X',
  37. "color": "blue"
  38. },
  39. 3.5: {
  40. "legend": "3 servers / 3 * 2",
  41. "marker": '.',
  42. "color": "magenta"
  43. },
  44. 4: {
  45. "legend": "4 servers",
  46. "marker": '*',
  47. "color": "green"
  48. },
  49. 5: {
  50. "legend": "5 servers",
  51. "marker": 'h',
  52. "color": "orange"
  53. }
  54. },
  55. "numClients": {
  56. 5: {
  57. "legend": "5 clients",
  58. "marker": "^",
  59. "color": "red"
  60. },
  61. 10: {
  62. "legend": "10 clients",
  63. "marker": "v",
  64. "color": "green"
  65. },
  66. 15: {
  67. "legend": "15 clients",
  68. "marker": ">",
  69. "color": "blue"
  70. },
  71. 20: {
  72. "legend": "20 clients",
  73. "marker": "<",
  74. "color": "orange"
  75. },
  76. 25: {
  77. "legend": "25 clients",
  78. "marker": "X",
  79. "color": "magenta"
  80. },
  81. 30: {
  82. "legend": "30 clients",
  83. "marker": "*",
  84. "color": "pink"
  85. },
  86. 40: {
  87. "legend": "40 clients",
  88. "marker": "h",
  89. "color": "cyan"
  90. },
  91. 50: {
  92. "legend": "50 clients",
  93. "marker": ".",
  94. "color": "black"
  95. }
  96. },
  97. "lambda": {
  98. 40: {
  99. "legend": "Lambda: 40",
  100. "marker": "^",
  101. "color": "red"
  102. },
  103. 50: {
  104. "legend": "Lambda: 50",
  105. "marker": "X",
  106. "color": "green"
  107. },
  108. 64: {
  109. "legend": "Lambda: 64",
  110. "marker": "*",
  111. "color": "blue"
  112. }
  113. }
  114. }
  115. ##
  116. # This functionality allows us to temporarily change our working directory
  117. #
  118. # @input newdir - the new directory (relative to our current position) we want to be in
  119. @contextmanager
  120. def cd(newdir, makenew):
  121. prevdir = os.getcwd()
  122. directory = os.path.expanduser(newdir)
  123. if not os.path.exists(directory) and makenew:
  124. os.makedirs(directory)
  125. os.chdir(directory)
  126. try:
  127. yield
  128. finally:
  129. os.chdir(prevdir)
  130. def genericCube(x, a, b, c, d):
  131. return a * (x * x * x) + b * (x * x) + c * x + d
  132. def readData(dataDirectory):
  133. serverData = {}
  134. clientData = {}
  135. realDirectory = os.path.expanduser(dataDirectory)
  136. for test in os.listdir(realDirectory):
  137. if not test.startswith('.') and not test.endswith('.tar.gz') and test.find("default") == -1:
  138. testParts = test.split("-")
  139. if not testParts[0] in serverData:
  140. serverData[testParts[0]] = {}
  141. if not testParts[0] in clientData:
  142. clientData[testParts[0]] = {}
  143. if not testParts[1] in serverData[testParts[0]]:
  144. serverData[testParts[0]][testParts[1]] = {}
  145. if not testParts[1] in clientData[testParts[0]]:
  146. clientData[testParts[0]][testParts[1]] = {}
  147. if not testParts[2] in serverData[testParts[0]][testParts[1]]:
  148. serverData[testParts[0]][testParts[1]][testParts[2]] = {}
  149. if not testParts[2] in clientData[testParts[0]][testParts[1]]:
  150. clientData[testParts[0]][testParts[1]][testParts[2]] = {}
  151. if not testParts[3] in serverData[testParts[0]][testParts[1]][testParts[2]]:
  152. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]] = {}
  153. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_wall'] = []
  154. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_cpu'] = []
  155. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_recv'] = []
  156. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_sent'] = []
  157. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_total'] = []
  158. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_wall'] = []
  159. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_cpu'] = []
  160. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_recv'] = []
  161. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_sent'] = []
  162. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_total'] = []
  163. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_wall'] = []
  164. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_cpu'] = []
  165. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_recv'] = []
  166. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_sent'] = []
  167. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_total'] = []
  168. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_wall'] = []
  169. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_cpu'] = []
  170. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_recv'] = []
  171. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_sent'] = []
  172. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_total'] = []
  173. if not testParts[3] in clientData[testParts[0]][testParts[1]][testParts[2]]:
  174. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]] = {}
  175. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_wall'] = []
  176. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_cpu'] = []
  177. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_recv'] = []
  178. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_sent'] = []
  179. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_total'] = []
  180. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_wall'] = []
  181. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_cpu'] = []
  182. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_recv'] = []
  183. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_sent'] = []
  184. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_total'] = []
  185. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_wall'] = []
  186. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_cpu'] = []
  187. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_recv'] = []
  188. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_sent'] = []
  189. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_total'] = []
  190. for test in os.listdir(realDirectory):
  191. if not test.startswith('.') and not test.endswith('.tar.gz') and test.find("default") == -1:
  192. testParts = test.split("-")
  193. for whichEntity in os.listdir(os.path.join(realDirectory, test)):
  194. if whichEntity.startswith('s') or whichEntity.startswith('d'):
  195. try:
  196. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'overallEpoch.out')), 'r') as overallEpochFile:
  197. for line in overallEpochFile:
  198. lineParts = line.rstrip().split(',')
  199. wallTime = float(lineParts[0])
  200. cpuTime = float(lineParts[1])
  201. dataRecv = float(lineParts[2])
  202. dataSent = float(lineParts[3])
  203. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_wall'].append(wallTime)
  204. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_cpu'].append(cpuTime)
  205. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_recv'].append(dataRecv)
  206. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_sent'].append(dataSent)
  207. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['overall_epoch_total'].append(dataRecv + dataSent)
  208. except FileNotFoundError as e:
  209. pass
  210. try:
  211. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'epochUp.out')), 'r') as epochUpFile:
  212. for line in epochUpFile:
  213. lineParts = line.rstrip().split(',')
  214. wallTime = float(lineParts[0])
  215. cpuTime = float(lineParts[1])
  216. dataRecv = float(lineParts[2])
  217. dataSent = float(lineParts[3])
  218. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_wall'].append(wallTime)
  219. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_cpu'].append(cpuTime)
  220. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_recv'].append(dataRecv)
  221. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_sent'].append(dataSent)
  222. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_up_total'].append(dataRecv + dataSent)
  223. except FileNotFoundError as e:
  224. pass
  225. try:
  226. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'epochDown.out')), 'r') as epochDownFile:
  227. for line in epochDownFile:
  228. lineParts = line.rstrip().split(',')
  229. wallTime = float(lineParts[0])
  230. cpuTime = float(lineParts[1])
  231. dataRecv = float(lineParts[2])
  232. dataSent = float(lineParts[3])
  233. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_wall'].append(wallTime)
  234. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_cpu'].append(cpuTime)
  235. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_recv'].append(dataRecv)
  236. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_sent'].append(dataSent)
  237. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['epoch_down_total'].append(dataRecv + dataSent)
  238. except FileNotFoundError as e:
  239. pass
  240. try:
  241. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'voteUpdate.out')), 'r') as voteUpdateFile:
  242. for line in voteUpdateFile:
  243. lineParts = line.rstrip().split(',')
  244. wallTime = float(lineParts[0])
  245. cpuTime = float(lineParts[1])
  246. dataRecv = float(lineParts[2])
  247. dataSent = float(lineParts[3])
  248. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_wall'].append(wallTime)
  249. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_cpu'].append(cpuTime)
  250. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_recv'].append(dataRecv)
  251. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_sent'].append(dataSent)
  252. serverData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_update_total'].append(dataRecv + dataSent)
  253. except FileNotFoundError as e:
  254. pass
  255. elif whichEntity.startswith('c'):
  256. try:
  257. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'vote.out')), 'r') as repVerifierFile:
  258. for line in repVerifierFile:
  259. lineParts = line.rstrip().split(',')
  260. wallTime = float(lineParts[0])
  261. cpuTime = float(lineParts[1])
  262. dataRecv = float(lineParts[2])
  263. dataSent = float(lineParts[3])
  264. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_wall'].append(wallTime)
  265. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_cpu'].append(cpuTime)
  266. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_recv'].append(dataRecv)
  267. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_sent'].append(dataSent)
  268. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['vote_total'].append(dataRecv + dataSent)
  269. except FileNotFoundError as e:
  270. pass
  271. try:
  272. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'repProver.out')), 'r') as repProverFile:
  273. for line in repProverFile:
  274. lineParts = line.rstrip().split(',')
  275. wallTime = float(lineParts[0])
  276. cpuTime = float(lineParts[1])
  277. dataRecv = float(lineParts[2])
  278. dataSent = float(lineParts[3])
  279. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_wall'].append(wallTime)
  280. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_cpu'].append(cpuTime)
  281. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_recv'].append(dataRecv)
  282. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_sent'].append(dataSent)
  283. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_prove_total'].append(dataRecv + dataSent)
  284. except FileNotFoundError as e:
  285. pass
  286. try:
  287. with open(os.path.expanduser(os.path.join(realDirectory, test, whichEntity, 'repVerifier.out')), 'r') as repVerifierFile:
  288. for line in repVerifierFile:
  289. lineParts = line.rstrip().split(',')
  290. wallTime = float(lineParts[0])
  291. cpuTime = float(lineParts[1])
  292. dataRecv = float(lineParts[2])
  293. dataSent = float(lineParts[3])
  294. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_wall'].append(wallTime)
  295. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_cpu'].append(cpuTime)
  296. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_recv'].append(dataRecv)
  297. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_sent'].append(dataSent)
  298. clientData[testParts[0]][testParts[1]][testParts[2]][testParts[3]]['rep_verify_total'].append(dataRecv + dataSent)
  299. except FileNotFoundError as e:
  300. pass
  301. return serverData, clientData
  302. def plotComparison(data, dataParts, xVariable, lineVariable, whichGraph, **kwargs):
  303. z_star = kwargs['z_star'] if 'z_star' in kwargs else 1.96
  304. title = kwargs['title'] if 'title' in kwargs else ''
  305. xLabel = kwargs['xLabel'] if 'xLabel' in kwargs else ''
  306. yLabel = kwargs['yLabel'] if 'yLabel' in kwargs else ''
  307. fileNameStr = kwargs['fileNameStr'] if 'fileNameStr' in kwargs else f"basic-{xVariable}-{lineVariable}-{whichGraph}"
  308. legendLoc = kwargs['legendLoc'] if 'legendLoc' in kwargs else "best"
  309. legendBBoxAnchor = kwargs['legendBBoxAnchor'] if 'legendBBoxAnchor' in kwargs else (0, 1)
  310. extraFit = kwargs['extraFit'] if 'extraFit' in kwargs else False
  311. loglog = kwargs['loglog'] if 'loglog' in kwargs else True
  312. yLim = kwargs['yLim'] if 'yLim' in kwargs else False
  313. aspect = kwargs['aspect'] if 'aspect' in kwargs else None
  314. fig = plt.figure()
  315. ax = fig.gca()
  316. whichLines = 0
  317. lineSelection = []
  318. legendStart = ""
  319. legendEnd = ""
  320. if lineVariable == 'workload':
  321. whichLines = 0
  322. lineSelection = [str(x) for x in data.keys() if x != "rep" and x != "vote"]
  323. lineSelection.sort()
  324. elif lineVariable == 'numServers':
  325. whichLines = 1
  326. lineSelection = [int(x) for x in data['all'].keys()]
  327. lineSelection.sort()
  328. elif lineVariable == 'numClients':
  329. whichLines = 2
  330. lineSelection = [int(x) for x in data['all']['2'].keys()]
  331. lineSelection.sort()
  332. elif lineVariable == 'lambda':
  333. whichLines = 3
  334. lineSelection = [int(x) for x in data['all']['2']['5'].keys()]
  335. lineSelection.sort()
  336. whichX = 0
  337. xSelection = []
  338. if xVariable == 'workload':
  339. whichX = 0
  340. xSelection = data.keys()
  341. elif xVariable == 'numServers':
  342. whichX = 1
  343. xSelection = [int(x) for x in data['all'].keys()]
  344. xSelection.sort()
  345. elif xVariable == 'numClients':
  346. whichX = 2
  347. xSelection = [int(x) for x in data['all']['2'].keys()]
  348. xSelection.sort()
  349. elif xVariable == 'lambda':
  350. whichX = 3
  351. xSelection = [int(x) for x in data['all']['2']['5'].keys()]
  352. xSelection.sort()
  353. for selection in lineSelection:
  354. xs = []
  355. xTicks = []
  356. ys = []
  357. additionalYs = []
  358. yErrs = []
  359. additionalYErrs = []
  360. legend = PLOT_OPTIONS[lineVariable][selection]['legend']
  361. marker = PLOT_OPTIONS[lineVariable][selection]['marker']
  362. color = PLOT_OPTIONS[lineVariable][selection]['color']
  363. dataParts[whichLines] = str(selection)
  364. for x in xSelection:
  365. dataParts[whichX] = str(x)
  366. try:
  367. curr_data = data[dataParts[0]][dataParts[1]][dataParts[2]][dataParts[3]][whichGraph]
  368. if len(curr_data) == 0:
  369. continue
  370. mean = np.mean(curr_data)
  371. std = np.std(curr_data)
  372. sqrt_len = sqrt(len(curr_data))
  373. xs.append(x)
  374. ys.append(mean)
  375. yErrs.append(z_star * std / sqrt_len)
  376. if lineVariable == 'numServers' and selection > 2:
  377. additional_data = [x / selection * 2 for x in curr_data]
  378. additional_mean = np.mean(additional_data)
  379. additional_std = np.std(additional_data)
  380. additionalYs.append(additional_mean)
  381. additionalYErrs.append(z_star * additional_std / sqrt_len)
  382. except KeyError as e:
  383. pass
  384. if len(xs) > 1:
  385. line, _, _ = ax.errorbar(xs, ys, yerr=yErrs, capsize=7.0, label=legend, marker=marker, linestyle='-', color=color)
  386. if lineVariable == 'numServers' and selection > 2:
  387. addlLegend = PLOT_OPTIONS[lineVariable][selection + 0.5]['legend']
  388. addlMarker = PLOT_OPTIONS[lineVariable][selection + 0.5]['marker']
  389. addlColor = PLOT_OPTIONS[lineVariable][selection + 0.5]['color']
  390. line, _, _ = ax.errorbar(xs, additionalYs, yerr=additionalYErrs, capsize=7.0, label=addlLegend, marker=addlMarker, linestyle='-', color=addlColor)
  391. if extraFit:
  392. popt, pcov = curve_fit(genericCube, xs, ys)
  393. beyondXs = np.linspace(xs[-1], 100, 50)
  394. ax.plot(beyondXs, genericCube(beyondXs, *popt), linestyle='--', color=color)
  395. ax.set_title(title, fontsize='x-large')
  396. ax.set_xlabel(xLabel, fontsize='large')
  397. ax.set_ylabel(yLabel, fontsize='large')
  398. bottom, top = ax.get_ylim()
  399. bottom = (0 if bottom > 0 else bottom)
  400. ax.set_ylim(bottom=bottom)
  401. if top > 100000:
  402. yTickLabels = ['{:2g}'.format(x) for x in ax.get_yticks().tolist()]
  403. ax.set_yticklabels(yTickLabels)
  404. if yLim:
  405. ax.set_ylim(bottom=yLim[0], top=yLim[1])
  406. if aspect:
  407. ax.set_aspect(aspect, adjustable='box')
  408. legend = ax.legend(loc=legendLoc, bbox_to_anchor=legendBBoxAnchor, fontsize='large')
  409. with cd('../plt/', True):
  410. fig.savefig(f"{fileNameStr}.pdf", bbox_inches='tight')
  411. plt.close(fig)
  412. def main(dataDirectory, plotOptionsFile):
  413. serverData, clientData = readData(dataDirectory)
  414. plotOptions = []
  415. with open(plotOptionsFile, 'r') as options:
  416. plotOptions = json.load(options)
  417. for option in plotOptions:
  418. try:
  419. data = serverData if (option['data'].lower() == "server" or option['data'].lower() == "s") else clientData
  420. dataParts = option['dataParts']
  421. xVariable = option['xVariable']
  422. lineVariable = option['lineVariable']
  423. whichGraph = option['whichGraph']
  424. except KeyError as e:
  425. continue
  426. kwargs = {}
  427. if "z_star" in option:
  428. kwargs["z_star"] = option["z_star"]
  429. if "title" in option:
  430. kwargs["title"] = option["title"]
  431. if "xLabel" in option:
  432. kwargs["xLabel"] = option["xLabel"]
  433. if "yLabel" in option:
  434. kwargs["yLabel"] = option["yLabel"]
  435. if "extraFit" in option:
  436. kwargs["extraFit"] = option["extraFit"]
  437. if "fileNameStr" in option:
  438. kwargs["fileNameStr"] = option["fileNameStr"]
  439. if "legendLoc" in option:
  440. kwargs["legendLoc"] = option["legendLoc"]
  441. if "legendBBoxAnchor" in option:
  442. anchor = (option["legendBBoxAnchor"][0], option["legendBBoxAnchor"][1])
  443. kwargs["legendBBoxAnchor"] = anchor
  444. if "loglog" in option:
  445. kwargs["loglog"] = option["loglog"]
  446. if "yLim" in option:
  447. kwargs["yLim"] = option["yLim"]
  448. if "aspect" in option:
  449. kwargs["aspect"] = option["aspect"]
  450. plotComparison(data, dataParts, xVariable, lineVariable, whichGraph, **kwargs)
  451. if __name__ == "__main__":
  452. main("../out", "../plt/plots.json")