grada 2.1.5 → 2.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.
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