import defapp from subprocess import Popen, PIPE from optparse import make_option as o FORMATS = ['png', 'eps', 'pdf', 'show'] STYLES = ['points', 'lines', 'linespoints'] class CommandBuffer(object): def __init__(self): self.cmds = [] def __call__(self, cmd): self.cmds += [cmd] def __str__(self): return '\n'.join([str(x) for x in self.cmds]) def gnuplot_cmd(graphs, title=None, ylabel=None, xlabel=None, format='show', term_opts=None, style='linespoints', xrange=None, yrange=None, xticks=None, yticks=None, key='below', fname=None): g = CommandBuffer() if format == 'png': terminal = 'png' if term_opts is None: term_opts = 'size 1024,768 large' elif format == 'eps': terminal = 'postscript eps' if term_opts is None: term_opts = 'color blacktext solid linewidth 1.0' elif format == 'pdf': terminal = 'pdf' if term_opts is None: term_opts = 'color enhanced' if format != 'show': g('set terminal %s %s' % (terminal, term_opts)) g("set out '/dev/null'") if xlabel: g("set xlabel '%s'" % xlabel) if ylabel: g("set ylabel '%s'" % ylabel) if title: g("set title '%s'" % title) if xrange: g("set xrange [%s:%s]" % xrange) if yrange: g("set yrange [%s:%s]" % yrange) if xticks: g("set xtics %s, %s" % xticks) if yticks: g("set ytics %s, %s" % yticks) g('set key %s' % key) plot = [] for gr in graphs: par = (gr[0], gr[1], gr[2], gr[3], style) if len(gr) == 4 else gr plot += ["'%s' using %s:%s title '%s' with %s" % par] if plot: g('plot ' + ', '.join(plot)) if format != 'show' and fname: g("set out '%s.%s'" % (fname, format)) if plot: g('replot') if format != 'show' and fname: g('set out') return g def pipe2gnuplot(cmds): proc = Popen(['gnuplot'], stdin=PIPE) proc.stdin.write(str(cmds)) proc.stdin.close() proc.wait() def eps2pdf(file): Popen(['ps2pdf', '-dEPSCrop', '%s.eps' % file]).wait() options = [ o('-f', '--format', action='store', dest='format', type='choice', choices=FORMATS, help='output format'), o('-o', '--output', action='store', dest='out', help='Output file name.'), o('-s', '--style', action='store', dest='style', type='choice', choices=STYLES, help='line style'), o('-t', '--title', action='store', dest='title'), o(None, '--xlabel', action='store', dest='xlabel'), o(None, '--ylabel', action='store', dest='ylabel'), o(None, '--xrange', action='store', dest='xrange', nargs=2, type='float'), o(None, '--yrange', action='store', dest='yrange', nargs=2, type='float'), o(None, '--xticks', action='store', dest='xticks', nargs=2, type='float'), o(None, '--yticks', action='store', dest='yticks', nargs=2, type='float'), ] defaults = { 'out' : 'graph', 'format' : 'show', 'style' : 'linespoints', 'title' : None, 'xlabel' : None, 'ylabel' : None, 'xrange' : None, 'yrange' : None, } class Plotter(defapp.App): def __init__(self): defapp.App.__init__(self, options, defaults, no_std_opts=True) def get_cmd(self, args): graphs = [] while len(args) >= 4: g = args[0:4] graphs += [g] args = args[4:] if args: self.err("Warning: Ignoring trailing args. Args:", *args) return gnuplot_cmd(graphs, title=self.options.title, format=self.options.format, style=self.options.style, xlabel=self.options.xlabel, ylabel=self.options.ylabel, xrange=self.options.xrange, yrange=self.options.yrange, xticks=self.options.xticks, yticks=self.options.yticks, fname=self.options.out) def default(self, _): cmd = self.get_cmd(list(self.args)) pipe2gnuplot(cmd) def do_cmd(self, _): cmd = self.get_cmd(self.args[1:]) self.out(cmd) if __name__ == "__main__": Plotter().launch()