diff options
| author | Björn B. Brandenburg <bbb@cs.unc.edu> | 2010-05-25 13:35:36 -0400 |
|---|---|---|
| committer | Björn B. Brandenburg <bbb@cs.unc.edu> | 2010-05-25 13:35:36 -0400 |
| commit | 707f7ed573c29581bc6a050257a0b6e8970a5553 (patch) | |
| tree | 17001272c826f8513dd844749d8a66fd5d944709 | |
| parent | ab01739fd3d30d3c808ed1773a2748d1f890f4d6 (diff) | |
add object-oriented interface to gnuplot
Create a plot, configure it as desired, then
executed. In the long run, this should make it
easier to customize "default styles" for
individual papers without changing the look
of old paper styles.
| -rwxr-xr-x | gnuplot.py | 179 |
1 files changed, 175 insertions, 4 deletions
| @@ -6,6 +6,13 @@ from optparse import make_option as o | |||
| 6 | FORMATS = ['png', 'eps', 'pdf', 'show', 'ps'] | 6 | FORMATS = ['png', 'eps', 'pdf', 'show', 'ps'] |
| 7 | STYLES = ['points', 'lines', 'linespoints'] | 7 | STYLES = ['points', 'lines', 'linespoints'] |
| 8 | 8 | ||
| 9 | TERMINALS = { | ||
| 10 | 'png' : 'png', | ||
| 11 | 'eps' : 'postscript eps', | ||
| 12 | 'ps' : 'postscript', | ||
| 13 | 'pdf' : 'pdf', | ||
| 14 | } | ||
| 15 | |||
| 9 | class CommandBuffer(object): | 16 | class CommandBuffer(object): |
| 10 | def __init__(self): | 17 | def __init__(self): |
| 11 | self.cmds = [] | 18 | self.cmds = [] |
| @@ -16,6 +23,21 @@ class CommandBuffer(object): | |||
| 16 | def __str__(self): | 23 | def __str__(self): |
| 17 | return '\n'.join([str(x) for x in self.cmds]) | 24 | return '\n'.join([str(x) for x in self.cmds]) |
| 18 | 25 | ||
| 26 | |||
| 27 | class Label(object): | ||
| 28 | def __init__(self, x, y, txt): | ||
| 29 | self.x = x | ||
| 30 | self.y = y | ||
| 31 | self.txt = txt | ||
| 32 | # support more label stuff optionally... | ||
| 33 | |||
| 34 | def gnuplot_cmd(self): | ||
| 35 | return '"%s" at %f,%f center' % (self.txt, self.x, self.y) | ||
| 36 | |||
| 37 | def __str__(self): | ||
| 38 | return 'set label %s' % self.gnuplot_cmd() | ||
| 39 | |||
| 40 | |||
| 19 | class FileGraph(object): | 41 | class FileGraph(object): |
| 20 | def __init__(self, fname, xcol=1, ycol=2, error=None, | 42 | def __init__(self, fname, xcol=1, ycol=2, error=None, |
| 21 | title=None, | 43 | title=None, |
| @@ -25,12 +47,12 @@ class FileGraph(object): | |||
| 25 | self.ycol = ycol | 47 | self.ycol = ycol |
| 26 | self.error = error | 48 | self.error = error |
| 27 | self.title = title | 49 | self.title = title |
| 28 | self.style = style | 50 | self.style = style # replace with linetype, lines/points etc. |
| 29 | 51 | ||
| 30 | def __str__(self): | 52 | def __str__(self): |
| 31 | return self.get_command() | 53 | return self.gnuplot_cmd() |
| 32 | 54 | ||
| 33 | def get_command(self, default_style=None): | 55 | def gnuplot_cmd(self, default_style=None): |
| 34 | if self.error: | 56 | if self.error: |
| 35 | using_txt = "%s:%s:%s" % (self.xcol, self.ycol, self.error) | 57 | using_txt = "%s:%s:%s" % (self.xcol, self.ycol, self.error) |
| 36 | style = self.style if self.style else "errorbars" | 58 | style = self.style if self.style else "errorbars" |
| @@ -42,6 +64,155 @@ class FileGraph(object): | |||
| 42 | return "'%s' using %s%s%s" % \ | 64 | return "'%s' using %s%s%s" % \ |
| 43 | (self.fname, using_txt, title_txt, style_txt) | 65 | (self.fname, using_txt, title_txt, style_txt) |
| 44 | 66 | ||
| 67 | |||
| 68 | class LiteralGraph(object): | ||
| 69 | def __init__(self, literal_expr, title=None, style=None): | ||
| 70 | self.expr = literal_expr | ||
| 71 | self.title = title | ||
| 72 | self.style = style | ||
| 73 | |||
| 74 | def __str__(self): | ||
| 75 | return self.gnuplot_cmd() | ||
| 76 | |||
| 77 | def gnuplot_cmd(self, default_style=None): | ||
| 78 | style = self.style if self.style else default_style | ||
| 79 | style_txt = " with %s" % style if style else "" | ||
| 80 | title_txt = " title '%s'" % self.title if self.title else "" | ||
| 81 | return "%s %s%s" % \ | ||
| 82 | (self.expr, title_txt, style_txt) | ||
| 83 | |||
| 84 | |||
| 85 | label = Label | ||
| 86 | |||
| 87 | def curve(fname=None, literal=None, **kargs): | ||
| 88 | if fname: | ||
| 89 | return FileGraph(fname, **kargs) | ||
| 90 | elif literal: | ||
| 91 | return LiteralGraph(literal, **kargs) | ||
| 92 | |||
| 93 | |||
| 94 | class Plot(object): | ||
| 95 | def __init__(self): | ||
| 96 | self.format = None | ||
| 97 | self.output = None | ||
| 98 | self.size = None | ||
| 99 | |||
| 100 | self.font = None | ||
| 101 | self.font_size = None | ||
| 102 | self.enhanced_text = None | ||
| 103 | |||
| 104 | self.monochrome = None | ||
| 105 | self.dashed_lines = None | ||
| 106 | self.rounded_caps = None | ||
| 107 | |||
| 108 | self.xrange = None | ||
| 109 | self.xticks = None | ||
| 110 | self.xlog = None | ||
| 111 | self.xlabel = None | ||
| 112 | |||
| 113 | self.yrange = None | ||
| 114 | self.yticks = None | ||
| 115 | self.ylog = None | ||
| 116 | self.ylabel = None | ||
| 117 | |||
| 118 | self.key = None | ||
| 119 | self.title = None | ||
| 120 | |||
| 121 | self.labels = [] | ||
| 122 | self.curves = [] | ||
| 123 | |||
| 124 | def gnuplot_commands(self, cmd_buf=None): | ||
| 125 | if cmd_buf: | ||
| 126 | g = cmd_buf | ||
| 127 | else: | ||
| 128 | g = CommandBuffer() | ||
| 129 | |||
| 130 | def isset(x): | ||
| 131 | return not (x is None) | ||
| 132 | |||
| 133 | if isset(self.format): | ||
| 134 | term = [TERMINALS[self.format]] | ||
| 135 | else: | ||
| 136 | term = 'x11' | ||
| 137 | |||
| 138 | ps_like = self.format in ['eps', 'pdf', 'ps'] | ||
| 139 | |||
| 140 | if isset(self.monochrome) and ps_like: | ||
| 141 | term += ['monochrome' if self.monochrome else 'color'] | ||
| 142 | |||
| 143 | if isset(self.enhanced_text): | ||
| 144 | term += ['enhanced' if self.enhanced_text else 'noenhanced'] | ||
| 145 | |||
| 146 | if isset(self.dashed_lines) and ps_like: | ||
| 147 | term += ['dashed' if self.dashed_lines else 'solid'] | ||
| 148 | if isset(self.font) and ps_like: | ||
| 149 | term += ['font "%s%s"' % | ||
| 150 | (self.font, | ||
| 151 | (",%s" % self.font_size) if isset(self.font_size) | ||
| 152 | else "") | ||
| 153 | ] | ||
| 154 | |||
| 155 | if isset(self.rounded_caps): | ||
| 156 | term += ['rounded' if self.rounded_caps else 'butt'] | ||
| 157 | |||
| 158 | if isset(self.size): | ||
| 159 | term += ['size %s,%s' % (self.size)] | ||
| 160 | |||
| 161 | if isset(self.font_size) and self.format == 'png': | ||
| 162 | term += [self.font_size] | ||
| 163 | |||
| 164 | g("set terminal %s" % " ".join(term)) | ||
| 165 | if isset(self.output): | ||
| 166 | g("set out '/dev/null'") | ||
| 167 | |||
| 168 | if self.xrange: | ||
| 169 | g("set xrange [%s:%s]" % self.xrange) | ||
| 170 | if self.xticks: | ||
| 171 | g("set xtics %s, %s" % self.xticks) | ||
| 172 | if self.xlabel: | ||
| 173 | g("set xlabel '%s'" % self.xlabel) | ||
| 174 | |||
| 175 | if self.yrange: | ||
| 176 | g("set yrange [%s:%s]" % self.yrange) | ||
| 177 | if self.yticks: | ||
| 178 | g("set ytics %s, %s" % self.yticks) | ||
| 179 | if self.ylabel: | ||
| 180 | g("set ylabel '%s'" % self.ylabel) | ||
| 181 | |||
| 182 | if self.key: | ||
| 183 | g('set key %s' % self.key) | ||
| 184 | if self.title: | ||
| 185 | g("set title '%s'" % self.title) | ||
| 186 | |||
| 187 | logscale = "" | ||
| 188 | if self.xlog: | ||
| 189 | logscale += "x" | ||
| 190 | if self.ylog: | ||
| 191 | logscale += "y" | ||
| 192 | if logscale: | ||
| 193 | g("set logscale %s" % logscale) | ||
| 194 | |||
| 195 | plots = [c.gnuplot_cmd() for c in self.curves] | ||
| 196 | if plots: | ||
| 197 | g("plot " + ", ".join(plots)) | ||
| 198 | |||
| 199 | for l in self.labels: | ||
| 200 | g("set label " + l.gnuplot_cmd()) | ||
| 201 | |||
| 202 | if isset(self.output): | ||
| 203 | g("set out '%s'" % self.output) | ||
| 204 | |||
| 205 | g("replot") | ||
| 206 | |||
| 207 | if isset(self.output): | ||
| 208 | g("set out") # close file | ||
| 209 | |||
| 210 | return g | ||
| 211 | |||
| 212 | |||
| 213 | def gnuplot_exec(self): | ||
| 214 | pipe2gnuplot(self.gnuplot_commands()) | ||
| 215 | |||
| 45 | def gnuplot_cmd(graphs, title=None, ylabel=None, xlabel=None, | 216 | def gnuplot_cmd(graphs, title=None, ylabel=None, xlabel=None, |
| 46 | format='show', term_opts=None, | 217 | format='show', term_opts=None, |
| 47 | style='linespoints', xrange=None, | 218 | style='linespoints', xrange=None, |
| @@ -99,7 +270,7 @@ def gnuplot_cmd(graphs, title=None, ylabel=None, xlabel=None, | |||
| 99 | plot.append(str(gr)) | 270 | plot.append(str(gr)) |
| 100 | elif type(gr) == FileGraph: | 271 | elif type(gr) == FileGraph: |
| 101 | # formatter object | 272 | # formatter object |
| 102 | plot.append(gr.get_command(style)) | 273 | plot.append(gr.gnuplot_cmd(style)) |
| 103 | elif len(gr) == 4: | 274 | elif len(gr) == 4: |
| 104 | par = (gr[0], gr[1], gr[2], gr[3], style) | 275 | par = (gr[0], gr[1], gr[2], gr[3], style) |
| 105 | plot += ["'%s' using %s:%s title '%s' with %s" % par] | 276 | plot += ["'%s' using %s:%s title '%s' with %s" % par] |
