grada 2.1.5 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/grada/gnuplot.rb +33 -23
  2. data/lib/grada.rb +46 -28
  3. metadata +17 -1
data/lib/grada/gnuplot.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'matrix'
2
+ require 'open3'
2
3
 
3
4
  class NoGnuPlotExecutableFound < RuntimeError; end
4
5
 
@@ -26,25 +27,33 @@ class Gnuplot
26
27
  nil
27
28
  end
28
29
 
29
- def self.gnuplot(persist)
30
+ def self.gnuplot
30
31
  gnu_exec = find_exec( ENV['RB_GNUPLOT'] || 'gnuplot' )
31
-
32
32
  raise NoGnuPlotExecutableFound unless gnu_exec
33
-
34
- "#{gnu_exec} #{'-persist' if persist}"
33
+ gnu_exec
35
34
  end
36
35
 
37
- def self.open(persist = true)
38
- output = nil
39
- gnuplot_cmd = gnuplot(persist)
36
+ def self.open(persist = true, &block)
37
+ gnuplot_cmd = gnuplot
40
38
 
41
- IO::popen( gnuplot_cmd, 'w+' ) do |io|
42
- yield io
43
- io.close_write
44
- output = io.read
45
- end
39
+ commands = yield
46
40
 
47
- output
41
+ output = StringIO.new
42
+ Open3::popen3(gnuplot_cmd, '-persist') do |data_in, data_out, stderr, wait_th|
43
+ data_in << commands[:plot_settings]
44
+ data_in << commands[:plot_data]
45
+
46
+ data_in.flush
47
+ sleep 1
48
+
49
+ while true do
50
+ window = IO::popen('xprop -name "Gnuplot" WM_NAME 2>/dev/null').gets
51
+ break unless window
52
+ sleep 1
53
+ end
54
+ end
55
+
56
+ output.string
48
57
  end
49
58
  end
50
59
 
@@ -53,18 +62,19 @@ class Plot
53
62
 
54
63
  QUOTED_METHODS = [ "title", "output", "xlabel", "x2label", "ylabel", "y2label", "clabel", "cblabel", "zlabel" ]
55
64
 
56
- def initialize(io = nil, cmd = 'plot')
57
- @cmd = cmd
65
+ def initialize
58
66
  @settings = []
59
67
  @arbitrary_lines = []
60
68
  @data = []
61
69
  @styles = []
62
- yield self if block_given?
70
+ end
63
71
 
64
- if io
65
- io << to_gplot
66
- io << store_datasets
67
- end
72
+ def self.construct(&block)
73
+ plot = new
74
+
75
+ block.call plot if block_given?
76
+
77
+ { plot_settings: plot.to_gplot, plot_data: plot.store_datasets }
68
78
  end
69
79
 
70
80
  def method_missing(meth, *args)
@@ -90,8 +100,8 @@ class Plot
90
100
 
91
101
  def store_datasets(io = '')
92
102
  if @data.size > 0
93
- io += @cmd + " #{ @data.map { |element| element.plot_args }.join(', ') } \n"
94
- io += @data.map { |ds| ds.to_gplot }.compact.join("e\n")
103
+ io += 'plot' + " #{ @data.map { |element| element.plot_args }.join(', ') } \n"
104
+ io += @data.map { |ds| ds.to_gplot }.compact.join("\n") + "\n"
95
105
  end
96
106
 
97
107
  io
@@ -199,7 +209,7 @@ class Array
199
209
  self.each { |elem| series_for_plot += "#{elem}\n" }
200
210
  series_for_plot + 'e'
201
211
  else
202
- self[0].zip(self[1]).map{ |elem| elem.join(' ') }.join("\n") + "\ne"
212
+ self[0].zip(self[1]).map{ |elem| elem.join(' ') }.join("\n") + "\ne\n"
203
213
  end
204
214
  end
205
215
 
