diff options
| author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2009-02-21 23:07:28 -0500 |
|---|---|---|
| committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2009-02-21 23:07:28 -0500 |
| commit | 22dd4f9b422ebb5d5ba903dc2b3113b3c8d3ec1b (patch) | |
| tree | f8d97efb18c3f37f6bbcf9628a22020b28a3b430 | |
| parent | 1c643e2c045cd3c2d2c73ce1111171e7f01ebcc6 (diff) | |
introduce Python-based plotter
- build for Gnuplot 4.2
- generates Gnuplot source
- native PDF generation
| -rw-r--r-- | plot.py | 138 |
1 files changed, 138 insertions, 0 deletions
| @@ -0,0 +1,138 @@ | |||
| 1 | import defapp | ||
| 2 | from subprocess import Popen, PIPE | ||
| 3 | from optparse import make_option as o | ||
| 4 | |||
| 5 | FORMATS = ['png', 'eps', 'pdf', 'show'] | ||
| 6 | STYLES = ['points', 'lines', 'linespoints'] | ||
| 7 | |||
| 8 | class CommandBuffer(object): | ||
| 9 | def __init__(self): | ||
| 10 | self.cmds = [] | ||
| 11 | |||
| 12 | def __call__(self, cmd): | ||
| 13 | self.cmds += [cmd] | ||
| 14 | |||
| 15 | def __str__(self): | ||
| 16 | return '\n'.join([str(x) for x in self.cmds]) | ||
| 17 | |||
| 18 | def gnuplot_cmd(graphs, title=None, ylabel=None, xlabel=None, | ||
| 19 | format='show', term_opts=None, | ||
| 20 | style='linespoints', xrange=None, | ||
| 21 | yrange=None, | ||
| 22 | xticks=None, yticks=None, | ||
| 23 | key='below', | ||
| 24 | fname=None): | ||
| 25 | g = CommandBuffer() | ||
| 26 | if format == 'png': | ||
| 27 | terminal = 'png' | ||
| 28 | if term_opts is None: | ||
| 29 | term_opts = 'size 1024,768 large' | ||
| 30 | elif format == 'eps': | ||
| 31 | terminal = 'postscript eps' | ||
| 32 | if term_opts is None: | ||
| 33 | term_opts = 'color blacktext solid linewidth 1.0' | ||
| 34 | elif format == 'pdf': | ||
| 35 | terminal = 'pdf' | ||
| 36 | if term_opts is None: | ||
| 37 | term_opts = 'color enhanced' | ||
| 38 | if format != 'show': | ||
| 39 | g('set terminal %s %s' % (terminal, term_opts)) | ||
| 40 | g("set out '/dev/null'") | ||
| 41 | if xlabel: | ||
| 42 | g("set xlabel '%s'" % xlabel) | ||
| 43 | if ylabel: | ||
| 44 | g("set ylabel '%s'" % ylabel) | ||
| 45 | if title: | ||
| 46 | g("set title '%s'" % title) | ||
| 47 | if xrange: | ||
| 48 | g("set xrange [%s:%s]" % xrange) | ||
| 49 | if yrange: | ||
| 50 | g("set yrange [%s:%s]" % yrange) | ||
| 51 | if xticks: | ||
| 52 | g("set xtics %s, %s" % xticks) | ||
| 53 | if yticks: | ||
| 54 | g("set ytics %s, %s" % yticks) | ||
| 55 | g('set key %s' % key) | ||
| 56 | plot = [] | ||
| 57 | for gr in graphs: | ||
| 58 | par = (gr[0], gr[1], gr[2], gr[3], style) if len(gr) == 4 else gr | ||
| 59 | plot += ["'%s' using %s:%s title '%s' with %s" % par] | ||
| 60 | if plot: | ||
| 61 | g('plot ' + ', '.join(plot)) | ||
| 62 | if format != 'show' and fname: | ||
| 63 | g("set out '%s.%s'" % (fname, format)) | ||
| 64 | if plot: | ||
| 65 | g('replot') | ||
| 66 | if format != 'show' and fname: | ||
| 67 | g('set out') | ||
| 68 | return g | ||
| 69 | |||
| 70 | def pipe2gnuplot(cmds): | ||
| 71 | proc = Popen(['gnuplot'], stdin=PIPE) | ||
| 72 | proc.stdin.write(str(cmds)) | ||
| 73 | proc.stdin.close() | ||
| 74 | proc.wait() | ||
| 75 | |||
| 76 | def eps2pdf(file): | ||
| 77 | Popen(['ps2pdf', '-dEPSCrop', '%s.eps' % file]).wait() | ||
| 78 | |||
| 79 | options = [ | ||
| 80 | o('-f', '--format', action='store', dest='format', type='choice', | ||
| 81 | choices=FORMATS, help='output format'), | ||
| 82 | o('-o', '--output', action='store', dest='out', help='Output file name.'), | ||
| 83 | o('-s', '--style', action='store', dest='style', type='choice', | ||
| 84 | choices=STYLES, help='line style'), | ||
| 85 | o('-t', '--title', action='store', dest='title'), | ||
| 86 | o(None, '--xlabel', action='store', dest='xlabel'), | ||
| 87 | o(None, '--ylabel', action='store', dest='ylabel'), | ||
| 88 | o(None, '--xrange', action='store', dest='xrange', nargs=2, type='float'), | ||
| 89 | o(None, '--yrange', action='store', dest='yrange', nargs=2, type='float'), | ||
| 90 | o(None, '--xticks', action='store', dest='xticks', nargs=2, type='float'), | ||
| 91 | o(None, '--yticks', action='store', dest='yticks', nargs=2, type='float'), | ||
| 92 | ] | ||
| 93 | |||
| 94 | defaults = { | ||
| 95 | 'out' : 'graph', | ||
| 96 | 'format' : 'show', | ||
| 97 | 'style' : 'linespoints', | ||
| 98 | 'title' : None, | ||
| 99 | 'xlabel' : None, | ||
| 100 | 'ylabel' : None, | ||
| 101 | 'xrange' : None, | ||
| 102 | 'yrange' : None, | ||
| 103 | } | ||
| 104 | |||
| 105 | class Plotter(defapp.App): | ||
| 106 | def __init__(self): | ||
| 107 | defapp.App.__init__(self, options, defaults, no_std_opts=True) | ||
| 108 | |||
| 109 | def get_cmd(self, args): | ||
| 110 | graphs = [] | ||
| 111 | while len(args) >= 4: | ||
| 112 | g = args[0:4] | ||
| 113 | graphs += [g] | ||
| 114 | args = args[4:] | ||
| 115 | if args: | ||
| 116 | self.err("Warning: Ignoring trailing args. Args:", *args) | ||
| 117 | return gnuplot_cmd(graphs, | ||
| 118 | title=self.options.title, | ||
| 119 | format=self.options.format, | ||
| 120 | style=self.options.style, | ||
| 121 | xlabel=self.options.xlabel, | ||
| 122 | ylabel=self.options.ylabel, | ||
| 123 | xrange=self.options.xrange, | ||
| 124 | yrange=self.options.yrange, | ||
| 125 | xticks=self.options.xticks, | ||
| 126 | yticks=self.options.yticks, | ||
| 127 | fname=self.options.out) | ||
| 128 | |||
| 129 | def default(self, _): | ||
| 130 | cmd = self.get_cmd(list(self.args)) | ||
| 131 | pipe2gnuplot(cmd) | ||
| 132 | |||
| 133 | def do_cmd(self, _): | ||
| 134 | cmd = self.get_cmd(self.args[1:]) | ||
| 135 | self.out(cmd) | ||
| 136 | |||
| 137 | if __name__ == "__main__": | ||
| 138 | Plotter().launch() | ||
