github.com/swiftstack/ProxyFS@v0.0.0-20210203235616-4017c267d62f/pfs-swift-load/pfs-swift-load-plot (about)

     1  #!/usr/bin/env python
     2  
     3  import argparse
     4  import itertools
     5  import matplotlib
     6  import pandas as pd
     7  import sys
     8  
     9  matplotlib.use("Agg")
    10  import matplotlib.pyplot as plt
    11  
    12  
    13  ELAPSED_TIME_COL = "ElapsedTime"
    14  ELAPSED_TIME_TEXT = "Elapsed Time (s)"
    15  COMPLETED_COL = "Completed"
    16  COMPLETED_TEXT = "Completed"
    17  DELTA_COL = "Delta"
    18  DELTA_TEXT = "Delta"
    19  OBJECTS_PER_SECOND_COL = "ObjectsPerSecond"
    20  OBJECTS_PER_SECOND_TEXT = "Objects/Second"
    21  PLOT_COLORS = ["r", "g", "b", "c", "m", "y", "k"]
    22  PLOT_COLS = 1
    23  PLOT_ROWS = 2
    24  FIG_SIZE = (18, 12)
    25  
    26  
    27  def plot(plot_position, x_axis_data, x_axis_label, warning_msg=None):
    28      color_iterator = itertools.cycle(PLOT_COLORS)
    29  
    30      ax = fig.add_subplot(PLOT_ROWS, PLOT_COLS, plot_position)
    31      for worker in workers:
    32          ax.plot(
    33              x_axis_data,
    34              data_frame[worker][OBJECTS_PER_SECOND_COL],
    35              color=color_iterator.next(), label=worker)
    36      ax.set_xlabel(x_axis_label, color="k")
    37      ax.set_ylabel(OBJECTS_PER_SECOND_TEXT, color="k")
    38      ax.grid(color="tab:gray", linestyle="dashdot", linewidth=.4)
    39      plt.legend()
    40      if warning_msg:
    41          plt.title(warning_msg, bbox=dict(facecolor='red', alpha=0.5))
    42  
    43  
    44  def parse_args():
    45      parser = argparse.ArgumentParser(description="Plot results from "
    46                                                   "pfs-swift-load")
    47      parser.add_argument("-i", "--input", type=str, required=True,
    48                          help="Input CSV file")
    49      parser.add_argument("-o", "--output", type=str, required=True,
    50                          help="Output PNG file")
    51      parser.add_argument("-w", "--warning", type=str, required=False,
    52                          default=None, help="Warning message to print on the "
    53                                             "PNG file")
    54      args = parser.parse_args()
    55      options = {
    56          "input": args.input,
    57          "output": args.output,
    58          "warning": args.warning,
    59      }
    60      return options
    61  
    62  
    63  if __name__ == "__main__":
    64      options = parse_args()
    65  
    66      data_frame = pd.read_csv(options["input"], header=[0, 1])
    67      workers = list(data_frame.keys().levels[0])
    68      # We only have len(PLOT_COLORS) colors to use, and we don't want 2 workers
    69      # to be plotted with the same color...
    70      if len(workers) > len(PLOT_COLORS):
    71          print("Too many workers: {}, max: {}".format(len(workers),
    72                                                       len(PLOT_COLORS)))
    73          sys.exit(1)
    74  
    75      # Check how long are the intervals between samples
    76      interval = data_frame[workers[0]].ElapsedTime[0]
    77      # We want an extra column for objects/second. Warning! It doesn't take into
    78      # account the fact that several threads could have been working in
    79      # parallel. Maybe we could add an option?
    80      for worker in workers:
    81          data_frame[worker, OBJECTS_PER_SECOND_COL] = \
    82              data_frame[worker][DELTA_COL] / interval
    83      data_frame = data_frame.sort_index(axis=1)
    84  
    85      # Draw the chart(s)
    86      fig = plt.figure(figsize=FIG_SIZE)
    87      plot(1, data_frame[worker][ELAPSED_TIME_COL], ELAPSED_TIME_TEXT,
    88           options["warning"])
    89      plot(2, data_frame[worker][COMPLETED_COL], COMPLETED_TEXT)
    90      plt.savefig(options["output"])