data/lib/grada.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'grada/gnuplot'
1
+ require_relative 'grada/gnuplot'
2
2
 
3
3
  class Grada
4
4
  # Not valid the format of the object to construct the graph
@@ -30,10 +30,10 @@ class Grada
30
30
 
31
31
  #Graph offsets
32
32
  #
33
- LEFT = 0.25
34
- RIGHT = 0.25
35
- TOP = 0.25
36
- BOTTOM = 0.25
33
+ LEFT = 0.05
34
+ RIGHT = 0.05
35
+ TOP = 0.05
36
+ BOTTOM = 0.05
37
37
 
38
38
  # Hello GraDA
39
39
  #
@@ -60,7 +60,7 @@ class Grada
60
60
  @y = y.nil? ? y : validate(y)
61
61
  end
62
62
 
63
- # Displays a graph in a window.
63
+ # Displays a graph in a X11 window.
64
64
  # You can specify all the options that you need:
65
65
  # *width* (Integer)
66
66
  # *height* (Integer)
@@ -70,6 +70,20 @@ class Grada
70
70
  # *graph_type* (:histogram, :heatmap) default: :default
71
71
  # *with* ('points', 'linespoints') default: 'lines'
72
72
  #
73
+ # Also is important to know that you can interact with the graph:
74
+ # * Zoom in => right click and drag the mouse to cover the area you want
75
+ # or
76
+ # use the scroll wheel
77
+ #
78
+ # * Zoom out => press key 'a'
79
+ # or
80
+ # if you want to go back to a previous state of zoom press key 'p'
81
+ #
82
+ # * Exit interactive mode => press key 'q'
83
+ # or
84
+ # just close the window
85
+ #
86
+ # * Save image => working on it
73
87
  #
74
88
  # Example:
75
89
  # >> grada.display
@@ -94,6 +108,7 @@ class Grada
94
108
  @opts[:with] = 'image'
95
109
 
96
110
  plot_heat_map do |plot|
111
+ plot.set "terminal x11 size #{@opts[:width]},#{@opts[:height]}"
97
112
  plot.set "offset graph #{LEFT},#{RIGHT},#{TOP},#{BOTTOM}"
98
113
  end
99
114
  else
@@ -107,10 +122,15 @@ class Grada
107
122
  end
108
123
 
109
124
  # Save the graph in a png file.
110
- # You can specify all the options that you need as _display_ but also need to specify the file
125
+ # You can specify all the options that you need as _display_ but also need to specify the file root-name and extension.
126
+ # The possible extensions you can use for saving a file are:
127
+ # *png*
128
+ # *gif*
129
+ # *jpeg*
130
+ # *svg* => default
111
131
  #
112
132
  # Example:
113
- # >> grada.save({ filename: 'secret/radiation_levels/ffa/zonex/devicex/radiation_level_malaga.png' ,title: 'Atomic Device X', x_label: 'Day', y_label: 'smSv', with: 'points' })
133
+ # >> grada.save({ filename: 'secret/radiation_levels/ffa/zonex/devicex/radiation_level_malaga', ext: 'png' ,title: 'Atomic Device X', x_label: 'Day', y_label: 'smSv', with: 'points' })
114
134
  # => ""
115
135
  # Arguments:
116
136
  # opts: (Hash) *optional*
@@ -119,14 +139,15 @@ class Grada
119
139
  @opts = DEFAULT_OPTIONS.merge(opts)
120
140
 
121
141
  return nil if @opts[:filename].nil?
142
+
143
+ ext = @opts[:ext] || 'svg'
122
144
 
123
145
  if @opts[:graph_type] == :histogram
124
146
  population_data?(@x)
125
147
 
126
148
  plot_histogram do |plot|
