#!/usr/bin/env python3 """Create pgf boxplots for emper-fs-eval experiment results""" import sys import yaml def parse_data(stream): """Convert yamls string to dict""" return yaml.safe_load(stream) TIKZ_TEMPLATE = \ """\\documentclass[]{standalone} \\usepackage{pgfplots} \\pgfplotsset{compat=1.17} \\usepgfplotslibrary{statistics} \\begin{document} \\begin{tikzpicture} \\begin{axis}[ ylabel={time [s]}, xtick=\\empty, ymajorgrids=true, boxplot/draw direction=y, legend columns=2, area legend, legend style={ draw=none, fill=none, at={(0.5,-0.1)}, anchor=north }, ] $PLOTS$ \\end{axis} \\end{tikzpicture} \\end{document} """ PLOT_TEMPLATE = \ """\\addplot+[ boxplot prepared={{ lower whisker={lower_whisker}, lower quartile={lower_quartile}, median={median}, average={mean}, upper quartile={upper_quartile}, upper whisker={upper_whisker}, }}, ] coordinates{{{outlier_cords}}}; \\addlegendentry{{{syscall}}} """ def generate_boxplot(data) -> str: """Create a boxplot""" key = 'duration_time:u' plots = '' for syscall, stats in data.items(): outlier_cords = '' for outlier in stats[key]['outliers']: outlier_cords += f'(0, {outlier}) ' plots += PLOT_TEMPLATE.format(syscall=syscall.replace('_', '-'), outlier_cords=outlier_cords, **stats[key]) return TIKZ_TEMPLATE.replace('$PLOTS$', plots) def main(): """Create a boxplot from read yaml data""" if len(sys.argv) == 1: _data = parse_data(sys.stdin) else: with open(sys.argv[1], 'r', encoding='utf-8') as yaml_file: _data = parse_data(yaml_file) tikz = generate_boxplot(_data) if len(sys.argv) > 2: with open(sys.argv[2], 'w', encoding='utf-8') as saveto: print(tikz, file=saveto) else: print(tikz) if __name__ == '__main__': main()