/ DAS / visualizor.py
visualizor.py
  1  #!/bin/python3
  2  
  3  import matplotlib.pyplot as plt
  4  import numpy as np
  5  import os
  6  
  7  def plotData(conf):
  8      plt.clf()
  9      fig = plt.figure("9, 3")
 10      if conf["desLoc"] == 1:
 11          xDes = 0
 12      else:
 13          xDes = conf["xdots"][-1] * 0.6
 14      props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
 15      plt.text(xDes, conf["yaxismax"]/4, conf["textBox"], fontsize=10, verticalalignment='top', bbox=props)
 16      for i in range(len(conf["data"])):
 17          if conf["type"] == "plot":
 18              plt.plot(conf["xdots"], conf["data"][i], conf["colors"][i], label=conf["labels"][i])
 19          if conf["type"] == "bar":
 20              plt.bar(conf["xdots"], conf["data"][i], label=conf["labels"][i])
 21      plt.title(conf["title"])
 22      plt.ylabel(conf["ylabel"])
 23      plt.xlabel(conf["xlabel"])
 24      plt.ylim(0, conf["yaxismax"]*1.1)
 25      plt.legend(loc=conf["legLoc"])
 26      plt.savefig(conf["path"], bbox_inches="tight")
 27  
 28  
 29  class Visualizor:
 30      """This class helps the visualization of the results"""
 31  
 32      def __init__(self, execID, config, results):
 33          """Initialize the visualizer module"""
 34          self.execID = execID
 35          self.config = config
 36          self.results = results
 37          os.makedirs("results/"+self.execID+"/plots", exist_ok=True)
 38      
 39      def __get_attrbs__(self, result):
 40          text = str(result.shape).split("-")
 41          d = dict()
 42          for i in range(0, len(text), 2):
 43              d[text[i]] = text[i + 1]
 44          return d
 45  
 46      def plotHeatmaps(self, x, y):
 47          """Plot the heatmap using the parameters given as x axis and y axis"""
 48          print("Plotting heatmap "+x+" vs "+y)
 49          #Find the location of x in shape
 50          #Find the location of y in shape
 51          #Find the location od r in shape
 52  
 53          #Loop over all results
 54              #Add unique values foir every parameter
 55  
 56          #Find number of runs from r
 57          #If number of values for x and y > 3 then plot heatmap, otherwise finish
 58  
 59          #Create a 2D grid with the dimensions of the number of values for x and y
 60          #For all values of x
 61              #For all values of y
 62                  # For all values in r
 63                      #Fixing all other values to 1 (in the mean time)
 64                      #Add/sum TTA into 2D grid
 65                      #if last r divide by number of runs
 66  
 67          #Plot 2D grid
 68  
 69  
 70  
 71  
 72      def plotAll(self):
 73          """Plot all the important elements of each result"""
 74          for result in self.results:
 75              plotPath = "results/"+self.execID+"/plots/"+str(result.shape)
 76              os.makedirs(plotPath, exist_ok=True)
 77              self.plotMissingSamples(result, plotPath)
 78              self.plotProgress(result, plotPath)
 79              self.plotSentData(result, plotPath)
 80              self.plotRecvData(result, plotPath)
 81              self.plotDupData(result, plotPath)
 82              if self.config.saveRCdist:
 83                  self.plotRowCol(result, plotPath)
 84  
 85      def plotMissingSamples(self, result, plotPath):
 86          """Plots the missing samples in the network"""
 87          conf = {}
 88          attrbs = self.__get_attrbs__(result)
 89          conf["textBox"] = "Block Size R: "+attrbs['bsrn']+"\nBlock Size C: "+attrbs['bscn']\
 90          +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+" \nNetwork degree: "+attrbs['nd']
 91          conf["title"] = "Missing Samples"
 92          conf["type"] = "plot"
 93          conf["legLoc"] = 1
 94          conf["desLoc"] = 1
 95          conf["colors"] = ["m-"]
 96          conf["labels"] = ["Missing Samples"]
 97          conf["xlabel"] = "Time (ms)"
 98          conf["ylabel"] = "Number of Missing Samples"
 99          conf["data"] = [result.missingVector]
