/ src / plotting.py
plotting.py
  1  # Python Imports
  2  import math
  3  import numpy as np
  4  import matplotlib.pyplot as plt
  5  
  6  # Project Imports
  7  from src import vars
  8  from src import analysis_logger
  9  from src import plotting_configurations
 10  
 11  def plot_figure_cproc(msg_propagation_times, cpu_usage, memory_usage, network_usage, disk_usage, injection_times, simulation_summary, simulation_config):
 12  
 13      def style_violin(parts, ax):
 14  
 15          # Change the extrema lines to dashed grey lines
 16          for line in parts['cmaxes'].get_segments() + parts['cmins'].get_segments():
 17              line_obj = plt.Line2D(line[:, 0], line[:, 1], color='grey', linestyle='dashed', linewidth=0.5)
 18              ax.add_line(line_obj)
 19  
 20          # Remove the original extrema lines
 21          parts['cmaxes'].set_visible(False)
 22          parts['cmins'].set_visible(False)
 23  
 24          # Change the vertical lines to dashed grey lines
 25          for line in parts['cbars'].get_segments():
 26              line_obj = plt.Line2D(line[:, 0], line[:, 1], color='grey', linestyle='dashed', linewidth=0.5)
 27              ax.add_line(line_obj)
 28  
 29          # Remove the original vertical lines
 30          parts['cbars'].set_visible(False)
 31  
 32          cmean_colors = parts['cmeans'].get_color()
 33          colors = [cmean_colors[0],'red',cmean_colors[0],cmean_colors[0]]
 34          parts['cmeans'].set_color(colors)
 35  
 36          # loop over the paths of the mean lines
 37          xy = [[l.vertices[:,0].mean(),l.vertices[0,1]] for l in parts['cmeans'].get_paths()]
 38          xy = np.array(xy)
 39          ax.scatter(xy[:,0], xy[:,1],s=25, c="crimson", marker="o", zorder=3)
 40  
 41          # make lines invisible
 42          parts['cmeans'].set_visible(False)
 43      
 44      fig, ((ax1, ax2, ax3), (ax4, ax5, ax6)) = plt.subplots(2, 3, figsize=(15, 15))
 45      
 46      if msg_propagation_times:
 47          parts = ax1.violinplot(msg_propagation_times, showmeans=True)
 48          ax1.set_title('Popagation Time (per message)')
 49          ax1.set_ylabel('Propagation Time (ms)')
 50          ax1.spines[['right', 'top']].set_visible(False)
 51          ax1.axes.xaxis.set_visible(False)
 52          style_violin(parts, ax1)
 53  
 54      parts = ax2.violinplot(cpu_usage, showmeans=True)
 55      ax2.set_title('Peak CPU Usage (per node)')
 56      ax2.set_ylabel('CPU Usage (%)')
 57      ax2.spines[['right', 'top']].set_visible(False)
 58      ax2.axes.xaxis.set_visible(False)
 59      style_violin(parts, ax2)
 60  
 61      parts = ax3.violinplot(memory_usage, showmeans=True)
 62      ax3.set_title('Peak Memory Usage (per node)')
 63      ax3.set_ylabel('Memory (MBytes)')
 64      ax3.spines[['right', 'top']].set_visible(False)
 65      ax3.axes.xaxis.set_visible(False)
 66      style_violin(parts, ax3)
 67  
 68      parts = ax4.violinplot([network_usage['rx_mbytes'], network_usage['tx_mbytes']], showmeans=True)
 69      ax4.set_title('Total Netowrk IO (per node)')
 70      ax4.set_ylabel('Bandwidth (MBytes)')
 71      ax4.spines[['right', 'top']].set_visible(False)
 72      ax4.set_xticks([1, 2])
 73      ax4.set_xticklabels(['Received (Rx)', 'Sent (Tx)'])
 74      style_violin(parts, ax4)
 75  
 76      parts = ax5.violinplot(injection_times, showmeans=True)
 77      ax5.set_title('Injection Time (per message)')
 78      ax5.set_ylabel('Milliseconds (ms)')
 79      ax5.spines[['right', 'top']].set_visible(False)
 80      ax5.axes.xaxis.set_visible(False)
 81      style_violin(parts, ax5)
 82      
 83      parts = ax6.violinplot([disk_usage['disk_read_mbytes'], disk_usage['disk_write_mbytes']], showmeans=True)
 84      ax6.set_title('Peak Disk IO (per node)')
 85      ax6.set_ylabel('Disk IO (MBytes)')
 86      ax6.spines[['right', 'top']].set_visible(False)
 87      ax6.set_xticks([1, 2])
 88      ax6.set_xticklabels(['Read', 'Write'])
 89      style_violin(parts, ax6)
 90      
 91      fig.suptitle('Wakurtosis Simulation Node Level Analysis\n(%d nodes, %d topic(s), Rate: %d msg/s, Time: %.2f s. Sampling Rate: %.2f samples/s.)\n' %(simulation_summary['num_nodes'], \
 92      simulation_summary['num_topics'], simulation_config['wls']['message_rate'], simulation_summary['simulation_time_ms'] / 1000.0, \
 93      simulation_summary['metrics']['esr']), fontsize=20)
 94      
 95      plt.tight_layout()
 96  
 97      figure_path = f'{vars.G_DEFAULT_SIMULATION_PATH}/{vars.G_DEFAULT_FIG_FILENAME}'
 98      plt.savefig(figure_path, format="pdf", bbox_inches="tight")
 99  
