blackwinter-gnuplot 2.3.5.1

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/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