100          conf["xdots"] = [x*self.config.stepDuration for x in range(len(result.missingVector))]
101          conf["path"] = plotPath+"/missingSamples.png"
102          maxi = 0
103          for v in conf["data"]:
104              if max(v) > maxi:
105                  maxi = max(v)
106          conf["yaxismax"] = maxi
107          plotData(conf)
108          print("Plot %s created." % conf["path"])
109  
110      def plotProgress(self, result, plotPath):
111          """Plots the percentage of nodes ready in the network"""
112          vector1 = result.metrics["progress"]["nodes ready"]
113          vector2 = result.metrics["progress"]["validators ready"]
114          vector3 = result.metrics["progress"]["samples received"]
115          conf = {}
116          attrbs = self.__get_attrbs__(result)
117          conf["textBox"] = "Block Size R: "+attrbs['bsrn']+"\nBlock Size C: "+attrbs['bscn']\
118          +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+" \nNetwork degree: "+attrbs['nd']
119          conf["title"] = "Nodes/validators ready"
120          conf["type"] = "plot"
121          conf["legLoc"] = 2
122          conf["desLoc"] = 2
123          conf["colors"] = ["g-", "b-", "r-"]
124          conf["labels"] = ["Nodes", "Validators", "Samples"]
125          conf["xlabel"] = "Time (ms)"
126          conf["ylabel"] = "Percentage (%)"
127          conf["data"] = [vector1, vector2, vector3]
128          conf["xdots"] = [x*self.config.stepDuration for x in range(len(vector1))]
129          conf["path"] = plotPath+"/nodesReady.png"
130          maxi = 0
131          for v in conf["data"]:
132              if max(v) > maxi:
133                  maxi = max(v)
134          conf["yaxismax"] = maxi
135          plotData(conf)
136          print("Plot %s created." % conf["path"])
137  
138      def plotSentData(self, result, plotPath):
139          """Plots the percentage of nodes ready in the network"""
140          vector1 = result.metrics["progress"]["TX builder mean"]
141          vector2 = result.metrics["progress"]["TX class1 mean"]
142          vector3 = result.metrics["progress"]["TX class2 mean"]
143          for i in range(len(vector1)):
144              vector1[i] = (vector1[i] * 8 * (1000/self.config.stepDuration) * self.config.segmentSize) / 1000000
145              vector2[i] = (vector2[i] * 8 * (1000/self.config.stepDuration) * self.config.segmentSize) / 1000000
146              vector3[i] = (vector3[i] * 8 * (1000/self.config.stepDuration) * self.config.segmentSize) / 1000000
147          conf = {}
148          attrbs = self.__get_attrbs__(result)
149          conf["textBox"] = "Block Size R: "+attrbs['bsrn']+"\nBlock Size C: "+attrbs['bscn']\
150          +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+" \nNetwork degree: "+attrbs['nd']
151          conf["title"] = "Sent data"
152          conf["type"] = "plot"
153          conf["legLoc"] = 2
154          conf["desLoc"] = 2
155          conf["colors"] = ["y-", "c-", "m-"]
156          conf["labels"] = ["Block Builder", "Solo stakers", "Staking pools"]
157          conf["xlabel"] = "Time (ms)"
158          conf["ylabel"] = "Bandwidth (MBits/s)"
159          conf["data"] = [vector1, vector2, vector3]
160          conf["xdots"] = [x*self.config.stepDuration for x in range(len(vector1))]
161          conf["path"] = plotPath+"/sentData.png"
162          maxi = 0
163          for v in conf["data"]:
164              if max(v) > maxi:
165                  maxi = max(v)
166          conf["yaxismax"] = maxi
167          plotData(conf)
168          print("Plot %s created." % conf["path"])
169  
170      def plotRecvData(self, result, plotPath):
171          """Plots the percentage of nodes ready in the network"""
172          vector1 = result.metrics["progress"]["RX class1 mean"]
173          vector2 = result.metrics["progress"]["RX class2 mean"]
174          for i in range(len(vector1)):
175              vector1[i] = (vector1[i] * 8 * (1000/self.config.stepDuration) * self.config.segmentSize) / 1000000
176              vector2[i] = (vector2[i] * 8 * (1000/self.config.stepDuration) * self.config.segmentSize) / 1000000
177          conf = {}
178          attrbs = self.__get_attrbs__(result)
179          conf["textBox"] = "Block Size R: "+attrbs['bsrn']+"\nBlock Size C: "+attrbs['bscn']\
180          +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+" \nNetwork degree: "+attrbs['nd']
181          conf["title"] = "Received data"
182          conf["type"] = "plot"
183          conf["legLoc"] = 2
184          conf["desLoc"] = 2
185          conf["colors"] = ["c-", "m-"]
186          conf["labels"] = ["Solo stakers", "Staking pools"]
187          conf["xlabel"] = "Time (ms)"
188          conf["ylabel"] = "Bandwidth (MBits/s)"
189          conf["data"] = [vector1, vector2]
190          conf["xdots"] = [x*self.config.stepDuration for x in range(len(vector1))]
191          conf["path"] = plotPath+"/recvData.png"
192          maxi = 0
193          for v in conf["data"]:
194              if max(v) > maxi:
195                  maxi = max(v)
196          conf["yaxismax"] = maxi
197          plotData(conf)
198          print("Plot %s created." % conf["path"])
199  
200      def plotDupData(self, result, plotPath):
201          """Plots the percentage of nodes ready in the network"""
202          vector1 = result.metrics["progress"]["Dup class1 mean"]
203          vector2 = result.metrics["progress"]["Dup class2 mean"]
204          for i in range(len(vector1)):
205              vector1[i] = (vector1[i] * 8 * (1000/self.config.stepDuration) * self.config.segmentSize) / 1000000
206              vector2[i] = (vector2[i] * 8 * (1000/self.config.stepDuration) * self.config.segmentSize) / 1000000
207          conf = {}
208          attrbs = self.__get_attrbs__(result)
209          conf["textBox"] = "Block Size R: "+attrbs['bsrn']+"\nBlock Size C: "+attrbs['bscn']\
210          +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+" \nNetwork degree: "+attrbs['nd']
211          conf["title"] = "Duplicated data"
212          conf["type"] = "plot"
213          conf["legLoc"] = 2
214          conf["desLoc"] = 2
215          conf["colors"] = ["c-", "m-"]
216          conf["labels"] = ["Solo stakers", "Staking pools"]
217          conf["xlabel"] = "Time (ms)"
218          conf["ylabel"] = "Bandwidth (MBits/s)"
219          conf["data"] = [vector1, vector2]
220          conf["xdots"] = [x*self.config.stepDuration for x in range(len(vector1))]
221          conf["path"] = plotPath+"/dupData.png"
222          maxi = 0
223          for v in conf["data"]:
224              if max(v) > maxi:
225                  maxi = max(v)
226          conf["yaxismax"] = maxi
227          plotData(conf)
228          print("Plot %s created." % conf["path"])
229  
230      def plotRowCol(self, result, plotPath):
231          """Plots the percentage of nodes ready in the network"""
232          vector1 = result.metrics["rowDist"]
233          vector2 = result.metrics["columnDist"]
234          if len(vector1) > len(vector2):
235              vector2 += [np.nan] * (len(vector1) - len(vector2))
236          elif len(vector1) < len(vector2):
237              vector1 += [np.nan] * (len(vector2) - len(vector1))
238          conf = {}
239          attrbs = self.__get_attrbs__(result)
240          conf["textBox"] = "Block Size R: "+attrbs['bsrn']+"\nBlock Size C: "+attrbs['bscn']\
241          +"\nNumber of nodes: "+attrbs['nn']+"\nFailure rate: "+attrbs['fr']+" \nNetwork degree: "+attrbs['nd']
242          conf["title"] = "Row/Column distribution"
243          conf["type"] = "bar"
244          conf["legLoc"] = 2
245          conf["desLoc"] = 2
246          conf["colors"] = ["r+", "b+"]
247          conf["labels"] = ["Rows", "Columns"]
248          conf["xlabel"] = "Row/Column ID"
249          conf["ylabel"] = "Validators subscribed"
250          conf["data"] = [vector1, vector2]
251          conf["xdots"] = range(len(vector1))
252          conf["path"] = plotPath+"/RowColDist.png"
253          maxi = 0
254          for v in conf["data"]:
255              if np.nanmax(v) > maxi:
256                  maxi = max(v)
257          conf["yaxismax"] = maxi
258          plotData(conf)
259          print("Plot %s created." % conf["path"])
260