blackwinter-gnuplot 2.3.5.1

Sign up to get free protection for your applications and to get access to all the features.
data/AUTHORS.txt ADDED
@@ -0,0 +1,7 @@
1
+ Gordon James Miller
2
+ Ara T. Howard
3
+ Roger Pack
4
+ Mike Cahill
5
+ jakobs
6
+ blambeau
7
+ Jens Wille
data/ChangeLog ADDED
@@ -0,0 +1,54 @@
1
+ 2.3.5
2
+ * Cleanup readme, add examples as real code files (thanks blambeau!)
3
+
4
+ 2.3.4
5
+ * Include more files in the gem by switching to Jeweler (thanks Jeweler guyz)!
6
+
7
+ 2.3.3
8
+ * Fix issue #4 (thanks Jakobs)
9
+ * Fix some unit tests (thanks Nobu!)
10
+
11
+ 2.3.2 Feb 2010
12
+ * Add an arbitrary_lines specifier
13
+
14
+ 2.3.1 Feb 2010
15
+
16
+ * Fix a bug I introduced in 2.3.0
17
+
18
+ 2.3.0 Feb 2010
19
+
20
+ * incorporate a few patch changes
21
+
22
+ 2.2.3.1 July 18 2009
23
+
24
+ * output the raw "to gnuplot" data if $VERBOSE
25
+
26
+ Version 2.2.2 July 2009
27
+
28
+ * raise if no executable found, should be windows compat. now
29
+
30
+ Version 2.2 14-Nov-2005
31
+
32
+ * Formally added the LICENSE.txt file. It is the new BSD license as defined
33
+ by opensource.org. See that file for details.
34
+
35
+ * Added Gnuplot.which to try and fix the recurring problem of windows users
36
+ having to hack code to get things working.
37
+
38
+ * Added the Gnuplot.gnuplot function so that I can unit test the finding
39
+ gnuplot executable routine.
40
+
41
+ * In the Array.to_gplot method the terminating e is added to the output. This
42
+ is in response to Bug #2209.
43
+
44
+ Version 2.1 17-Nov-2004
45
+
46
+ * Array.to_gplot and Array.to_gsplot now support passing in arrays of
47
+ arbitrary objects. This is in response to a request by Yoshiki Tsunesada
48
+ (Tracker ID 1063)
49
+
50
+ Version 2.0 10-Nov-2004
51
+
52
+ * The 2.0 version of the gnuplot interface is a cross between the original,
53
+ object oriented version, and the version 1.0 which was simply a string
54
+ manipulation library.
data/LICENSE.txt ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2004-2005, Gordon James Miller (gmiller@bittwiddlers.com)
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in the
12
+ documentation and/or other materials provided with the distribution.
13
+
14
+ * Neither the name of the BitTwiddlers, Inc. nor the names of its
15
+ contributors may be used to endorse or promote products derived from
16
+ this software without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.rdoc ADDED
@@ -0,0 +1,203 @@
1
+ = Ruby Gnuplot - Utility library to aid in interacting with GNUPLOT
2
+
3
+ * {Rubyforge Project page}[http://rubyforge.org/projects/rgplot]
4
+ * {Documentation}[http://blackwinter.github.com/ruby_gnuplot]
5
+ * {Source code}[http://github.com/blackwinter/ruby_gnuplot]
6
+
7
+
8
+ == History and Background
9
+
10
+ GNUPLOT[http://gnuplot.info] is a program that has a rich language for the
11
+ generation of plots. It has a unique place in academia as it was one of the
12
+ first freely available programs for plot generation. I started using GNUPLOT
13
+ over 10 years ago while pursuing my Master's degree in Physics and have been
14
+ using it actively ever since.
15
+
16
+ === Version 0.9
17
+
18
+ My first attempt at a Ruby interface to GNUPLOT was an object interface
19
+ encapsulating GNUPLOT language. This was taken directly from the Python
20
+ GNUPLOT interface. In spite of my being very familiar with GNUPLOT and Ruby
21
+ and being the author of the RGnuplot package, I found it non-intuitive to
22
+ use the RGnuplot package. I found myself constantly looking at the code to
23
+ figure out what I needed to do. This was not sufficient and did not sit well.
24
+
25
+ === Version 1.0
26
+
27
+ The second attempt at a Ruby interface was to do absolutely nothing but use
28
+ Ruby's built in string manipulation methods. This meant that I could simply
29
+ use my knowledge of GNUPLOT without having to worry about objects. While in
30
+ some ways an improvement over version 0.9, it still did not sit well with me.
31
+
32
+ === Version 2.0
33
+
34
+ After attending RubyConf 2004 I was inspired by Rich Kilmer's use of Ruby to
35
+ implement domain specific languages. That is the current implementation of
36
+ Gnuplot and quite probably the one that I'll stick with for some time. This
37
+ version combines the direct mapping of the GNUPLOT language without wrapping
38
+ with the Ruby syntax and mechanism of adding methods to existing classes to
39
+ interface Ruby objects with GNUPLOT.
40
+
41
+
42
+ == Setup
43
+
44
+ === Version 2.2
45
+
46
+ If the +gnuplot+ command is in your path then there is no required setup. If
47
+ the GNUPLOT executable for your system is called something other than simply
48
+ +gnuplot+ then set the +RB_GNUPLOT+ environment variable to the name of the
49
+ executable. This must either be a full path to the GNUPLOT command or an
50
+ executable filename that exists in your +PATH+ environment variable.
51
+
52
+
53
+ == Ruby Gnuplot Concepts
54
+
55
+ GNUPLOT has a very simple conceptual model. Calls to _set_ are made to set
56
+ parameters and either _plot_ or _splot_ is called to generate the actual plot.
57
+ The _dataset_ to be plotted can be specified in a number of ways, contained
58
+ in a separate file, generated from a function, read from standard input, or
59
+ read immediately after the plot command.
60
+
61
+ The object model for the Ruby Gnuplot wrapper directly mimics this layout and
62
+ flow. The following are the standard steps for generating a plot:
63
+
64
+ * Instantiate a Gnuplot::Plot or Gnuplot::SPlot object and set parameters by
65
+ GNUPLOT variable name.
66
+ * Instantiate Gnuplot::DataSet objects and attach Ruby objects containing the
67
+ data to be plotted to the data set.
68
+ * Attach properties that modify the plot command using the modifier name.
69
+ * Send the Plot/SPlot object to a GNUPLOT instance for plotting.
70
+
71
+ The version 2.0 interface makes heavy use of blocks leading to very readable
72
+ code.
73
+
74
+ [<tt>Gnuplot.open</tt>]
75
+ Instantiates a new GNUPLOT process. The path to the executable is determined
76
+ using the Gnuplot.which command. If a block is given to the function the
77
+ opened process is passed into the block. This mimics the most common usage
78
+ of the File.open method.
79
+
80
+ [<tt>Gnuplot::Plot.new</tt>, <tt>Gnuplot::SPlot.new</tt>]
81
+ Create a new Plot or SPlot object. DataSets are attached to the object to
82
+ specify the data and its properties. If a block is given to the function,
83
+ the plot object is passed into the block.
84
+
85
+ [<tt>Gnuplot::DataSet.new</tt>]
86
+ Associates a Ruby object containing the data to plot with the properties
87
+ that will be passed to the plot command for that data set. Any Ruby object
88
+ can be associated with a DataSet as long as it understands the +to_gplot+
89
+ method.
90
+
91
+ [<tt>to_gplot</tt>]
92
+ Within GNUPLOT, plot data is read in very simple formats. The +to_gplot+
93
+ method is expected to write the data of the object in a format that is
94
+ understandable by GNUPLOT. One of the many great things about Ruby is that
95
+ methods can be added after the original declaration. The Gnuplot module
96
+ defines the +to_gplot+ method on the classes Array and Matrix. Simply
97
+ define a +to_gplot+ method on your own class to tie the class into gnuplot.
98
+
99
+
100
+ == Examples
101
+
102
+ === Simple sine wave
103
+
104
+ The following example simply plots the value of <tt>sin(x)</tt> between the
105
+ ranges of -10 and 10. A few points to notice:
106
+
107
+ The code uses nested blocks to construct the plot. The newly created object
108
+ is passed to the block so it can be modified in place.
109
+
110
+ Each of the GNUPLOT plot variables is modified using the variable name as a
111
+ method name on the plot object or on the data set object. The wrapper also
112
+ takes care of the single quoting that is required on some of the variables
113
+ like +title+, +ylabel+, and +xlabel+.
114
+
115
+ The plot object simply has an array of Gnuplot::DataSet objects. The
116
+ constructor initializes this empty array before yielding to the block. This
117
+ method uses the <tt><<</tt> operator to add the DataSet to the plot.
118
+
119
+ When the plot block ends, if an IO object is given to the Gnuplot::Plot
120
+ constructor, the plot commands will be written to the IO object. Any object can
121
+ be passed to the constructor as long as it understands the <tt><<</tt> operator.
122
+
123
+ Gnuplot.open { |gp|
124
+ Gnuplot::Plot.new(gp) { |plot|
125
+
126
+ plot.xrange '[-10:10]'
127
+ plot.title 'Sine Wave Example'
128
+ plot.xlabel 'x'
129
+ plot.ylabel 'sin(x)'
130
+
131
+ plot.data << Gnuplot::DataSet.new('sin(x)') { |ds|
132
+ ds.with = 'lines'
133
+ ds.linewidth = 4
134
+ }
135
+
136
+ }
137
+ }
138
+
139
+ === Plotting discrete points
140
+
141
+ Array data can be plotted quite easily since Arrays have a defined
142
+ Array#to_gplot method.
143
+
144
+ Simply pass an array of data to the constructor of the Gnuplot::DataSet
145
+ object or set the data property of the DataSet. In this example, because
146
+ there are two arrays, each array will be a single column of data to the
147
+ GNUPLOT process.
148
+
149
+ Also, this example uses the Gnuplot.plot convenience method which wraps
150
+ the calls to Gnuplot.open and Gnuplot::Plot.new.
151
+
152
+ Gnuplot.plot { |plot|
153
+ plot.title 'Array Plot Example'
154
+ plot.xlabel 'x'
155
+ plot.ylabel 'x^2'
156
+
157
+ x = (0..50).map { |v| v.to_f }
158
+ y = x.map { |v| v ** 2 }
159
+
160
+ plot.data << Gnuplot::DataSet.new([x, y]) { |ds|
161
+ ds.with = 'linespoints'
162
+ ds.notitle
163
+ }
164
+ }
165
+
166
+ === Multiple Data Sets
167
+
168
+ As many data sets as are desired can be attached to a plot. Each of these can
169
+ have their own plot modifiers. Notice in this example how the data array is
170
+ set through the Gnuplot::DataSet#data convenience method instead of using the
171
+ <tt><<</tt> operator.
172
+
173
+ Also in this example, the commands are not written to the GNUPLOT process but
174
+ are instead written to a File called <tt>gnuplot.dat</tt>. This file can later
175
+ be run directly by a GNUPLOT process as it contains only the GNUPLOT commands.
176
+
177
+ Gnuplot.plot_to('gnuplot.dat') { |plot|
178
+ plot.xrange '[-10:10]'
179
+ plot.title 'Sin Wave Example'
180
+ plot.xlabel 'x'
181
+ plot.ylabel 'sin(x)'
182
+
183
+ x = (0..50).map { |v| v.to_f }
184
+ y = x.map { |v| v ** 2 }
185
+
186
+ plot.data('sin(x)') { |ds|
187
+ ds.with = 'lines'
188
+ ds.title = 'String function'
189
+ ds.linewidth = 4
190
+ }
191
+
192
+ plot.data([x, y]) { |ds|
193
+ ds.with = 'linespoints'
194
+ ds.title = 'Array data'
195
+ }
196
+ }
197
+
198
+ You can also add arbitrary lines to the output:
199
+
200
+ plot.arbitrary_lines << 'set ylabel "y label" font "Helvetica,20"'
201
+
202
+ # or more conveniently
203
+ plot << 'set ylabel "y label" font "Helvetica,20"'
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ require File.expand_path(%q{../lib/gnuplot/version}, __FILE__)
2
+
3
+ require 'jeweler'
4
+ require 'rdoc/task'
5
+ require 'rake/testtask'
6
+
7
+ Jeweler::Tasks.new { |s|
8
+ s.name = 'blackwinter-gnuplot'
9
+ s.version = Gnuplot::VERSION
10
+ s.summary = 'Utility library to aid in interacting with GNUPLOT'
11
+ s.authors = ['Roger Pack', 'Jens Wille']
12
+ s.email = ['rogerpack2005@gmail.com', 'jens.wille@uni-koeln.de']
13
+ s.homepage = 'http://github.com/blackwinter/ruby_gnuplot'
14
+
15
+ s.add_dependency 'ruby-nuggets'
16
+ }
17
+
18
+ RDoc::Task.new(:doc) { |t|
19
+ t.rdoc_dir = 'doc'
20
+ t.rdoc_files = FileList[
21
+ 'lib/**/*.rb', 'README.rdoc', 'ChangeLog', 'AUTHORS.txt', 'LICENSE.txt'
22
+ ].to_a
23
+ t.options = [
24
+ '--title', "Gnuplot Application documentation (v#{Gnuplot::VERSION})",
25
+ '--main', 'README.rdoc', '--charset', 'UTF-8', '--line-numbers', '--all'
26
+ ]
27
+ }
28
+
29
+ Rake::TestTask.new { |t|
30
+ t.test_files = FileList['test/**/test_*.rb'].to_a
31
+ t.ruby_opts << '-rubygems'
32
+ }
@@ -0,0 +1 @@
1
+ sine_wave_example*.*
@@ -0,0 +1,15 @@
1
+ require 'gnuplot'
2
+
3
+ Gnuplot.plot { |plot|
4
+ plot.title 'Discrete Points Example'
5
+ plot.xlabel 'x'
6
+ plot.ylabel 'x^2'
7
+
8
+ x = (0..50).map { |v| v.to_f }
9
+ y = x.map { |v| v ** 2 }
10
+
11
+ plot.data([x, y]) { |ds|
12
+ ds.with = 'linespoints'
13
+ ds.notitle
14
+ }
15
+ }
@@ -0,0 +1,18 @@
1
+ require 'gnuplot'
2
+
3
+ Gnuplot.plot { |plot|
4
+ plot.title 'Histogram Example'
5
+ plot.xlabel 'x'
6
+ plot.ylabel 'frequency'
7
+
8
+ plot << 'bin(x, s) = s*int(x/s)'
9
+
10
+ x = (0..500).map { |v| (rand - 0.5) ** 3 }
11
+
12
+ plot.data([x]) { |ds|
13
+ ds.title = 'smooth frequency'
14
+ ds.using = '(bin($1,.01)):(1.)'
15
+ ds.smooth = 'freq'
16
+ ds.with = 'boxes'
17
+ }
18
+ }
@@ -0,0 +1,22 @@
1
+ require 'gnuplot'
2
+
3
+ Gnuplot.plot { |plot|
4
+ plot.xrange '[-10:10]'
5
+ plot.title 'Multiple Data Sets Example'
6
+ plot.xlabel 'x'
7
+ plot.ylabel 'y'
8
+
9
+ x = (0..50).map { |v| v.to_f }
10
+ y = x.map { |v| v ** 2 }
11
+
12
+ plot.data('sin(x)') { |ds|
13
+ ds.with = 'lines'
14
+ ds.title = 'String function'
15
+ ds.linewidth = 4
16
+ }
17
+
18
+ plot.data([x, y]) { |ds|
19
+ ds.with = 'linespoints'
20
+ ds.title = 'Array data'
21
+ }
22
+ }
@@ -0,0 +1,26 @@
1
+ require 'gnuplot'
2
+
3
+ file = File.expand_path('../output_file_example1.gif', __FILE__)
4
+
5
+ Gnuplot.plot { |plot|
6
+ # The following lines allow outputting the graph to an image file.
7
+ # The first sets the kind of image that you want, while the second
8
+ # redirects the output to a given file.
9
+ #
10
+ # Typical terminals: gif, png, postscript, latex, texdraw
11
+ #
12
+ # See http://mibai.tec.u-ryukyu.ac.jp/~oshiro/Doc/gnuplot_primer/gptermcmp.html
13
+ # for a list of recognized terminals.
14
+ plot.terminal 'gif'
15
+ plot.output file
16
+
17
+ plot.xrange '[-10:10]'
18
+ plot.title 'Sine Wave Example'
19
+ plot.xlabel 'x'
20
+ plot.ylabel 'sin(x)'
21
+
22
+ plot.data('sin(x)') { |ds|
23
+ ds.with = 'lines'
24
+ ds.linewidth = 4
25
+ }
26
+ }
@@ -0,0 +1,15 @@
1
+ require 'gnuplot'
2
+
3
+ file = File.expand_path('../output_file_example2.dat', __FILE__)
4
+
5
+ Gnuplot.plot_to(file) { |plot|
6
+ plot.xrange '[-10:10]'
7
+ plot.title 'Sine Wave Example'
8
+ plot.xlabel 'x'
9
+ plot.ylabel 'sin(x)'
10
+
11
+ plot.data('sin(x)') { |ds|
12
+ ds.with = 'lines'
13
+ ds.linewidth = 4
14
+ }
15
+ }
@@ -0,0 +1,13 @@
1
+ require 'gnuplot'
2
+
3
+ Gnuplot.plot { |plot|
4
+ plot.xrange '[-10:10]'
5
+ plot.title 'Sine Wave Example'
6
+ plot.xlabel 'x'
7
+ plot.ylabel 'sin(x)'
8
+
9
+ plot.data('sin(x)') { |ds|
10
+ ds.with = 'lines'
11
+ ds.linewidth = 4
12
+ }
13
+ }
@@ -0,0 +1,5 @@
1
+ module Gnuplot
2
+
3
+ VERSION = '2.3.5.1'
4
+
5
+ end
data/lib/gnuplot.rb ADDED
@@ -0,0 +1,332 @@
1
+ require 'matrix'
2
+ require 'nuggets/file/which'
3
+
4
+ # Methods and variables for interacting with the GNUPLOT process. Most of
5
+ # these methods are for sending data to a GNUPLOT process, not for reading
6
+ # from it. Some of the methods are implemented as added methods to the built
7
+ # in classes.
8
+
9
+ module Gnuplot
10
+
11
+ # Holds the map of file extensions to GNUPLOT terminals.
12
+ TERMINAL = Hash.new { |h, k| h[k] = k }.update(
13
+ 'dat' => nil,
14
+ 'jpg' => 'jpeg',
15
+ 'ps' => 'postscript'
16
+ )
17
+
18
+ class << self
19
+
20
+ attr_writer :gnuplot
21
+
22
+ # Maps file extension (with optional dot) to GNUPLOT terminal (cf.
23
+ # TERMINAL).
24
+ def terminal(ext)
25
+ TERMINAL[ext.to_s.sub(/\A\./, '')]
26
+ end
27
+
28
+ # Delegates to File.which, but String#strip's +bin+ first.
29
+ def which(bin)
30
+ File.which(bin.strip)
31
+ end
32
+
33
+ # Finds the path to the GNUPLOT executable. The name of the executable
34
+ # can be specified using the link:#gnuplot= accessor or the RB_GNUPLOT
35
+ # environment variable but will default to the command +gnuplot+.
36
+ #
37
+ # Adds the persist flag to the GNUPLOT executable if +persist+ is +true+.
38
+ #
39
+ # Returns the path to the GNUPLOT executable or raises an error if one
40
+ # cannot be found.
41
+ def gnuplot(persist = true)
42
+ @gnuplot ||= which(ENV['RB_GNUPLOT'] || 'gnuplot')
43
+ raise 'GNUPLOT executable not found' unless @gnuplot
44
+
45
+ "#{@gnuplot}#{' -persist' if persist}"
46
+ end
47
+
48
+ # Opens a GNUPLOT process via Gnuplot.gnuplot (passing the +persist+ flag) and
49
+ # yields the IO object associated with the GNUPLOT process to the block.
50
+ #
51
+ # See the {GNUPLOT documentation}[http://gnuplot.sourceforge.net/documentation.html]
52
+ # for information on the persist flag.
53
+ def open(persist = true, mode = 'w')
54
+ IO.popen(gnuplot(persist), mode) { |gp| yield gp }
55
+ end
56
+
57
+ # Wraps the calls to Gnuplot.open and Gnuplot::Plot.new.
58
+ def plot(persist = true, *args, &block)
59
+ open(persist) { |gp| Plot.new(gp, *args, &block) }
60
+ end
61
+
62
+ # If +file+ is a file name that has a Gnuplot.terminal associated with it,
63
+ # the GNUPLOT process's terminal will be set accordingly and its output
64
+ # redirected to +file+.
65
+ #
66
+ # If +file+ is an IO object or doesn't have a terminal associated with it,
67
+ # the GNUPLOT process's output will simply be written to +file+.
68
+ def plot_to(file, persist = false, *args, &block)
69
+ io, file = file, nil if file.respond_to?(:write)
70
+
71
+ if file and term = terminal(File.extname(file))
72
+ plot(persist, *args) { |plot|
73
+ block[plot]
74
+
75
+ plot.terminal term unless plot[:terminal] || plot[:term]
76
+ plot.output file.to_s unless plot[:output] || plot[:out]
77
+ }
78
+ else
79
+ begin
80
+ io ||= File.open(file, 'w')
81
+ Plot.new(io, *args, &block)
82
+ ensure
83
+ io.close if file && io
84
+ end
85
+ end
86
+ end
87
+
88
+ end
89
+
90
+ # Holds command information and performs the formatting of that command
91
+ # information to a GNUPLOT process. When constructing a new plot for
92
+ # GNUPLOT, this is the first object that must be instantiated. On this
93
+ # object set the various properties and add data sets.
94
+
95
+ class Plot
96
+
97
+ QUOTED = %w[title output xlabel ylabel]
98
+
99
+ attr_accessor :io, :cmd, :data, :sets, :arbitrary_lines
100
+
101
+ def initialize(io = nil, cmd = 'plot')
102
+ @io, @cmd, @data, @sets, @arbitrary_lines = io, cmd, [], [], []
103
+
104
+ yield self if block_given?
105
+
106
+ plot! if io
107
+ end
108
+
109
+ # Sends the data and commands to the GNUPLOT process, drawing the plot.
110
+ #
111
+ # Prints the plot commands that are sent to the GNUPLOT process to +io+
112
+ # if +verbose+ is +true+.
113
+ def plot!(verbose = $VERBOSE, io = $stderr)
114
+ if verbose && io
115
+ io << "Writing this to GNUPLOT:\n"
116
+ to_gplot(io)
117
+ end
118
+
119
+ to_gplot
120
+ end
121
+
122
+ # Invoke the set method on the plot using the name of the invoked method
123
+ # as the set variable and any arguments that have been passed as the
124
+ # value. See the #set method for more details.
125
+ def method_missing(method, *args)
126
+ set(method, *args)
127
+ end
128
+
129
+ # Set a variable to the given +value+. +var+ must be a GNUPLOT variable
130
+ # and +value+ must be the value to set it to. Automatic quoting will be
131
+ # performed if the variable requires it (see QUOTED).
132
+ def set(var, value = '')
133
+ var = var.to_s
134
+ value = %Q{"#{value}"} if QUOTED.include?(var) && value !~ /\A'.*'\z/
135
+
136
+ @sets << [var, value]
137
+ end
138
+
139
+ alias_method :[]=, :set
140
+
141
+ # Return the current value of the GNUPLOT variable +var+. This will
142
+ # return the setting that is currently in the instance, not one that's
143
+ # been given to the GNUPLOT process.
144
+ def [](var)
145
+ assoc = @sets.assoc(var.to_s)
146
+ assoc.last if assoc
147
+ end
148
+
149
+ # If +args+ is non-empty or +block+ is given, calls #add_data. Returns
150
+ # the current data otherwise.
151
+ def data(*args, &block)
152
+ args.empty? && !block ? @data : add_data(*args, &block)
153
+ end
154
+
155
+ # Adds the DataSet +data+ to the GNUPLOT process's data sets. If +data+
156
+ # is not already a DataSet object, DataSet.new will be called with +data+
157
+ # and +block+ as arguments.
158
+ def add_data(data = nil, &block)
159
+ @data.push(data.is_a?(DataSet) ? data : DataSet.new(data, &block))
160
+ end
161
+
162
+ # Adds an arbitrary +line+ to write to the GNUPLOT process. Returns +self+
163
+ # to allow chaining.
164
+ def <<(line)
165
+ @arbitrary_lines << line.to_s
166
+ self
167
+ end
168
+
169
+ # Sends the GNUPLOT data and commands to +io+.
170
+ def to_gplot(io = io)
171
+ to_plot(io) { |ds| ds.to_gplot(io) }
172
+ end
173
+
174
+ private
175
+
176
+ def to_plot(io)
177
+ return unless io
178
+
179
+ @sets.each { |var, val| io << "set #{var} #{val}\n" }
180
+ @arbitrary_lines.each { |line| io << line << "\n" }
181
+
182
+ unless @data.empty?
183
+ io << @cmd
184
+ io << ' '
185
+ io << @data.map { |e| e.plot_args }.compact.join(', ')
186
+ io << "\n"
187
+
188
+ @data.each { |ds| io << "e\n" if yield ds } if block_given?
189
+ end
190
+
191
+ io
192
+ end
193
+
194
+ end
195
+
196
+ class SPlot < Plot
197
+
198
+ def initialize(io = nil, cmd = 'splot')
199
+ super
200
+ end
201
+
202
+ # Sends the GNUPLOT data and commands to +io+.
203
+ def to_gplot(io = io)
204
+ to_plot(io) { |ds| ds.to_gsplot(io) }
205
+ end
206
+
207
+ end
208
+
209
+ # Container for a single data set being displayed by GNUPLOT. Each object
210
+ # has a reference to the actual data being plotted as well as settings that
211
+ # control the +plot+ command. The data object must support the +to_gplot+
212
+ # command.
213
+ #
214
+ # The other attributes correspond to their related string in the GNUPLOT
215
+ # command. See the {GNUPLOT documentation}[http://gnuplot.sourceforge.net/documentation.html]
216
+ # for more information on this.
217
+
218
+ class DataSet
219
+
220
+ attr_accessor :data, :title, :with, :using, :linewidth, :matrix, :smooth, :axes
221
+
222
+ def initialize(data = nil)
223
+ @data = data
224
+ yield self if block_given?
225
+ end
226
+
227
+ # Set no title.
228
+ def notitle
229
+ @title = 'notitle'
230
+ end
231
+
232
+ # Write the plot arguments to +io+.
233
+ def plot_args(io = '')
234
+ # Order of these is important or GNUPLOT barfs on 'em
235
+ %w[data using axes title matrix smooth with linewidth].each { |arg|
236
+ plot_arg(io, arg)
237
+ }
238
+
239
+ io
240
+ end
241
+
242
+ # Write the plot data to +io+.
243
+ def to_gplot(io = '')
244
+ @data.to_gplot(io) if plot?
245
+ end
246
+
247
+ # Write the splot data to +io+.
248
+ def to_gsplot(io = '')
249
+ @data.to_gsplot(io) if plot?
250
+ end
251
+
252
+ private
253
+
254
+ def plot_arg(io, arg)
255
+ var = "@#{arg}"
256
+ val = instance_variable_get(var) if instance_variable_defined?(var)
257
+
258
+ case arg
259
+ when 'data'
260
+ io << (val.is_a?(String) ? val : "'-'")
261
+ when 'title'
262
+ io << (val =~ /notitle/ ? ' notitle' : " title '#{val}'") if val
263
+ when 'matrix'
264
+ io << ' matrix' if val
265
+ else
266
+ io << " #{arg} #{val}" if val
267
+ end
268
+ end
269
+
270
+ def plot?
271
+ @data && !@data.is_a?(String)
272
+ end
273
+
274
+ end
275
+
276
+ end
277
+
278
+ class Array
279
+
280
+ # Write GNUPLOT plot data to +io+.
281
+ def to_gplot(io = '')
282
+ case x = self[0]
283
+ when Array
284
+ x.zip(*self[1..-1]).each { |a| io << a.join(' ') << "\n" }
285
+ io << 'e'
286
+ when Numeric then each { |i| io << "#{i}\n" }
287
+ else x.zip(*self[1..-1]).to_gplot(io)
288
+ end
289
+
290
+ io
291
+ end
292
+
293
+ # Write GNUPLOT splot data to +io+.
294
+ def to_gsplot(io = '')
295
+ case x = self[0]
296
+ when Array
297
+ y, d = values_at(1, 2)
298
+
299
+ x.each_with_index { |xv, i|
300
+ y.each_with_index { |yv, j|
301
+ io << [xv, yv, d[i][j]].join(' ') << "\n"
302
+ }
303
+ }
304
+
305
+ io
306
+ when Numeric then each { |i| io << "#{i}\n" }
307
+ else x.zip(*self[1..-1]).to_gsplot(io)
308
+ end
309
+
310
+ io
311
+ end
312
+
313
+ end
314
+
315
+ class Matrix
316
+
317
+ # Write GNUPLOT plot data to +io+.
318
+ def to_gplot(io = '', xgrid = nil, ygrid = nil)
319
+ xgrid ||= (0...column_size).to_a
320
+ ygrid ||= (0...row_size).to_a
321
+
322
+ ygrid.each_with_index { |y, j|
323
+ xgrid.each_with_index { |x, i|
324
+ z = self[j, i]
325
+ io << "#{x} #{y} #{z}\n" if z
326
+ }
327
+ }
328
+
329
+ io
330
+ end
331
+
332
+ end
@@ -0,0 +1,110 @@
1
+ require 'gnuplot'
2
+ require 'test/unit'
3
+
4
+ class StdDataTest < Test::Unit::TestCase
5
+
6
+ def test_array_1d
7
+ data = (0..5).to_a
8
+ ds = Gnuplot::DataSet.new(data)
9
+
10
+ assert data == ds.data
11
+ assert data.join("\n") + "\n", ds.to_gplot
12
+ end
13
+
14
+ # Test a multidimensional array.
15
+
16
+ def test_array_nd
17
+ d1 = (0..3).to_a
18
+ d2 = d1.map { |v| 3 * v }
19
+ d3 = d2.map { |v| 4 * v }
20
+
21
+ data = [d1, d2, d3]
22
+ ds = Gnuplot::DataSet.new(data)
23
+
24
+ assert data == ds.data
25
+ assert "0 0 0\n1 3 12\n2 6 24\n3 9 36\n", ds.to_gplot
26
+ end
27
+
28
+ end
29
+
30
+ class DataSetTest < Test::Unit::TestCase
31
+
32
+ def test_yield_ctor
33
+ ds = Gnuplot::DataSet.new { |ds|
34
+ ds.with = 'lines'
35
+ ds.using = '1:2'
36
+ ds.data = [[0, 1, 2], [1, 2, 5]]
37
+ }
38
+
39
+ assert 'lines', ds.with
40
+ assert '1:2', ds.using
41
+
42
+ assert nil == ds.title
43
+ assert [[0, 1, 2], [1, 2, 5]] == ds.data
44
+
45
+ assert "''-' using 1:2 with lines", ds.plot_args
46
+ assert "0 1\n1 2\n2 5\n", ds.to_gplot
47
+ end
48
+
49
+ end
50
+
51
+ class PlotTest < Test::Unit::TestCase
52
+
53
+ def test_no_data
54
+ plot = Gnuplot::Plot.new { |p|
55
+ p.set 'output', "'foo'"
56
+ p.set 'terminal', 'postscript enhanced'
57
+ }
58
+
59
+ assert plot.sets == [
60
+ ['output', "'foo'"],
61
+ ['terminal', 'postscript enhanced']
62
+ ]
63
+
64
+ assert plot.to_gplot, "set output 'foo'\nset terminal postscript enhanced\n"
65
+ end
66
+
67
+ def test_set
68
+ plot = Gnuplot::Plot.new { |gp| gp.set 'title', 'foo' }
69
+ assert "'foo'", plot['title']
70
+
71
+ plot.set 'title', "'bar'"
72
+ assert "'bar'", plot['title']
73
+ end
74
+
75
+ end
76
+
77
+ require 'rbconfig'
78
+ CONFIG = Config::MAKEFILE_CONFIG
79
+
80
+ # This attempts to test the functions that comprise the gnuplot package. Most
81
+ # of the bug reports that I get for this package have to do with finding the
82
+ # gnuplot executable under different environments so that makes it difficult
83
+ # to test on a single environment. To try to get around this I'm using the
84
+ # rbconfig library and its path to the sh environment variable.
85
+
86
+ class GnuplotModuleTest < Test::Unit::TestCase
87
+
88
+ def test_which
89
+ # Put the spaces around the command to make sure that it gets stripped
90
+ # properly.
91
+ assert CONFIG['SHELL'], Gnuplot.which(' sh ')
92
+ assert CONFIG['SHELL'], Gnuplot.which(CONFIG['SHELL'])
93
+ end
94
+
95
+ def test_gnuplot
96
+ cmd = Gnuplot.gnuplot
97
+ assert Gnuplot.which('gnuplot') + ' -persist', cmd
98
+
99
+ cmd = Gnuplot.gnuplot(false)
100
+ assert Gnuplot.which('gnuplot'), cmd
101
+
102
+ # If I set the name of the gnuplot environment variable to a different
103
+ # name (one that is in the path) then I should get the shell name as the
104
+ # result of the gnuplot call.
105
+
106
+ ENV['RB_GNUPLOT'] = 'sh'
107
+ assert CONFIG['SHELL'], Gnuplot.gnuplot(false)
108
+ end
109
+
110
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: blackwinter-gnuplot
3
+ version: !ruby/object:Gem::Version
4
+ hash: 97
5
+ prerelease:
6
+ segments:
7
+ - 2
8
+ - 3
9
+ - 5
10
+ - 1
11
+ version: 2.3.5.1
12
+ platform: ruby
13
+ authors:
14
+ - Roger Pack
15
+ - Jens Wille
16
+ autorequire:
17
+ bindir: bin
18
+ cert_chain: []
19
+
20
+ date: 2011-02-22 00:00:00 +01:00
21
+ default_executable:
22
+ dependencies:
23
+ - !ruby/object:Gem::Dependency
24
+ name: ruby-nuggets
25
+ prerelease: false
26
+ requirement: &id001 !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ hash: 3
32
+ segments:
33
+ - 0
34
+ version: "0"
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ description:
38
+ email:
39
+ - rogerpack2005@gmail.com
40
+ - jens.wille@uni-koeln.de
41
+ executables: []
42
+
43
+ extensions: []
44
+
45
+ extra_rdoc_files:
46
+ - ChangeLog
47
+ - LICENSE.txt
48
+ - README.rdoc
49
+ files:
50
+ - AUTHORS.txt
51
+ - ChangeLog
52
+ - LICENSE.txt
53
+ - README.rdoc
54
+ - Rakefile
55
+ - examples/.gitignore
56
+ - examples/discrete_points.rb
57
+ - examples/histogram.rb
58
+ - examples/multiple_data_sets.rb
59
+ - examples/output_file1.rb
60
+ - examples/output_file2.rb
61
+ - examples/sine_wave.rb
62
+ - lib/gnuplot.rb
63
+ - lib/gnuplot/version.rb
64
+ - test/test_gnuplot.rb
65
+ has_rdoc: true
66
+ homepage: http://github.com/blackwinter/ruby_gnuplot
67
+ licenses: []
68
+
69
+ post_install_message:
70
+ rdoc_options: []
71
+
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ hash: 3
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ hash: 3
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ requirements: []
93
+
94
+ rubyforge_project:
95
+ rubygems_version: 1.5.2
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: Utility library to aid in interacting with GNUPLOT
99
+ test_files:
100
+ - examples/discrete_points.rb
101
+ - examples/histogram.rb
102
+ - examples/multiple_data_sets.rb
103
+ - examples/output_file1.rb
104
+ - examples/output_file2.rb
105
+ - examples/sine_wave.rb
106
+ - test/test_gnuplot.rb