100      analysis_logger.G_LOGGER.info(f'Figure saved in {figure_path}')
101  
102  
103  def plot_figure_ex(simulation_config):
104      def style_violin(parts, ax):
105  
106          # Change the extrema lines to dashed grey lines
107          for line in parts['cmaxes'].get_segments() + parts['cmins'].get_segments():
108              line_obj = plt.Line2D(line[:, 0], line[:, 1], color='grey', linestyle='dashed', linewidth=0.5)
109              ax.add_line(line_obj)
110  
111          # Remove the original extrema lines
112          parts['cmaxes'].set_visible(False)
113          parts['cmins'].set_visible(False)
114  
115          # Change the vertical lines to dashed grey lines
116          for line in parts['cbars'].get_segments():
117              line_obj = plt.Line2D(line[:, 0], line[:, 1], color='grey', linestyle='dashed', linewidth=0.5)
118              ax.add_line(line_obj)
119  
120          # Remove the original vertical lines
121          parts['cbars'].set_visible(False)
122  
123          cmean_colors = parts['cmeans'].get_color()
124          colors = [cmean_colors[0], 'red', cmean_colors[0], cmean_colors[0]]
125          parts['cmeans'].set_color(colors)
126  
127          # loop over the paths of the mean lines
128          xy = [[l.vertices[:, 0].mean(), l.vertices[0, 1]] for l in parts['cmeans'].get_paths()]
129          xy = np.array(xy)
130          ax.scatter(xy[:, 0], xy[:, 1], s=25, c="crimson", marker="o", zorder=3)
131  
132          # make lines invisible
133          parts['cmeans'].set_visible(False)
134  
135      metrics = plotting_configurations.plotting_config
136      num_subplots = len(metrics.keys())
137      num_cols = 3
138      num_rows = math.ceil(num_subplots / num_cols)
139  
140      fig, axs = plt.subplots(num_rows, num_cols, figsize=(15, 15))
141      axs = axs.flatten()
142  
143      # Remove unused subplots
144      for i in range(num_subplots, num_rows * num_cols):
145          fig.delaxes(axs[i])
146  
147      for i, key in enumerate(metrics.keys()):
148          # if type(metrics[key]) is list:
149          #     if sum([plotting_configurations[val]["values"] for val in metrics[key]]) == 0:
150          #         continue
151          metric = metrics[key]
152          analysis_logger.G_LOGGER.info(f"Plotting {key}: {metric['values']}")
153          parts = axs[i].violinplot(metric["values"], showmeans=True)
154          axs[i].set_title(metric["title"])
155          axs[i].set_ylabel(metric["y_label"])
156          axs[i].spines[['right', 'top']].set_visible(False)
157          axs[i].axes.xaxis.set_visible(False)
158          if "xtic_labels" in metric.keys():
159              axs[i].set_xticks([i+1 for i in range(len(metric["xtic_labels"]))])
160              axs[i].set_xticklabels(metric["xtic_labels"])
161              axs[i].axes.xaxis.set_visible(True)
162          style_violin(parts, axs[i])
163  
164      fig.suptitle(
165          'Wakurtosis Simulation Node Level Analysis\n(%d nodes, %d topic(s), Rate: %d msg/s, Time: %.2f s. Message Rate: %.2f. Min/Max size: %d/%d.)\n' % (
166          simulation_config['gennet']['num_nodes'], \
167          simulation_config['gennet']['num_topics'], simulation_config['wls']['message_rate'],
168          simulation_config['wls']['simulation_time'], \
169          simulation_config['wls']['message_rate'],
170          simulation_config['wls']['min_packet_size'],
171          simulation_config['wls']['max_packet_size']
172          ), fontsize=20)
173  
174      plt.tight_layout()
175  
176      figure_path = f'{vars.G_DEFAULT_SIMULATION_PATH}{vars.G_DEFAULT_FIG_FILENAME}'
177      plt.savefig(figure_path, format="pdf", bbox_inches="tight")
178  
179      analysis_logger.G_LOGGER.info(f'Figure saved in {figure_path}')