#!/usr/bin/env python import defapp from plot import decode from util import load_csv_file, write_csv_file from math import ceil from numpy import amin, amax, mean, median, std, histogram from os.path import splitext, basename from optparse import make_option as o from gnuplot import gnuplot, FORMATS, Plot, label, curve options = [ # output options o('-f', '--format', action='store', dest='format', type='choice', choices=FORMATS, help='output format'), o(None, '--save-script', action='store_true', dest='save_script'), o('-p', '--prefix', action='store', dest='prefix'), # formatting options # These may or may not be supported by a particular experiment plotter. o(None, '--smooth', action='store_true', dest='smooth'), ] defaults = { # output options 'format' : 'pdf', 'save_script' : False, 'prefix' : '', # formatting options 'alternate' : False, } class VideoPlotter(defapp.App): def __init__(self): defapp.App.__init__(self, options, defaults, no_std_opts=True) self.tmpfiles = [] def make_plot(self, fname=None): p = Plot() p.output = "%s%s.%s" % (self.options.prefix, fname, self.options.format) p.format = self.options.format return p def setup_png(self, plot): # standard png options; usually correct; never tweaked for paper if self.options.format == 'png': plot.font_size = 'large' plot.size = (1024, 768) plot.xticks = (0, 1) plot.yticks = (0, 0.1) plot.default_style = "linespoints" return True else: return False def load(self, datafile, name): data = load_csv_file(datafile) # make a copy without comments, etc. if self.options.save_script: fname = "%s.data" % name write_csv_file(fname, data) return (data, fname) else: tmp = write_csv_file(None, data) # keep a reference so that it isn't deleted self.tmpfiles.append(tmp) return (data, tmp.name) def render(self, p): if self.options.save_script: p.gnuplot_save(p.output + '.plot') else: p.gnuplot_exec() def plot_vdecode(self, datafile, name, conf): (data, fname) = self.load(datafile, name) decode_times = data[:,0] avg = mean(decode_times) med = median(decode_times) dev = std(decode_times) max = amax(decode_times) min = amin(decode_times) stats_label = "min=%.2fms max=%.2fms avg=%.2fms median=%.2fms std=%.2fms" \ % (min, max, avg, med, dev) p = self.make_plot(name) p.title = "raw decoding cost; input=%s; host=%s" \ % (conf['file'], conf['host']) p.ylabel = "decoding cost (ms)" p.xlabel = "frame number" p.xrange = (0, len(data)) #p.xticks = (0, 100) p.yticks = (0, 1) p.yrange = (0, ceil(max)) p.curves = [curve(fname=fname, xcol=2, ycol=1, title="decoding cost")] p.labels = [label(0.5, 0.9, stats_label, coord=['graph', 'screen'], align='center')] #### Styling. if not self.setup_png(p): p.rounded_caps = True p.font = 'Helvetica' p.font_size = '10' p.size = ('20cm', '10cm') p.monochrome = False p.dashed_lines = False p.key = 'off' p.default_style = 'points lw 1' if self.options.smooth: p.default_style += " smooth bezier" self.render(p) def plot_file(self, datafile): bname = basename(datafile) name, ext = splitext(bname) conf = decode(name) plotters = { 'vdecode' : self.plot_vdecode, } for plot_type in plotters: if plot_type in conf: try: plotters[plot_type](datafile, name, conf) except IOError as err: self.err("Skipped '%s' (%s)." % err) break else: self.err("Skipped '%s'; unkown experiment type." % bname) # release all tmp files self.tmpfiles = [] def default(self, _): for i, datafile in enumerate(self.args): self.out("[%d/%d] Processing %s ..." % (i + 1, len(self.args), datafile)) self.plot_file(datafile) if __name__ == "__main__": VideoPlotter().launch()