graphkit 0.1.0.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +20 -0
- data/README.md +4 -0
- data/README.rdoc +19 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/graphkit.gemspec +64 -0
- data/lib/graphkit/csv.rb +140 -0
- data/lib/graphkit/gnuplot.rb +364 -245
- data/lib/graphkit/mm.rb +43 -0
- data/lib/graphkit/vtk_legacy_ruby.rb +550 -0
- data/lib/graphkit.rb +135 -11
- data/test/helper.rb +18 -0
- data/test/test_graphkit.rb +7 -0
- metadata +114 -51
data/lib/graphkit/gnuplot.rb
CHANGED
@@ -1,16 +1,99 @@
|
|
1
|
+
require 'matrix'
|
2
|
+
# Methods and variables for interacting with the gnuplot process. Most of
|
3
|
+
# these methods are for sending data to a gnuplot process, not for reading from
|
4
|
+
# it. Most of the methods are implemented as added methods to the built in
|
5
|
+
# classes.
|
6
|
+
|
7
|
+
module Gnuplot
|
8
|
+
|
9
|
+
# Trivial implementation of the which command that uses the PATH environment
|
10
|
+
# variable to attempt to find the given application. The application must
|
11
|
+
# be executable and reside in one of the directories in the PATH environment
|
12
|
+
# to be found. The first match that is found will be returned.
|
13
|
+
#
|
14
|
+
# bin [String] The name of the executable to search for.
|
15
|
+
#
|
16
|
+
# Return the full path to the first match or nil if no match is found.
|
17
|
+
#
|
18
|
+
def Gnuplot.which ( bin )
|
19
|
+
return bin if File::executable? bin
|
20
|
+
|
21
|
+
path = ENV['PATH'] # || ENV['WHAT_EVER_WINDOWS_PATH_VAR_IS']
|
22
|
+
path.split(File::PATH_SEPARATOR).each do |dir|
|
23
|
+
candidate = File::join dir, bin.strip
|
24
|
+
return candidate if File::executable? candidate
|
25
|
+
end
|
26
|
+
|
27
|
+
# This is an implementation that works when the which command is
|
28
|
+
# available.
|
29
|
+
#
|
30
|
+
# IO.popen("which #{bin}") { |io| return io.readline.chomp }
|
31
|
+
|
32
|
+
return nil
|
33
|
+
end
|
34
|
+
|
35
|
+
# Find the path to the gnuplot executable. The name of the executable can
|
36
|
+
# be specified using the RB_GNUPLOT environment variable but will default to
|
37
|
+
# the command 'gnuplot'.
|
38
|
+
#
|
39
|
+
# persist [bool] Add the persist flag to the gnuplot executable
|
40
|
+
#
|
41
|
+
# Return the path to the gnuplot executable or nil if one cannot be found.
|
42
|
+
def Gnuplot.gnuplot( persist = true )
|
43
|
+
cmd = which( ENV['RB_GNUPLOT'] || 'gnuplot' )
|
44
|
+
#cmd = "gnuplot"
|
45
|
+
cmd += " -background white"
|
46
|
+
cmd += " -persist" if persist
|
47
|
+
cmd
|
48
|
+
end
|
49
|
+
|
50
|
+
# Open a gnuplot process that exists in the current PATH. If the persist
|
51
|
+
# flag is true then the -persist flag is added to the command line. The
|
52
|
+
# path to the gnuplot executable is determined using the 'which' command.
|
53
|
+
#
|
54
|
+
# See the gnuplot documentation for information on the persist flag.
|
55
|
+
#
|
56
|
+
# <b>todo</b> Add a method to pass the gnuplot path to the function.
|
57
|
+
|
58
|
+
def Gnuplot.open( persist=true )
|
59
|
+
cmd = Gnuplot.gnuplot( persist ) or raise 'gnuplot not found'
|
60
|
+
#File.open(".gptemp#{Process.pid}", 'w'){|f| yield f}
|
61
|
+
#system "#{cmd} .gptemp#{Process.pid}"
|
62
|
+
#FileUtils.rm ".gptemp#{Process.pid}"
|
63
|
+
|
64
|
+
|
65
|
+
IO::popen( cmd, "w") { |io| yield io }
|
66
|
+
#yield(STDOUT)
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
end
|
72
|
+
|
1
73
|
|
2
74
|
class GraphKit
|
3
75
|
|
76
|
+
GNUPLOT_DEFAULT_TERM=ENV['GRAPHKIT_TERM'] || "x11"
|
77
|
+
GNUPLOT_DEFAULT_COLOURS = {0 => "#df0000", 1 => "#00df00", 2 => "#0000df", 3 => "#a000a0", 4 => "#0090a0", 5 => "#e59500", 6 => "#82c290", 7 => "#f76dba", 8 => "#c20f00", 9 => "#4f1099"}
|
78
|
+
|
79
|
+
class GnuplotVariables < KitHash
|
80
|
+
def apply(io)
|
81
|
+
self.each do |var,val|
|
82
|
+
ion << "#{var} = #{val}\n" if val
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
4
86
|
class GnuplotSetOptions < KitHash
|
5
87
|
alias :hash_key :key
|
6
88
|
undef :key
|
7
|
-
|
89
|
+
QUOTED = [ "title", "output", "xlabel", "ylabel", "zlabel", "x2label", "y2label", "z2label" ]
|
90
|
+
GNUPLOT_SETS = %w[ dgrid3d
|
8
91
|
angles arrow autoscale bars
|
9
92
|
bmargin border boxwidth cbdata
|
10
93
|
cbdtics cblabel cbmtics cbrange
|
11
94
|
cbtics clabel clip cntrparam
|
12
95
|
colorbox contour data datafile
|
13
|
-
date_specifiers decimalsign
|
96
|
+
date_specifiers decimalsign dummy
|
14
97
|
encoding fit fontpath format
|
15
98
|
function grid hidden3d historysize
|
16
99
|
isosamples key label lmargin
|
@@ -18,6 +101,7 @@ class GnuplotSetOptions < KitHash
|
|
18
101
|
macros mapping margin missing
|
19
102
|
mouse multiplot mx2tics mxtics
|
20
103
|
my2tics mytics mztics object
|
104
|
+
nosurface
|
21
105
|
offsets origin output palette
|
22
106
|
parametric pm3d pointsize polar
|
23
107
|
print rmargin rrange samples
|
@@ -51,19 +135,49 @@ class GnuplotSetOptions < KitHash
|
|
51
135
|
raise "#{opt} is not a valid gnuplot set option" unless GNUPLOT_SETS.include? opt
|
52
136
|
super
|
53
137
|
end
|
138
|
+
|
139
|
+
def apply(io)
|
140
|
+
self.each do |var,val|
|
141
|
+
next unless val
|
142
|
+
if val == "unset"
|
143
|
+
#eputs "Unsetting #{var}"
|
144
|
+
io << "unset #{var}\n"
|
145
|
+
next
|
146
|
+
end
|
147
|
+
if var.to_s == 'log_axis'
|
148
|
+
var = 'log'
|
149
|
+
end
|
150
|
+
if val.kind_of? Array
|
151
|
+
val.each do |vall|
|
152
|
+
io << "set #{var} #{vall}\n"
|
153
|
+
end
|
154
|
+
elsif QUOTED.include? var.to_s and not val =~ /^\s*'.*'/
|
155
|
+
#ep "quoting #{var}: #{val}"
|
156
|
+
io << "set #{var} '#{val}'\n"
|
157
|
+
else
|
158
|
+
io << "set #{var} #{val}\n"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
io << "set term #{GNUPLOT_DEFAULT_TERM}\n" unless self[:term]
|
162
|
+
end
|
163
|
+
|
164
|
+
|
54
165
|
end
|
55
166
|
|
167
|
+
|
168
|
+
|
56
169
|
class GnuplotPlotOptions < KitHash
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
170
|
+
QUOTED = ["title"]
|
171
|
+
GNUPLOT_SETS = %w[ function using axes title with ].map{|s| s.to_sym}
|
172
|
+
|
173
|
+
#%w[
|
174
|
+
#acsplines axes bezier binary
|
175
|
+
#csplines cumulative datafile errorbars
|
176
|
+
#errorlines every example frequency
|
177
|
+
#index iteration kdensity matrix
|
178
|
+
#parametric ranges sbezier smooth
|
179
|
+
#special-filenames style thru title
|
180
|
+
#unique using with].map{|s| s.to_sym}
|
67
181
|
# p instance_methods.sort
|
68
182
|
GNUPLOT_SETS.each do |opt|
|
69
183
|
define_method(opt + "=".to_sym) do |str|
|
@@ -80,23 +194,45 @@ class GnuplotPlotOptions < KitHash
|
|
80
194
|
raise "#{opt} is not a valid gnuplot set option" unless GNUPLOT_SETS.include? opt
|
81
195
|
super
|
82
196
|
end
|
197
|
+
def apply(io)
|
198
|
+
self[:function] ||= "'-'"
|
199
|
+
GNUPLOT_SETS.each do |var|
|
200
|
+
val = send(var)
|
201
|
+
next unless val
|
202
|
+
case var
|
203
|
+
when :function
|
204
|
+
io << " #{val} "
|
205
|
+
when :title
|
206
|
+
io << "#{var} '#{val}'"
|
207
|
+
else
|
208
|
+
if QUOTED.include? var.to_s and not val =~ Regexp.quoted_string
|
209
|
+
io << "#{var} '#{val}' "
|
210
|
+
else
|
211
|
+
io << "#{var} #{val} "
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
83
217
|
end
|
84
218
|
|
85
|
-
# class GraphKit < KitHash
|
86
219
|
|
87
|
-
def
|
88
|
-
|
89
|
-
@gnuplot_options
|
220
|
+
def gnuplot_sets
|
221
|
+
# gnuplot_options included for back. comp
|
222
|
+
self[:gnuplot_sets] ||= @gnuplot_options || GnuplotSetOptions.new
|
223
|
+
self[:gnuplot_sets]
|
90
224
|
end
|
91
|
-
|
92
|
-
alias :gp :gnuplot_options
|
225
|
+
alias :gp :gnuplot_sets
|
93
226
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
227
|
+
def gnuplot_variables
|
228
|
+
@gnuplot_variables ||= GnuplotVariables.new
|
229
|
+
end
|
230
|
+
alias :gv :gnuplot_variables
|
231
|
+
|
232
|
+
# Modify the graphkit according to the options hash
|
233
|
+
|
234
|
+
def apply_gnuplot_options(options)
|
235
|
+
options = options.dup # No reason to modify the original hash
|
100
236
|
logf :gnuplot
|
101
237
|
processes = %x[ps | grep 'gnuplot'].scan(/^\s*\d+/).map{|match| match.to_i}
|
102
238
|
if options[:outlier_tolerance]
|
@@ -108,107 +244,239 @@ end
|
|
108
244
|
end
|
109
245
|
options.delete(:outlier_tolerance)
|
110
246
|
end
|
111
|
-
live = options[:live]
|
247
|
+
self.live = options[:live]
|
112
248
|
options.delete(:live) if live
|
113
|
-
check_integrity
|
114
249
|
if (self.view =~ /map/ or self.pm3d =~ /map/) and naxes < 4
|
115
250
|
self.cbrange ||= self.zrange
|
116
251
|
options[:cbrange] ||= options[:zrange] if options[:zrange]
|
117
252
|
end
|
253
|
+
if options[:eval]
|
254
|
+
eval(options[:eval])
|
255
|
+
options.delete(:eval)
|
256
|
+
end
|
118
257
|
options.each do |k,v|
|
119
258
|
# ep option, val if option == :xrange
|
120
259
|
|
121
260
|
# ep k, v
|
122
261
|
set(k, v)
|
123
262
|
end
|
263
|
+
end
|
124
264
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
option = axis + property
|
134
|
-
val = self.send(option)
|
135
|
-
# ep option, val if option == :xrange
|
136
|
-
if val
|
137
|
-
|
138
|
-
if property == :range
|
139
|
-
val = "[#{val[0]}:#{val[1]}]"
|
140
|
-
end
|
141
|
-
plot.send(option, val)
|
142
|
-
end
|
265
|
+
def apply_graphkit_standard_options_to_gnuplot
|
266
|
+
[:label, :range].each do |property|
|
267
|
+
(AXES - [:f]).each do |axis|
|
268
|
+
option = axis + property
|
269
|
+
val = self.send(option)
|
270
|
+
if val
|
271
|
+
if property == :range
|
272
|
+
val = "[#{val[0]}:#{val[1]}]"
|
143
273
|
end
|
274
|
+
gp.set(option, val)
|
144
275
|
end
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
276
|
+
end
|
277
|
+
end
|
278
|
+
[:title].each do |option|
|
279
|
+
val = send(option)
|
280
|
+
gp.set(option, val) if val
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
private :apply_graphkit_standard_options_to_gnuplot
|
285
|
+
|
286
|
+
def gnuplot(options={})
|
287
|
+
apply_gnuplot_options(options)
|
288
|
+
apply_graphkit_standard_options_to_gnuplot
|
289
|
+
check_integrity
|
290
|
+
Gnuplot.open(true) do |io|
|
291
|
+
self.pid = io.pid
|
292
|
+
gnuplot_sets.apply(io)
|
293
|
+
gnuplot_variables.apply(io)
|
294
|
+
case naxes
|
295
|
+
when 1,2
|
296
|
+
io << "plot "
|
297
|
+
when 3,4
|
298
|
+
io << "splot "
|
153
299
|
end
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
#
|
159
|
-
|
160
|
-
|
161
|
-
|
300
|
+
imax = data.size - 1
|
301
|
+
data.each_with_index do |dk,i|
|
302
|
+
next if i>0 and compress_datakits
|
303
|
+
dk.gnuplot_plot_options.with ||= dk.with #b.c.
|
304
|
+
dk.gnuplot_plot_options.title ||= dk.title #b.c.
|
305
|
+
dk.gnuplot_plot_options.apply(io)
|
306
|
+
#p 'imax', imax, i, i == imax
|
307
|
+
next if compress_datakits
|
308
|
+
io << ", " unless i == imax
|
162
309
|
end
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
310
|
+
io << "\n"
|
311
|
+
data.each_with_index do |dk,i|
|
312
|
+
dk.gnuplot(io)
|
313
|
+
unless compress_datakits and i<imax
|
314
|
+
io << "e\n\n"
|
315
|
+
else
|
316
|
+
io << "\n\n"
|
317
|
+
end
|
168
318
|
end
|
169
|
-
|
170
|
-
|
319
|
+
(STDIN.gets) if live
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
def close
|
324
|
+
logf :close
|
325
|
+
begin
|
326
|
+
Process.kill('TERM', pid) if pid
|
327
|
+
rescue => err
|
328
|
+
puts err
|
329
|
+
end
|
330
|
+
self.pid = nil
|
331
|
+
end
|
332
|
+
|
333
|
+
|
334
|
+
class DataKit
|
335
|
+
def gnuplot_plot_options
|
336
|
+
self[:gnuplot_plot_options] ||= GnuplotPlotOptions.new
|
337
|
+
end
|
338
|
+
alias :gp :gnuplot_plot_options
|
339
|
+
|
340
|
+
class TensorArray
|
341
|
+
def initialize(arr)
|
342
|
+
@arr=arr
|
171
343
|
end
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
344
|
+
def [](*args)
|
345
|
+
args.reverse.inject(@arr) do |arr,idx|
|
346
|
+
arr[idx]
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
def gnuplot(io)
|
351
|
+
axs = self.axes.values_at(*AXES).compact
|
352
|
+
#ep 'axs', axs
|
353
|
+
dl = data_length = axs[-1].shape.product
|
354
|
+
dat = axs.map{|ax| ax.data}
|
355
|
+
sh = shapes
|
356
|
+
cml_sh = sh.map do |sh|
|
357
|
+
cml = 1
|
358
|
+
sh.reverse.map{|dim| cml *= dim; cml}.reverse
|
359
|
+
end
|
360
|
+
dat = dat.map do |d|
|
361
|
+
d.kind_of?(Array) ? TensorArray.new(d) : d
|
362
|
+
end
|
363
|
+
|
364
|
+
if self.errors
|
365
|
+
raise "Errors can only be plotted for 1D or 2D data" unless ranks == [1] or ranks == [1,1]
|
366
|
+
edat = self.errors.values_at(:x, :xmin, :xmax, :y, :ymin, :ymax).compact
|
367
|
+
#ep 'edat', edat
|
368
|
+
end
|
369
|
+
case ranks
|
370
|
+
when [1], [1,1], [1,1,1], [1,1,1,1]
|
371
|
+
dl.times do |n|
|
372
|
+
dat.each{|d| io << d[n] << " "}
|
373
|
+
io << " " << edat.map{|e| e[n].to_s}.join(" ") if self.errors
|
374
|
+
io << "\n"
|
375
|
+
end
|
376
|
+
when [1,1,2]
|
377
|
+
sh[-1][0].times do |i|
|
378
|
+
sh[-1][1].times do |j|
|
379
|
+
next unless dat[2][i,j]
|
380
|
+
d = [dat[0][i], dat[1][j], dat[2][i,j]]
|
381
|
+
d.each{|dt| io << dt << " "}
|
382
|
+
io << "\n"
|
383
|
+
end
|
384
|
+
io << "\n" unless sh[-1][1] == 1
|
385
|
+
end
|
386
|
+
when [2,2,2]
|
387
|
+
sh[-1][0].times do |i|
|
388
|
+
sh[-1][1].times do |j|
|
389
|
+
next unless dat[2][i,j]
|
390
|
+
d = [dat[0][i,j], dat[1][i,j], dat[2][i,j]]
|
391
|
+
d.each{|dt| io << dt << " "}
|
392
|
+
io << "\n"
|
393
|
+
end
|
394
|
+
io << "\n" unless sh[-1][1] == 1
|
395
|
+
end
|
396
|
+
when [1,1,2,2]
|
397
|
+
sh[-1][0].times do |i|
|
398
|
+
sh[-1][1].times do |j|
|
399
|
+
next unless dat[3][i,j]
|
400
|
+
d = [dat[0][i], dat[1][j], dat[2][i,j], dat[3][i,j]]
|
401
|
+
d.each{|dt| io << dt << " "}
|
402
|
+
io << "\n"
|
403
|
+
end
|
404
|
+
io << "\n" unless sh[-1][1] == 1
|
405
|
+
end
|
406
|
+
when [1,1,1,3]
|
407
|
+
sh[-1][0].times do |i|
|
408
|
+
sh[-1][1].times do |j|
|
409
|
+
sh[-1][2].times do |k|
|
410
|
+
next unless dat[3][i,j,k]
|
411
|
+
|
412
|
+
d = [dat[0][i], dat[1][j], dat[2][k], dat[3][i,j,k]]
|
413
|
+
d.each{|dt| io << dt << " "}
|
414
|
+
io << "\n"
|
415
|
+
end
|
416
|
+
io << "\n" unless sh[-1][2] == 1
|
417
|
+
end
|
418
|
+
io << "\n" unless sh[-1][1] == 1
|
419
|
+
end
|
420
|
+
when [2,2,2,2]
|
421
|
+
sh[-1][0].times do |i|
|
422
|
+
sh[-1][1].times do |j|
|
423
|
+
next unless dat[3][i,j]
|
424
|
+
d = [dat[0][i,j], dat[1][i,j], dat[2][i,j], dat[3][i,j]]
|
425
|
+
d.each{|dt| io << dt << " "}
|
426
|
+
io << "\n"
|
427
|
+
end
|
428
|
+
io << "\n" unless sh[-1][1] == 1
|
429
|
+
end
|
430
|
+
when [3,3,3,3]
|
431
|
+
#pp dat
|
432
|
+
#pp dat
|
433
|
+
#pp sh
|
434
|
+
sh[-1][0].times do |i|
|
435
|
+
sh[-1][1].times do |j|
|
436
|
+
sh[-1][2].times do |k|
|
437
|
+
next unless dat[3][i,j,k]
|
438
|
+
#p [i,j,k]
|
439
|
+
|
440
|
+
#d = [dat[0][i,j,k], dat[1][i,j,k], dat[2][i,j,k], dat[3][i,j,k]]
|
441
|
+
io << "#{dat[0][i,j,k]} #{dat[1][i,j,k]} #{dat[2][i,j,k]} #{dat[3][i,j,k]} \n"
|
442
|
+
#d.each{|dt| io << dt << " "}
|
443
|
+
#io << "\n"
|
444
|
+
end
|
445
|
+
io << "\n" unless sh[-1][2] == 1
|
446
|
+
end
|
447
|
+
io << "\n" unless sh[-1][1] == 1
|
448
|
+
end
|
181
449
|
end
|
182
|
-
log 'sent plotproc'
|
183
|
-
(STDIN.gets) if live
|
184
450
|
|
185
451
|
end
|
186
|
-
self.pid = (%x[ps | grep 'gnuplot'].scan(/^\s*\d+/).map{|match| match.to_i} - processes)[-1]
|
187
|
-
# p pid
|
188
452
|
end
|
189
|
-
|
190
|
-
|
453
|
+
|
454
|
+
|
455
|
+
|
191
456
|
def gnuplot_write(file_name, options={})
|
192
457
|
logf :gnuplot_write
|
193
458
|
if file_name
|
194
|
-
|
195
|
-
unless
|
459
|
+
gp.output = file_name
|
460
|
+
unless gp.term or options[:terminal]
|
196
461
|
case File.extname(file_name)
|
197
462
|
when '.pdf'
|
198
|
-
|
463
|
+
gp.term = 'pdf size 20cm,15cm'
|
199
464
|
when '.ps'
|
200
|
-
|
465
|
+
gp.term = 'post color'
|
201
466
|
when '.eps'
|
202
467
|
unless options[:latex]
|
203
|
-
|
468
|
+
gp.term = %[post eps color enhanced size #{options[:size] or "3.5in,2.33in"}]
|
204
469
|
else
|
205
|
-
|
206
|
-
options[:
|
470
|
+
gp.term ||= "epslatex color dashed size #{options[:size] or "3.5in,#{options[:height] or "2.0in"}"} colortext standalone 8"
|
471
|
+
(gp.term += " header '#{options[:preamble].inspect.gsub(/\\\n/, "\\\\\\n")}'"; options.delete(:preamble)) if options[:preamble]
|
472
|
+
gp.output = file_name.sub(/\.eps/, '.tex')
|
207
473
|
end
|
208
474
|
when '.jpg'
|
209
|
-
|
475
|
+
gp.term = "jpeg size #{options[:size] or "3.5in,2.33in"}"
|
210
476
|
when '.png'
|
211
|
-
|
477
|
+
gp.term = "png size #{options[:size] or "640,480"}"
|
478
|
+
when '.gif'
|
479
|
+
gp.term = "gif size #{options[:size] or "640,480"}"
|
212
480
|
|
213
481
|
end
|
214
482
|
end
|
@@ -218,7 +486,7 @@ end
|
|
218
486
|
if options[:latex]
|
219
487
|
name = file_name.sub(/\.eps$/, '')
|
220
488
|
raise 'latex failed' unless system "latex #{name}.tex"
|
221
|
-
raise 'dvips failed' unless system "dvips #{name}.dvi"
|
489
|
+
raise 'dvips failed' unless system "dvips #{name}.dvi -o #{name}.ps"
|
222
490
|
FileUtils.rm "#{name}.eps" if FileTest.exist? "#{name}.eps"
|
223
491
|
raise 'ps2eps failed' unless system "ps2eps #{name}.ps"
|
224
492
|
end
|
@@ -229,9 +497,10 @@ end
|
|
229
497
|
def self.latex_multiplot(name, options={})
|
230
498
|
name = name.sub(/\.eps$/, '')
|
231
499
|
figure_preamble = options[:preamble] || <<EOF
|
232
|
-
\\documentclass[
|
500
|
+
\\documentclass[graphicx,reprint,twocolumn]{revtex4}
|
233
501
|
%\documentclass[aip,reprint]{revtex4-1}
|
234
|
-
\\usepackage{graphics,bm,overpic,
|
502
|
+
\\usepackage{graphics,bm,overpic,color}
|
503
|
+
\\usepackage[tight]{subfigure}
|
235
504
|
|
236
505
|
\\pagestyle{empty}
|
237
506
|
\\begin{document}
|
@@ -254,159 +523,9 @@ EOF
|
|
254
523
|
raise 'ps2eps failed' unless system "ps2eps #{name}.ps"
|
255
524
|
end
|
256
525
|
|
257
|
-
def close
|
258
|
-
logf :close
|
259
|
-
begin
|
260
|
-
Process.kill('TERM', pid) if pid
|
261
|
-
rescue => err
|
262
|
-
puts err
|
263
|
-
end
|
264
|
-
self.pid = nil
|
265
|
-
end
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
# end
|
270
|
-
|
271
|
-
class DataKit < KitHash
|
272
|
-
|
273
|
-
|
274
|
-
def gnuplot_ranks
|
275
|
-
case axes.size
|
276
|
-
when 1,2
|
277
|
-
return ranks
|
278
|
-
when 3
|
279
|
-
return [1,1,2]
|
280
|
-
when 4
|
281
|
-
case ranks[2]
|
282
|
-
when 1
|
283
|
-
return [1,1,1,3]
|
284
|
-
when 2
|
285
|
-
return [1,1,2,2]
|
286
|
-
end
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
def gnuplot
|
291
|
-
# p axes.values_at(*AXES).compact.zip(gnuplot_ranks)
|
292
|
-
Gnuplot::DataSet.new(axes.values_at(*AXES).compact.zip(gnuplot_ranks).map{|axis, rank| axis.data_for_gnuplot(rank) }) do |ds|
|
293
|
-
(keys - [:axes, :outlier_tolerance, :outliers, :gnuplot_options]).each do |key|
|
294
|
-
ds.set(key, self[key])
|
295
|
-
end
|
296
|
-
if @gnuplot_options
|
297
|
-
@gnuplot_options.each do |opt, val|
|
298
|
-
ds.set(opt, val)
|
299
|
-
end
|
300
|
-
end
|
301
|
-
# ds.title = title
|
302
|
-
# ds.with = [:lines, :points].inject(""){|str, opt| self[opt] ? str + opt.to_s : str }
|
303
|
-
# p ds.with
|
304
|
-
# ds.with = "lines"
|
305
|
-
# ds.linewidth = 4
|
306
|
-
end
|
307
|
-
end
|
308
|
-
|
309
|
-
def gnuplot_options
|
310
|
-
@gnuplot_options ||= GnuplotPlotOptions.new
|
311
|
-
@gnuplot_options
|
312
|
-
end
|
313
|
-
|
314
|
-
alias :gp :gnuplot_options
|
315
526
|
|
316
|
-
|
317
|
-
end
|
318
527
|
|
319
528
|
|
320
|
-
class AxisKit < KitHash
|
321
|
-
|
322
529
|
|
323
|
-
def data_for_gnuplot(rank)
|
324
|
-
case rank
|
325
|
-
when 0, 1
|
326
|
-
return data
|
327
|
-
when Fixnum
|
328
|
-
if shape.size == 1
|
329
|
-
return SparseTensor.diagonal(rank, data)
|
330
|
-
else
|
331
|
-
return data
|
332
|
-
end
|
333
|
-
else
|
334
|
-
raise TypeError("Bad Rank")
|
335
|
-
end
|
336
530
|
end
|
337
|
-
|
338
|
-
end
|
339
|
-
|
340
|
-
end # class GraphKit
|
341
|
-
# end #class CodeRunner
|
342
|
-
|
343
|
-
|
344
|
-
if $0 == __FILE__
|
345
|
-
|
346
|
-
a = CodeRunner::GraphKit.autocreate({x: {data: [1,3,5,6], units: 'feet', title: 'Height'}})
|
347
|
-
a.gnuplot
|
348
|
-
gets
|
349
|
-
a.close
|
350
|
-
a = CodeRunner::GraphKit.autocreate({x: {data: [2, 5, 11, 22], units: 'years', title: 'Age'}, y: {data: [1,3,5,6], units: 'feet', title: 'Height'}})
|
351
|
-
|
352
|
-
puts a.pretty_inspect
|
353
|
-
|
354
|
-
p a.title
|
355
|
-
p a.label
|
356
|
-
p a.chox
|
357
|
-
p a.xlabel
|
358
|
-
p a.yunits
|
359
|
-
|
360
|
-
# a.gnuplot
|
361
|
-
# gets
|
362
|
-
# a.close
|
363
|
-
a.data[0].with = 'lp'
|
364
|
-
datakit = a.data[0].dup
|
365
|
-
datakit.axes[:y].data.map!{|value| value * 0.85}
|
366
|
-
datakit.title += ' of women'
|
367
|
-
a.data.push datakit
|
368
|
-
a.data[0].title += ' of men'
|
369
|
-
pp a
|
370
|
-
a.gnuplot
|
371
|
-
gets
|
372
|
-
a.close
|
373
|
-
# Gnuplot.open{a.to_gnuplot}
|
374
|
-
|
375
|
-
b = CodeRunner::GraphKit.autocreate({x: {data: [2, 5, 11, 22], units: 'years', title: 'Age'}, y: {data: [1,3,5,6], units: 'feet', title: 'Height'}, z: {data: [2,4,8,12], units: 'stone', title: 'Weight'}})
|
376
|
-
b.data[0].modify({with: 'lp'})
|
377
|
-
pp b
|
378
|
-
# d = b.data[0].f.data_for_gnuplot(2)
|
379
|
-
# p d
|
380
|
-
# p d[0,1]
|
381
|
-
# d.delete([0,0])
|
382
|
-
# p d
|
383
|
-
# p d[1,1]
|
384
|
-
# p d[1,2]
|
385
|
-
# d = SparseTensor.new(3)
|
386
|
-
# p d
|
387
|
-
# p d[0,1,4]
|
388
|
-
# p d[3, 4,6]
|
389
|
-
#
|
390
|
-
b.gnuplot
|
391
|
-
gets
|
392
|
-
b.close
|
393
|
-
b.gnuplot_write('heights.ps')
|
394
|
-
|
395
|
-
p b.data[0].plot_area_size
|
396
|
-
|
397
|
-
c = SparseTensor.new(3)
|
398
|
-
c[1,3,9]= 4
|
399
|
-
c[3,3,34] = 4.346
|
400
|
-
c[23, 234, 293] = 9.234
|
401
|
-
|
402
|
-
p c
|
403
|
-
|
404
|
-
d = SparseTensor.new(3)
|
405
|
-
d[1,3,9]= 4
|
406
|
-
d[3,3,34] = 4.346
|
407
|
-
d[23, 234, 294] = 9.234
|
408
|
-
|
409
|
-
p c + d
|
410
|
-
|
411
|
-
end
|
412
|
-
|
531
|
+
|