127
- plot.output @opts[:filename]
128
- plot.set "terminal png size #{@opts[:width]}, #{@opts[:height]} crop"
129
- plot.terminal 'png'
149
+ plot.output "#{@opts[:filename]}.#{ext}"
150
+ plot.set "terminal #{ext} size #{@opts[:width]}, #{@opts[:height]} crop"
130
151
  plot.set "offset graph #{LEFT},#{RIGHT},#{TOP},#{BOTTOM}"
131
152
  end
132
153
  elsif @opts[:graph_type] == :heatmap
@@ -134,18 +155,15 @@ class Grada
134
155
  @opts[:with] = 'image'
135
156
 
136
157
  plot_heat_map do |plot|
137
- plot.output @opts[:filename]
138
- plot.set "terminal png size #{@opts[:width]}, #{@opts[:height]} crop"
139
- plot.terminal 'png'
140
- plot.set "offset graph #{LEFT},#{RIGHT},#{TOP},#{BOTTOM}"
158
+ plot.output "#{@opts[:filename]}.#{ext}"
159
+ plot.set "terminal #{ext} size #{@opts[:width]}, #{@opts[:height]} crop"
141
160
  end
142
161
  else
143
162
  raise NoPlotDataError if @y.nil?
144
163
 
145
164
  plot_and do |plot|
146
- plot.output @opts[:filename]
147
- plot.set "terminal png size #{@opts[:width]}, #{@opts[:height]} crop"
148
- plot.terminal 'png'
165
+ plot.output "#{@opts[:filename]}.#{ext}"
166
+ plot.set "terminal #{ext} size #{@opts[:width]}, #{@opts[:height]} crop"
149
167
  plot.set "offset graph #{LEFT},#{RIGHT},#{TOP},#{BOTTOM}"
150
168
  end
151
169
  end
@@ -182,9 +200,9 @@ class Grada
182
200
  end
183
201
 
184
202
  def plot_and(&block)
185
- Gnuplot.open do |gp|
186
- Gnuplot::Plot.new(gp) do |plot|
187
- block[plot] if block
203
+ Gnuplot.open do
204
+ Gnuplot::Plot.construct do |plot|
205
+ block.call plot if block
188
206
 
189
207
  plot.title @opts[:title]
190
208
 
@@ -224,9 +242,9 @@ class Grada
224
242
  end
225
243
 
226
244
  def plot_histogram(&block)
227
- Gnuplot.open do |gp|
228
- Gnuplot::Plot.new(gp) do |plot|
229
- block[plot] if block
245
+ Gnuplot.open do
246
+ Gnuplot::Plot.construct do |plot|
247
+ block.call plot if block
230
248
 
231
249
  width = ( @x.max - @x.min ) / @x.size
232
250
 
@@ -237,7 +255,7 @@ class Grada
237
255
  plot.ylabel "Frequency"
238
256
  plot.set "style fill solid 0.5"
239
257
  plot.set "xrange [#{@x.min}:#{@x.max}]"
240
- plot.set "boxwidth #{ width * 0.4}"
258
+ plot.set "boxwidth #{ width * 0.1}"
241
259
  plot.set "xtics #{@x.min},#{(@x.max-@x.min)/5},#{@x.max}"
242
260
  plot.set "tics out nomirror"
243
261
 
@@ -252,9 +270,9 @@ class Grada
252
270
  end
253
271
 
254
272
  def plot_heat_map(&block)
255
- Gnuplot.open do |gp|
256
- Gnuplot::Plot.new(gp) do |plot|
257
- block[plot] if block
273
+ Gnuplot.open do
274
+ Gnuplot::Plot.construct do |plot|
275
+ block.call plot if block
258
276
 
259
277
  plot.set "pm3d map"
260
278
  plot.set "palette color"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grada
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.5
4
+ version: 2.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,6 +11,22 @@ bindir: bin
11
11
  cert_chain: []
12
12
  date: 2013-06-20 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: magritte
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
14
30
  - !ruby/object:Gem::Dependency
15
31
  name: rspec
16
32
  requirement: !ruby/object:Gem::Requirement