numo-gnuplot 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +54 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +153 -0
- data/Rakefile +2 -0
- data/examples/all.rb +20 -0
- data/examples/ex001.rb +7 -0
- data/examples/ex002.rb +11 -0
- data/examples/ex003.rb +10 -0
- data/examples/ex004.rb +6 -0
- data/examples/ex005.rb +11 -0
- data/examples/ex010.rb +14 -0
- data/examples/ex011.rb +22 -0
- data/lib/numo/gnuplot.rb +493 -0
- data/numo-gnuplot.gemspec +31 -0
- data/setup.rb +1295 -0
- metadata +88 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 7a5482f076a126f3270d221c2ad38455ac266b6a
|
|
4
|
+
data.tar.gz: 1115269a4c0e558c2272f14b36e591e41d26bd28
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 0cb38d93f404dca82818117ae8f7620c160bbd3eb3e6f3abfcf3a2d9cd44b05d2d3a445b6f2592b6011446fd7038a0da6f4660131a659c1cefb976484e0f5161
|
|
7
|
+
data.tar.gz: 76b7602cd0fe6f0e23e5a62dddc01ff63cf5064ad54a5bf8a3d8594dfcec9d600990a81dc539c72cfc490ad0b3913220f1214ca70b94f734a4e1286b3c7a0742
|
data/.gitignore
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
*.gem
|
|
2
|
+
*.rbc
|
|
3
|
+
Gemfile.lock
|
|
4
|
+
InstalledFiles
|
|
5
|
+
SetupConfig
|
|
6
|
+
SetupReceipt
|
|
7
|
+
coverage
|
|
8
|
+
pkg/
|
|
9
|
+
spec/reports
|
|
10
|
+
spec/examples.txt
|
|
11
|
+
spec/*/*.dat
|
|
12
|
+
spec/*/*.csv
|
|
13
|
+
test/tmp
|
|
14
|
+
test/version_tmp
|
|
15
|
+
tmp/
|
|
16
|
+
.config
|
|
17
|
+
*~
|
|
18
|
+
*/*~
|
|
19
|
+
*/*/*~
|
|
20
|
+
*.bak
|
|
21
|
+
*/*.bak
|
|
22
|
+
*/*/*.bak
|
|
23
|
+
.#*
|
|
24
|
+
*/.#*
|
|
25
|
+
*/*/.#*
|
|
26
|
+
rhosts
|
|
27
|
+
|
|
28
|
+
## Specific to RubyMotion:
|
|
29
|
+
.dat*
|
|
30
|
+
.repl_history
|
|
31
|
+
build/
|
|
32
|
+
|
|
33
|
+
## Documentation cache and generated files:
|
|
34
|
+
.yardoc/
|
|
35
|
+
_yardoc/
|
|
36
|
+
doc/
|
|
37
|
+
rdoc/
|
|
38
|
+
|
|
39
|
+
## Environment normalization:
|
|
40
|
+
.bundle/
|
|
41
|
+
/vendor/bundle
|
|
42
|
+
/lib/bundler/man/
|
|
43
|
+
|
|
44
|
+
# for a library or gem, you might want to ignore these files since the code is
|
|
45
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
46
|
+
# Gemfile.lock
|
|
47
|
+
# .ruby-version
|
|
48
|
+
# .ruby-gemset
|
|
49
|
+
|
|
50
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
|
51
|
+
.rvmrc
|
|
52
|
+
|
|
53
|
+
# examples
|
|
54
|
+
/examples/*.png
|
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2016 Masahiro TANAKA
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Numo::Gnuplot : Gnuplot interface for Ruby
|
|
2
|
+
|
|
3
|
+
* Alpha version under development.
|
|
4
|
+
* [GitHub site](https://github.com/masa16/numo-gnuplot)
|
|
5
|
+
|
|
6
|
+
Although there are many [other Gnuplot interface libraries for Ruby](https://github.com/masa16/numo-gnuplot#related-work),
|
|
7
|
+
none of them have so simple interface as to obtain an XY data plot by just typing:
|
|
8
|
+
|
|
9
|
+
plot x,y
|
|
10
|
+
|
|
11
|
+
Numo::Gnuplot achieves this by providing only one class which has
|
|
12
|
+
the same inteface as Gnuplot command line, and no other class which
|
|
13
|
+
causes extra learning costs.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
Add this line to your application's Gemfile:
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
gem 'numo-gnuplot'
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
And then execute:
|
|
24
|
+
|
|
25
|
+
$ bundle
|
|
26
|
+
|
|
27
|
+
Or install it yourself as:
|
|
28
|
+
|
|
29
|
+
$ gem install numo-gnuplot
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
* All examples require to load Numo::Gnuplot class:
|
|
34
|
+
|
|
35
|
+
```ruby
|
|
36
|
+
require "numo/gnuplot"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
* The first example showing how it works.
|
|
40
|
+
|
|
41
|
+
```ruby
|
|
42
|
+
gp = Numo::Gnuplot.new
|
|
43
|
+
gp.set title:"First Example"
|
|
44
|
+
gp.plot "sin(x)"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
* You can avoid receiver.
|
|
48
|
+
|
|
49
|
+
```ruby
|
|
50
|
+
Numo::Gnuplot.new.instance_eval do
|
|
51
|
+
set title:"Second Example"
|
|
52
|
+
plot "sin(x)"
|
|
53
|
+
end
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
* The same thing in short.
|
|
57
|
+
|
|
58
|
+
```ruby
|
|
59
|
+
Numo.gnuplot do
|
|
60
|
+
set title:"Third Example"
|
|
61
|
+
plot "sin(x)"
|
|
62
|
+
end
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
* Interactive plotting with IRB:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
$ irb -r numo/gnuplot
|
|
69
|
+
irb(main):001:0> pushb Numo.gnuplot
|
|
70
|
+
irb(gnuplot):002:0> set t:"Forth Example"
|
|
71
|
+
irb(gnuplot):003:0> plot "sin(x)"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
* Plotting X-Y data.
|
|
75
|
+
|
|
76
|
+
```ruby
|
|
77
|
+
require "numo/gnuplot"
|
|
78
|
+
|
|
79
|
+
x = (0..100).map{|i| i*0.1}
|
|
80
|
+
y = x.map{|i| Math.sin(i)}
|
|
81
|
+
|
|
82
|
+
Numo.gnuplot do
|
|
83
|
+
set title:"X-Y data plot"
|
|
84
|
+
plot x,y, w:'lines', t:'sin(x)'
|
|
85
|
+
end
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
* Plotting X-Y data in NArray.
|
|
89
|
+
|
|
90
|
+
```ruby
|
|
91
|
+
require "numo/gnuplot"
|
|
92
|
+
require "numo/narray"
|
|
93
|
+
|
|
94
|
+
x = Numo::DFloat[0..100]/10
|
|
95
|
+
y = Numo::NMath.sin(x)
|
|
96
|
+
|
|
97
|
+
Numo.gnuplot do
|
|
98
|
+
set title:"X-Y data plot in Numo::NArray"
|
|
99
|
+
plot x,y, w:'lines', t:'sin(x)'
|
|
100
|
+
end
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
* Multiple data are separated by Hash or put into Array.
|
|
104
|
+
|
|
105
|
+
```ruby
|
|
106
|
+
require 'numo/gnuplot'
|
|
107
|
+
require 'numo/narray'
|
|
108
|
+
NM = Numo::NMath
|
|
109
|
+
|
|
110
|
+
n = 60
|
|
111
|
+
x = Numo::DFloat[-n..n]/n*10
|
|
112
|
+
|
|
113
|
+
Numo.gnuplot do
|
|
114
|
+
set title:"multiple data series"
|
|
115
|
+
# separate by Hash
|
|
116
|
+
plot x,NM.sin(x), {w:'points',t:'sin(x)'}, x,x*NM.sin(x),{w:"lines",t:'x*sin(x)'}
|
|
117
|
+
# or separate into Array
|
|
118
|
+
# plot [x,NM.sin(x), w:'points',t:'sin(x)'], [x,x*NM.sin(x),w:"lines",t:'x*sin(x)']
|
|
119
|
+
# (here last item in each Array should be Hash in order to distinguish from array data)
|
|
120
|
+
gets
|
|
121
|
+
end
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
* Plotting 2D arrays in 3D.
|
|
125
|
+
|
|
126
|
+
```ruby
|
|
127
|
+
require 'numo/gnuplot'
|
|
128
|
+
require 'numo/narray'
|
|
129
|
+
|
|
130
|
+
n = 60
|
|
131
|
+
x = (Numo::DFloat.new(1,n).seq/n-0.5)*30
|
|
132
|
+
y = (Numo::DFloat.new(n,1).seq/n-0.5)*30
|
|
133
|
+
r = Numo::NMath.sqrt(x**2+y**2) + 1e-10
|
|
134
|
+
z = Numo::NMath.sin(r)/r
|
|
135
|
+
|
|
136
|
+
Numo.gnuplot do
|
|
137
|
+
set title:'2D data plot'
|
|
138
|
+
set dgrid3d:[60,60]
|
|
139
|
+
splot z, w:'pm3d', t:'sin(r)/r'
|
|
140
|
+
end
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Related Work
|
|
144
|
+
|
|
145
|
+
* [Ruby Gnuplot](https://github.com/rdp/ruby_gnuplot/tree/master)
|
|
146
|
+
* [GNUPlotr](https://github.com/pbosetti/gnuplotr)
|
|
147
|
+
* [GnuPlotter](https://github.com/maasha/gnuplotter)
|
|
148
|
+
* [GnuplotRB](https://github.com/dilcom/gnuplotrb)
|
|
149
|
+
|
|
150
|
+
## Contributing
|
|
151
|
+
|
|
152
|
+
Bug reports and pull requests are welcome on GitHub at
|
|
153
|
+
https://github.com/[USERNAME]/numo-gnuplot.
|
data/Rakefile
ADDED
data/examples/all.rb
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require "numo/gnuplot"
|
|
2
|
+
|
|
3
|
+
gp = Numo.gnuplot
|
|
4
|
+
|
|
5
|
+
puts "mouse/key on window to continue"
|
|
6
|
+
Dir.glob("ex*.rb") do |frb|
|
|
7
|
+
gp.reset
|
|
8
|
+
load frb
|
|
9
|
+
gp.pause mouse:"any"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
gp.set term:"png"
|
|
13
|
+
|
|
14
|
+
Dir.glob("ex*.rb") do |frb|
|
|
15
|
+
fimg = File.basename(frb,".rb")+".png"
|
|
16
|
+
gp.reset
|
|
17
|
+
gp.set output:fimg
|
|
18
|
+
load frb
|
|
19
|
+
puts "wrote #{fimg}"
|
|
20
|
+
end
|
data/examples/ex001.rb
ADDED
data/examples/ex002.rb
ADDED
data/examples/ex003.rb
ADDED
data/examples/ex004.rb
ADDED
data/examples/ex005.rb
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'numo/narray'
|
|
2
|
+
|
|
3
|
+
# multiple data series plot (Hash separated)
|
|
4
|
+
n = 60
|
|
5
|
+
x = Numo::DFloat[-n..n]/n*10
|
|
6
|
+
nm = Numo::NMath
|
|
7
|
+
|
|
8
|
+
Numo.gnuplot do
|
|
9
|
+
set title:"multiple data series plot"
|
|
10
|
+
plot x,nm.sin(x), {w:'points',t:'sin(x)'}, x,x*nm.sin(x),{w:"lines",t:'x*sin(x)'}
|
|
11
|
+
end
|
data/examples/ex010.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require "numo/narray"
|
|
2
|
+
|
|
3
|
+
# 3D plot of 2D data with Numo::NArray
|
|
4
|
+
n = 60
|
|
5
|
+
x = (Numo::DFloat.new(1,n).seq/n-0.5)*30
|
|
6
|
+
y = (Numo::DFloat.new(n,1).seq/n-0.5)*30
|
|
7
|
+
r = Numo::NMath.sqrt(x**2+y**2) + 1e-10
|
|
8
|
+
z = Numo::NMath.sin(r)/r
|
|
9
|
+
|
|
10
|
+
Numo.gnuplot do
|
|
11
|
+
set title:'3D plot of 2D data'
|
|
12
|
+
set dgrid3d:[60,60]
|
|
13
|
+
splot z, w:'pm3d', t:'sin(r)/r'
|
|
14
|
+
end
|
data/examples/ex011.rb
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require "numo/narray"
|
|
2
|
+
|
|
3
|
+
# 3D plot of XYZ data with Numo::NArray
|
|
4
|
+
df = Numo::DFloat
|
|
5
|
+
nm = Numo::NMath
|
|
6
|
+
n = 120
|
|
7
|
+
x = (df.new(1,n).seq/n-0.5)*30
|
|
8
|
+
y = (df.new(n,1).seq/n-0.5)*30
|
|
9
|
+
r = nm.sqrt(x**2+y**2) + 1e-10
|
|
10
|
+
z = nm.sin(r)/r
|
|
11
|
+
x += df.zeros(n,1)
|
|
12
|
+
y += df.zeros(1,n)
|
|
13
|
+
|
|
14
|
+
Numo.gnuplot do
|
|
15
|
+
set title:'3D plot of XYZ data',
|
|
16
|
+
palette:{rgbformula:[22,13,-31]},
|
|
17
|
+
dgrid3d:[60,60],
|
|
18
|
+
xlabel:'x',
|
|
19
|
+
ylabel:'y',
|
|
20
|
+
zlabel:'sin(r)/r'
|
|
21
|
+
splot x,y,z, w:'pm3d', t:'sin(r)/r'
|
|
22
|
+
end
|
data/lib/numo/gnuplot.rb
ADDED
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
module Numo
|
|
2
|
+
|
|
3
|
+
def gnuplot(&block)
|
|
4
|
+
if block
|
|
5
|
+
Gnuplot.default.instance_eval(&block)
|
|
6
|
+
else
|
|
7
|
+
Gnuplot.default
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
module_function :gnuplot
|
|
11
|
+
|
|
12
|
+
class Gnuplot
|
|
13
|
+
|
|
14
|
+
VERSION = "0.1.0"
|
|
15
|
+
POOL = []
|
|
16
|
+
DATA_FORMAT = "%.5g"
|
|
17
|
+
|
|
18
|
+
class GnuplotError < StandardError; end
|
|
19
|
+
|
|
20
|
+
def self.default
|
|
21
|
+
POOL[0] ||= self.new
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def initialize(gnuplot_command="gnuplot")
|
|
25
|
+
@history = []
|
|
26
|
+
@iow = IO.popen(gnuplot_command+" 2>&1","w+")
|
|
27
|
+
@ior = @iow
|
|
28
|
+
@gnuplot_version = send_cmd("print GPVAL_VERSION")[0].chomp
|
|
29
|
+
@debug = false
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
attr_reader :history
|
|
33
|
+
attr_reader :gnuplot_version
|
|
34
|
+
|
|
35
|
+
# draw 2D functions and data.
|
|
36
|
+
def plot(*args)
|
|
37
|
+
_plot_splot("plot",args)
|
|
38
|
+
nil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# draws 2D projections of 3D surfaces and data.
|
|
42
|
+
def splot(*args)
|
|
43
|
+
_plot_splot("splot",args)
|
|
44
|
+
nil
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def _plot_splot(cmd,args)
|
|
48
|
+
contents = parse_plot_args(args)
|
|
49
|
+
r = contents.shift.map{|x|"[#{x.begin}:#{x.end}] "}.join
|
|
50
|
+
c = contents.map{|x| x.cmd_str}.join(",")
|
|
51
|
+
d = contents.map{|x| x.data_str}.join
|
|
52
|
+
run "#{cmd} #{r}#{c}\n#{d}"
|
|
53
|
+
nil
|
|
54
|
+
end
|
|
55
|
+
private :_plot_splot
|
|
56
|
+
|
|
57
|
+
# replot is not recommended, use refresh
|
|
58
|
+
def replot
|
|
59
|
+
run "replot\n#{@last_data}"
|
|
60
|
+
nil
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# The `set` command is used to set _lots_ of options.
|
|
64
|
+
def set(*args)
|
|
65
|
+
_set_unset("set",args)
|
|
66
|
+
nil
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# The `unset` command is used to return to their default state.
|
|
70
|
+
def unset(*args)
|
|
71
|
+
_set_unset("unset",args)
|
|
72
|
+
nil
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def _set_unset(cmd,args)
|
|
76
|
+
args.each do |a|
|
|
77
|
+
case a
|
|
78
|
+
when Hash
|
|
79
|
+
a.each do |k,v|
|
|
80
|
+
run "#{cmd} #{KvItem.new(k,v)}"
|
|
81
|
+
end
|
|
82
|
+
else
|
|
83
|
+
run "#{cmd} #{a}"
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
nil
|
|
87
|
+
end
|
|
88
|
+
private :_set_unset
|
|
89
|
+
|
|
90
|
+
# The `help` command displays built-in help.
|
|
91
|
+
def help(s=nil)
|
|
92
|
+
puts send_cmd "help #{s}\n\n"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# The `show` command shows their settings.
|
|
96
|
+
def show(x)
|
|
97
|
+
puts send_cmd "show #{x}"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# The `reset` command causes all graph-related options that can be
|
|
101
|
+
# set with the `set` command to take on their default values.
|
|
102
|
+
def reset(x=nil)
|
|
103
|
+
run "reset #{x}"
|
|
104
|
+
nil
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# The `pause` command used to wait for events on window.
|
|
108
|
+
# Carriage return entry (-1 is given for argument) and
|
|
109
|
+
# text display option is disabled.
|
|
110
|
+
# pause 10
|
|
111
|
+
# pause 'mouse'
|
|
112
|
+
# pause mouse:%w[keypress,button1,button2,button3,close,any]
|
|
113
|
+
def pause(*args)
|
|
114
|
+
send_cmd("pause #{OptsToS.new(*args)}").join.chomp
|
|
115
|
+
nil
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# The `load` command executes each line of the specified input file.
|
|
119
|
+
def load(filename)
|
|
120
|
+
send_cmd "load '#{filename}'"
|
|
121
|
+
nil
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
alias kernel_raise :raise
|
|
125
|
+
|
|
126
|
+
# The `raise` command raises plot window(s)
|
|
127
|
+
def raise_plot(plot_window_nb=nil)
|
|
128
|
+
send_cmd "raise #{plot_window_nb}"
|
|
129
|
+
nil
|
|
130
|
+
end
|
|
131
|
+
alias raise :raise_plot
|
|
132
|
+
|
|
133
|
+
# The `lower` command lowers plot window(s)
|
|
134
|
+
def lower_plot(plot_window_nb=nil)
|
|
135
|
+
send_cmd "lower #{plot_window_nb}"
|
|
136
|
+
nil
|
|
137
|
+
end
|
|
138
|
+
alias lower :lower_plot
|
|
139
|
+
|
|
140
|
+
# The `clear` command erases the current screen or output device as specified
|
|
141
|
+
# by `set output`. This usually generates a formfeed on hardcopy devices.
|
|
142
|
+
def clear
|
|
143
|
+
send_cmd "clear"
|
|
144
|
+
nil
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# The `exit` and `quit` commands will exit `gnuplot`.
|
|
148
|
+
def exit
|
|
149
|
+
send_cmd "exit"
|
|
150
|
+
nil
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# The `exit` and `quit` commands will exit `gnuplot`.
|
|
154
|
+
def quit
|
|
155
|
+
send_cmd "quit"
|
|
156
|
+
nil
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# The `refresh` reformats and redraws the current plot using the
|
|
160
|
+
# data already read in.
|
|
161
|
+
def refresh
|
|
162
|
+
send_cmd "reflesh"
|
|
163
|
+
nil
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# `var` returns Gnuplot variable (not Gnuplot command)
|
|
167
|
+
def var(name)
|
|
168
|
+
res = send_cmd("print #{name}").join("").chomp
|
|
169
|
+
if /undefined variable:/ =~ res
|
|
170
|
+
kernel_raise GnuplotError,res.strip
|
|
171
|
+
end
|
|
172
|
+
res
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# turn on debug
|
|
176
|
+
def debug_on
|
|
177
|
+
@debug = true
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# turn off debug
|
|
181
|
+
def debug_off
|
|
182
|
+
@debug = false
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
#other_commands = %w[
|
|
186
|
+
# bind
|
|
187
|
+
# call
|
|
188
|
+
# cd
|
|
189
|
+
# do
|
|
190
|
+
# evaluate
|
|
191
|
+
# fit
|
|
192
|
+
# history
|
|
193
|
+
# if
|
|
194
|
+
# print
|
|
195
|
+
# pwd
|
|
196
|
+
# reread
|
|
197
|
+
# save
|
|
198
|
+
# shell
|
|
199
|
+
# stats
|
|
200
|
+
# system
|
|
201
|
+
# test
|
|
202
|
+
# update
|
|
203
|
+
# while
|
|
204
|
+
#]
|
|
205
|
+
|
|
206
|
+
# for irb workspace name
|
|
207
|
+
def to_s
|
|
208
|
+
"gnuplot"
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def run(s)
|
|
212
|
+
res = send_cmd(s)
|
|
213
|
+
if !res.empty?
|
|
214
|
+
if res.size > 7
|
|
215
|
+
msg = "\n"+res[0..5].join("")+" :\n"
|
|
216
|
+
else
|
|
217
|
+
msg = "\n"+res.join("")
|
|
218
|
+
end
|
|
219
|
+
kernel_raise GnuplotError,msg
|
|
220
|
+
end
|
|
221
|
+
nil
|
|
222
|
+
end
|
|
223
|
+
private :run
|
|
224
|
+
|
|
225
|
+
def send_cmd(s)
|
|
226
|
+
puts "<"+s if @debug
|
|
227
|
+
@iow.puts s
|
|
228
|
+
@iow.flush
|
|
229
|
+
@iow.puts "print '_end_of_cmd_'"
|
|
230
|
+
@iow.flush
|
|
231
|
+
@history << s
|
|
232
|
+
res = []
|
|
233
|
+
while line=@ior.gets
|
|
234
|
+
puts ">"+line if @debug
|
|
235
|
+
break if /^_end_of_cmd_$/ =~ line
|
|
236
|
+
res << line
|
|
237
|
+
end
|
|
238
|
+
res # = res.chomp.strip
|
|
239
|
+
end
|
|
240
|
+
private :send_cmd
|
|
241
|
+
|
|
242
|
+
def parse_plot_args(args)
|
|
243
|
+
list = [[]]
|
|
244
|
+
item = PlotItem.new
|
|
245
|
+
list << item
|
|
246
|
+
args.each do |arg|
|
|
247
|
+
case arg
|
|
248
|
+
when Range
|
|
249
|
+
list.first << arg
|
|
250
|
+
when Array
|
|
251
|
+
if arg.all?{|e| e.kind_of?(Range)}
|
|
252
|
+
list.first.concat(arg)
|
|
253
|
+
elsif PlotItem.is_data(arg)
|
|
254
|
+
item << arg
|
|
255
|
+
else
|
|
256
|
+
if list.last.empty?
|
|
257
|
+
list.pop
|
|
258
|
+
end
|
|
259
|
+
item = PlotItem.new(*arg)
|
|
260
|
+
list << item
|
|
261
|
+
end
|
|
262
|
+
when Hash
|
|
263
|
+
item << arg
|
|
264
|
+
item = PlotItem.new
|
|
265
|
+
list << item
|
|
266
|
+
else
|
|
267
|
+
item << arg
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
if list.last.empty?
|
|
271
|
+
list.pop
|
|
272
|
+
end
|
|
273
|
+
return list
|
|
274
|
+
end
|
|
275
|
+
private :parse_plot_args
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
# @private
|
|
279
|
+
class OptsToS # :nodoc: all
|
|
280
|
+
def initialize(*opts)
|
|
281
|
+
@opts = opts
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def to_s
|
|
285
|
+
opts_to_s(*@opts)
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
def opts_to_s(*opts)
|
|
289
|
+
#p opts
|
|
290
|
+
sep = ","
|
|
291
|
+
opts.map do |opt|
|
|
292
|
+
sep = " " if !opt.kind_of?(Numeric)
|
|
293
|
+
case opt
|
|
294
|
+
when Array
|
|
295
|
+
opt.map{|v| "#{opts_to_s(*v)}"}.join(sep)
|
|
296
|
+
when Hash
|
|
297
|
+
opt.map{|k,v| KvItem.new(k,v).to_s}.compact.join(" ")
|
|
298
|
+
when Range
|
|
299
|
+
"[#{opt.begin}:#{opt.end}]"
|
|
300
|
+
else
|
|
301
|
+
opt.to_s
|
|
302
|
+
end
|
|
303
|
+
end.join(sep)
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# @private
|
|
308
|
+
class KvItem # :nodoc: all
|
|
309
|
+
NEED_QUOTE = %w[
|
|
310
|
+
background
|
|
311
|
+
cblabel
|
|
312
|
+
clabel
|
|
313
|
+
dashtype
|
|
314
|
+
dt
|
|
315
|
+
font
|
|
316
|
+
format
|
|
317
|
+
format_cb
|
|
318
|
+
format_x
|
|
319
|
+
format_x2
|
|
320
|
+
format_xy
|
|
321
|
+
format_y
|
|
322
|
+
format_y2
|
|
323
|
+
format_z
|
|
324
|
+
output
|
|
325
|
+
rgb
|
|
326
|
+
timefmt
|
|
327
|
+
title
|
|
328
|
+
x2label
|
|
329
|
+
xlabel
|
|
330
|
+
y2label
|
|
331
|
+
ylabel
|
|
332
|
+
zlabel
|
|
333
|
+
].map{|x| x.to_sym}
|
|
334
|
+
|
|
335
|
+
def initialize(k,v)
|
|
336
|
+
@k = k
|
|
337
|
+
@v = v
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
def need_quote?(k)
|
|
341
|
+
NEED_QUOTE.any? do |q|
|
|
342
|
+
/^#{k}/ =~ q
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
def to_s
|
|
347
|
+
kv_to_s(@k,@v)
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
def kv_to_s(k,v)
|
|
351
|
+
if need_quote?(k)
|
|
352
|
+
case v
|
|
353
|
+
when String
|
|
354
|
+
"#{k} #{v.inspect}"
|
|
355
|
+
when Array
|
|
356
|
+
"#{k} #{v[0].inspect} #{OptsToS.new(*v[1..-1])}"
|
|
357
|
+
end
|
|
358
|
+
else
|
|
359
|
+
case v
|
|
360
|
+
when String
|
|
361
|
+
"#{k} #{v}"
|
|
362
|
+
when TrueClass
|
|
363
|
+
"#{k}"
|
|
364
|
+
when NilClass
|
|
365
|
+
nil
|
|
366
|
+
when FalseClass
|
|
367
|
+
nil
|
|
368
|
+
when Array
|
|
369
|
+
"#{k} #{OptsToS.new(*v)}"
|
|
370
|
+
else
|
|
371
|
+
"#{k} #{OptsToS.new(v)}"
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
end
|
|
375
|
+
end # KvItem
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
# @private
|
|
379
|
+
class PlotItem # :nodoc: all
|
|
380
|
+
|
|
381
|
+
def self.is_data(a)
|
|
382
|
+
if a.kind_of? Array
|
|
383
|
+
if a.last.kind_of?(Hash)
|
|
384
|
+
return false
|
|
385
|
+
else
|
|
386
|
+
t = a.first.class
|
|
387
|
+
t = Numeric if t < Numeric
|
|
388
|
+
return a.all?{|e| e.kind_of?(t)}
|
|
389
|
+
end
|
|
390
|
+
elsif defined?(Numo::NArray)
|
|
391
|
+
return true if a.kind_of?(Numo::NArray)
|
|
392
|
+
elsif defined?(NArray)
|
|
393
|
+
return true if a.kind_of?(NArray)
|
|
394
|
+
elsif defined?(NMatrix)
|
|
395
|
+
return true if a.kind_of?(NMatix)
|
|
396
|
+
end
|
|
397
|
+
false
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
def initialize(*items)
|
|
401
|
+
@items = items
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
def <<(item)
|
|
405
|
+
@items << item
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
def empty?
|
|
409
|
+
@items.empty?
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
def parse_items
|
|
413
|
+
if !@options
|
|
414
|
+
if @items.empty?
|
|
415
|
+
return
|
|
416
|
+
elsif @items.first.kind_of? String
|
|
417
|
+
@function = @items.first
|
|
418
|
+
@options = @items[1..-1]
|
|
419
|
+
else
|
|
420
|
+
@data = []
|
|
421
|
+
@options = []
|
|
422
|
+
@items.each do |x|
|
|
423
|
+
if PlotItem.is_data(x)
|
|
424
|
+
@data << x
|
|
425
|
+
else
|
|
426
|
+
@options << x
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
if @data.size==1
|
|
430
|
+
a = @data[0]
|
|
431
|
+
if a.respond_to?(:shape)
|
|
432
|
+
if a.shape.size == 2
|
|
433
|
+
@matrix = true
|
|
434
|
+
end
|
|
435
|
+
end
|
|
436
|
+
end
|
|
437
|
+
end
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
def cmd_str
|
|
442
|
+
parse_items
|
|
443
|
+
if @function
|
|
444
|
+
"%s %s" % [@function, OptsToS.new(*@options)]
|
|
445
|
+
else
|
|
446
|
+
if @matrix
|
|
447
|
+
"'-' matrix %s" % OptsToS.new(*@options)
|
|
448
|
+
else
|
|
449
|
+
"'-' %s" % OptsToS.new(*@options)
|
|
450
|
+
end
|
|
451
|
+
end
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
def data_str
|
|
455
|
+
parse_items
|
|
456
|
+
if @function
|
|
457
|
+
nil
|
|
458
|
+
else
|
|
459
|
+
if @matrix
|
|
460
|
+
data2d_to_s(@data[0])+"\ne\n"
|
|
461
|
+
else
|
|
462
|
+
data1d_to_s(@data)+"e\n"
|
|
463
|
+
end
|
|
464
|
+
end
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
def data_format
|
|
468
|
+
@data_format || DATA_FORMAT
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
def data_format=(s)
|
|
472
|
+
@data_format = s
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
def data1d_to_s(a)
|
|
476
|
+
n = a.map{|e| e.size}.min
|
|
477
|
+
f = ([data_format]*a.size).join(" ")+"\n"
|
|
478
|
+
s = ""
|
|
479
|
+
n.times{|i| s << f % a.map{|e| e[i]}}
|
|
480
|
+
s
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
def data2d_to_s(a)
|
|
484
|
+
f = data_format
|
|
485
|
+
s = ""
|
|
486
|
+
a.to_a.each do |b|
|
|
487
|
+
s << b.map{|e| f%e}.join(" ")+"\n"
|
|
488
|
+
end
|
|
489
|
+
s
|
|
490
|
+
end
|
|
491
|
+
end # PlotItem
|
|
492
|
+
end # Numo::Gnuplot
|
|
493
|
+
end
|