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] |