text: #!/usr/bin/env python
  # Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
  #
  # Use of this source code is governed by a BSD-style license
  # that can be found in the LICENSE file in the root of the source
  # tree. An additional intellectual property rights grant can be found
  # in the file PATENTS.  All contributing project authors may
  # be found in the AUTHORS file in the root of the source tree.
  
  """Shows boxplots of given score for different values of selected
  parameters. Can be used to compare scores by audioproc_f flag.
  
  Usage: apm_quality_assessment_boxplot.py -o /path/to/output
                                           -v polqa
                                           -n /path/to/dir/with/apm_configs
                                           -z audioproc_f_arg1 [arg2 ...]
  
  Arguments --config_names, --render_names, --echo_simulator_names,
  --test_data_generators, --eval_scores can be used to filter the data
  used for plotting.
  """
  
  import collections
  import logging
  import matplotlib.pyplot as plt
  import os
  
  import quality_assessment.data_access as data_access
  import quality_assessment.collect_data as collect_data
  
  
  def InstanceArgumentsParser():
    """Arguments parser factory.
    """
    parser = collect_data.InstanceArgumentsParser()
    parser.description = (
        'Shows boxplot of given score for different values of selected'
        'parameters. Can be used to compare scores by audioproc_f flag')
  
    parser.add_argument('-v', '--eval_score', required=True,
                        help=('Score name for constructing boxplots'))
  
    parser.add_argument('-n', '--config_dir', required=False,
                        help=('path to the folder with the configuration files'),
                        default='apm_configs')
  
    parser.add_argument('-z', '--params_to_plot', required=True,
                        nargs='+', help=('audioproc_f parameter values'
                        'by which to group scores (no leading dash)'))
  
    return parser
  
  
  def FilterScoresByParams(data_frame, filter_params, score_name, config_dir):
    """Filters data on the values of one or more parameters.
  
    Args:
      data_frame: pandas.DataFrame of all used input data.
  
      filter_params: each config of the input data is assumed to have
        exactly one parameter from `filter_params` defined. Every value
        of the parameters in `filter_params` is a key in the returned
        dict; the associated value is all cells of the data with that
        value of the parameter.
  
      score_name: Name of score which value is boxplotted. Currently cannot do
        more than one value.
  
      config_dir: path to dir with APM configs.
  
    Returns: dictionary, key is a param value, result is all scores for
      that param value (see `filter_params` for explanation).
    """
  
    results = collections.defaultdict(dict)
    config_names = data_frame['apm_config'].drop_duplicates().values.tolist()
  
    for config_name in config_names:
      config_json = data_access.AudioProcConfigFile.Load(
          os.path.join(config_dir, config_name + '.json'))
      data_with_config = data_frame[data_frame.apm_config == config_name]
  
      data_cell_scores = data_with_config[data_with_config.eval_score_name ==
                                          score_name]
  
      # Exactly one of |params_to_plot| must match:
      (matching_param, ) = [x for x in filter_params if '-' + x in config_json]
  
      # Add scores for every track to the result.
      for capture_name in data_cell_scores.capture:
        result_score = float(data_cell_scores[data_cell_scores.capture ==
                                              capture_name].score)
        config_dict = results[config_json['-' + matching_param]]
        if capture_name not in config_dict:
          config_dict[capture_name] = {}
  
        config_dict[capture_name][matching_param] = result_score
  
    return results
  
  
  def _FlattenToScoresList(config_param_score_dict):
    """Extracts a list of scores from input data structure.
  
    Args:
      config_param_score_dict: of the form {'capture_name':
      {'param_name' : score_value,.. } ..}
  
    Returns: Plain list of all score value present in input data
      structure
    """
    result = []
    for capture_name in config_param_score_dict:
      result += list(config_param_score_dict[capture_name].values())
    return result
  
  
  def main():
    # Init.
    # TODO(alessiob): INFO once debugged.
    logging.basicConfig(level=logging.DEBUG)
    parser = InstanceArgumentsParser()
    args = parser.parse_args()
  
    # Get the scores.
    src_path = collect_data.ConstructSrcPath(args)
    logging.debug(src_path)
    scores_data_frame = collect_data.FindScores(src_path, args)
  
    # Filter the data by `args.params_to_plot`
    scores_filtered = FilterScoresByParams(scores_data_frame,
                                           args.params_to_plot,
                                           args.eval_score,
                                           args.config_dir)
  
    data_list = sorted(scores_filtered.items())
    data_values = [_FlattenToScoresList(x) for (_, x) in data_list]
    data_labels = [x for (x, _) in data_list]
  
    _, axes = plt.subplots(nrows=1, ncols=1, figsize=(6, 6))
    axes.boxplot(data_values, labels=data_labels)
    axes.set_ylabel(args.eval_score)
    axes.set_xlabel('/'.join(args.params_to_plot))
    plt.show()
  
  
  if __name__ == "__main__":
    main()
  