Browse Source

Add plot for average packets sent per communication interval per connection

dustin.born 6 years ago
parent
commit
b10fc1eb17
1 changed files with 73 additions and 3 deletions
  1. 73 3
      code/ID2TLib/Statistics.py

+ 73 - 3
code/ID2TLib/Statistics.py

@@ -1078,6 +1078,7 @@ class Statistics:
             """
             Plots the exchanged packets per connection as horizontal bar plot. 
             Included are 'half-open' connections, where only one packet is exchanged.
+            Note: there may be cutoff problems within the plot if there is to little data.
 
             :param file_ending: The file extension for the output file containing the plot
             :return: A filepath to the file containing the created plot
@@ -1125,11 +1126,14 @@ class Statistics:
                 plt.barh(range(len(graphy)), graphx, width, align='center', linewidth=1, color='red', edgecolor='red')
                 # now change the y numbers to the respective address labels
                 plt.yticks(range(len(graphy)), graphy)
-                # use tight layout to cut off unnecessary space
-                plt.tight_layout(pad=4)
+                # try to use tight layout to cut off unnecessary space
+                try:
+                    plt.tight_layout(pad=4)
+                except ValueError:
+                    pass
 
                 # save created figure
-                out = self.pcap_filepath.replace('.pcap', '_plot-connection' + file_ending)
+                out = self.pcap_filepath.replace('.pcap', '_plot-PktCount per Connection Distribution' + file_ending)
                 plt.savefig(out, dpi=500)
                 return out
             else:
@@ -1188,6 +1192,71 @@ class Statistics:
             plt.savefig(out,dpi=500)
             return out
 
+        def plot_avgpkts_per_comm_interval(file_ending: str):
+            """
+            Plots the exchanged packets per connection as horizontal bar plot. 
+            Included are 'half-open' connections, where only one packet is exchanged.
+            Note: there may be cutoff problems within the plot if there is to little data.
+
+            :param file_ending: The file extension for the output file containing the plot
+            :return: A filepath to the file containing the created plot
+            """
+            plt.gcf().clear()
+            result = self.stats_db._process_user_defined_query(
+                "SELECT ipAddressA, portA, ipAddressB, portB, avgPktCount FROM comm_interval_statistics")
+
+            if (result):
+                graphy, graphx = [], []
+                # plot data in descending order
+                result = sorted(result, key=lambda row: row[4])
+
+                # compute plot data
+                for i, row in enumerate(result):
+                    addr1, addr2 = "%s:%d" % (row[0], row[1]), "%s:%d" % (row[2], row[3])
+                    # adjust the justification of strings to improve appearance
+                    len_max = max(len(addr1), len(addr2))
+                    addr1 = addr1.ljust(len_max)
+                    addr2 = addr2.ljust(len_max)
+                    # add plot data
+                    graphy.append("%s\n%s" % (addr1, addr2))
+                    graphx.append(row[4])
+
+                # compute plot height in inches
+                dist_mult_height, dist_mult_width = 0.55, 0.07  # these values turned out to work well
+                plt_height, plt_width = len(graphy) * dist_mult_height, max(graphx) * dist_mult_width
+                title_distance = 1 + 0.012*52.8/plt_height  # orginally, a good title distance turned out to be 1.012 with a plot height of 52.8
+
+                # have x axis and its label appear at the top (instead of bottom)
+                fig, ax = plt.subplots()
+                ax.xaxis.tick_top()
+                ax.xaxis.set_label_position("top")
+
+                # set additional plot parameters
+                plt.title("Average number of packets per communication interval", y=title_distance)
+                plt.xlabel('Number of Packets')
+                plt.ylabel('Connection')
+                width = 0.5
+                plt.grid(True)
+                plt.gca().margins(y=0)  # removes the space between data and x-axis within the plot
+                plt.gcf().set_size_inches(plt_width, plt_height)  # set plot size
+
+                # plot the above data, first use plain numbers as graphy to maintain sorting
+                plt.barh(range(len(graphy)), graphx, width, align='center', linewidth=1, color='red', edgecolor='red')
+                # now change the y numbers to the respective address labels
+                plt.yticks(range(len(graphy)), graphy)
+                # try to use tight layout to cut off unnecessary space
+                try:
+                    plt.tight_layout(pad=4)
+                except ValueError:
+                    pass
+
+                # save created figure
+                out = self.pcap_filepath.replace('.pcap', '_plot-Avg PktCount Communication Interval Distribution' + file_ending)
+                plt.savefig(out, dpi=500)
+                return out
+            else:
+                print("Error plot protocol: No protocol values found!")
+
 
         ttl_out_path = plot_ttl('.' + format)
         mss_out_path = plot_mss('.' + format)
@@ -1207,6 +1276,7 @@ class Statistics:
         plot_packets_per_connection_out = plot_packets_per_connection('.' + format)
         plot_out_degree = plot_out_degree('.' + format)
         plot_in_degree = plot_in_degree('.' + format)
+        plot_avgpkts_per_comm_interval_out = plot_avgpkts_per_comm_interval('.' + format)
 
         ## Time consuming plot
         # port_out_path = plot_port('.' + format)