gnuplot-2.6.2/ 0000755 0000041 0000041 00000000000 12142216002 013227 5 ustar www-data www-data gnuplot-2.6.2/README.textile 0000644 0000041 0000041 00000015033 12142216002 015566 0 ustar www-data www-data h1. Ruby Gnuplot - How To p=. ["ChangeLog":/ChangeLog] ["Authors":AUTHORS.txt] ["License":LICENSE.txt] h2. History and Background Gnuplot is a program that has a rich language for the generation of plots. It has a unique place in academia as it was one of the first freely available programs for plot generation. I started using gnuplot over 10 years ago while pursuing my Master's degree in Physics and have been using it actively ever since. Now rdp maintains it. See also the changelog for more detail. h2. Ruby Gnuplot Concepts Gnuplot has a very simple conceptual model. Calls to _Set_ are made to set parameters and either _Plot_ or _Splot_ is called to generate the actual plot. The _dataset_ to be plotted can be specified in a number of ways, contained in a seperate file, generated from a function, read from standard input, or read immediately after the plot command. The object model for the Ruby gnuplot wrapper directly mimics this layout and flow. The following are the standard steps for generating a plot: # Instantiate a @Plot@ or @Splot@ object and set parameters by gnuplot variable name. # Instantiate @DataSet@ objects and attach Ruby objects containing the data to be plotted to the @DataSet@. Attach properties that modify the plot command using the modifier name. # Send the @Plot@/@Splot@ object to a @Gnuplot@ instance for plotting. The Version 2.0 interface makes very heavy use of blocks leading to very readable code. @Gnuplot.open@ bq. Instantiates a new Gnuplot process. The path to the executable is determined on a Unix or MacOSX system using the which command. Windows users, I have no idea what to do. If a block is given to the function the opened process is passed into the block. This mimics the most common usage of the @File.open@ method. @Plot.new@ @SPlot.new@ bq. Create a new @Plot@ or @SPlot@ object. @DataSet@ s are attached to the object to specify the data and its properties. If a block is given to the function, the plot object is passed into the block. @DataSet.new@ bq. Associates a Ruby object containing the data to plot with the properties that will be passed to the plot command for that dataset. Any Ruby object can be associated with a @DataSet@ as long as it understands the @to_gplot@ method. @to_gplot@ bq. Within Gnuplot, plot data is read in very simple formats. The @to_gplot@ method is expected to write the data of the object in a format that is understandable by Gnuplot. One of the many great things about Ruby is that methods can be added after the original declaration. The gnuplot module defines the @to_gplot@ method on the following classes: @Array@, @String@, and @Matrix@. Simply define a @to_gplot@ method on your own class to tie the class into gnuplot. h2. Examples h3. Simple sin wave bq. The following example simply plots the value of sin(x) between the ranges of -10 and 10. A few points to notice: * The code uses nested blocks to construct the plot. The newly created object is passed to the block so it can be modified in place. * Each of the gnuplot plot variables are modified using the variable name as a method name on the plot object or on the dataset object. The wrapper also takes care of the single quoting that is required on some of the variables like @title@, @ylabel@, and @xlabel@. * The plot object simply has an array of @DataSet@s. The constructor initializes this empty array before yielding to the block. This method uses the @<<@ operator to add the @DataSet@ to the plot. * When the plot block ends, if an @IO@ object is given to the @Plot@ constructor, the plot commands will be written to the @IO@ object. Any object can be passed to the constructor as long as it understands the @<<@ operator.
Gnuplot.open do |gp| Gnuplot::Plot.new( gp ) do |plot| plot.xrange "[-10:10]" plot.title "Sin Wave Example" plot.ylabel "x" plot.xlabel "sin(x)" plot.data << Gnuplot::DataSet.new( "sin(x)" ) do |ds| ds.with = "lines" ds.linewidth = 4 end end endOr you can write it out to a file (the above snippet displays the graph, in Linux, but in windows you'd need to write it to a file). See the file @examples/output_image_file.rb@. h3. Plotting discrete points Array data can be plotted quite easily since @Array@s have a defined @to_gplot@ method. Simply pass an array of data to the constructor of the @DataSet@ object or set the data property of the @DataSet@. In this example, because there are two arrays, each array will be a single column of data to the gnuplot process.
Gnuplot.open do |gp| Gnuplot::Plot.new( gp ) do |plot| plot.title "Array Plot Example" plot.xlabel "x" plot.ylabel "x^2" x = (0..50).collect { |v| v.to_f } y = x.collect { |v| v ** 2 } plot.data << Gnuplot::DataSet.new( [x, y] ) do |ds| ds.with = "linespoints" ds.notitle end end endh3. Multiple Data Sets As many data sets as are desired can be attached to a plot. Each of these can have their own plot modifiers. Notice in this example how the data array is explicitly set instead of using the @<<@ operator. Also in this example, the commands are not written to the Gnuplot process but are instead written to a File called @gnuplot.dat@. This file can later be run directly by a gnuplot process as it contains only the gnuplot commands.
File.open( "gnuplot.dat", "w") do |gp| Gnuplot::Plot.new( gp ) do |plot| plot.xrange "[-10:10]" plot.title "Sin Wave Example" plot.ylabel "x" plot.xlabel "sin(x)" x = (0..50).collect { |v| v.to_f } y = x.collect { |v| v ** 2 } plot.data = [ Gnuplot::DataSet.new( "sin(x)" ) { |ds| ds.with = "lines" ds.title = "String function" ds.linewidth = 4 }, Gnuplot::DataSet.new( [x, y] ) { |ds| ds.with = "linespoints" ds.title = "Array data" } ] end endYou can also add arbitrary lines to the output
plot.arbitrary_lines << "set ylabel \"y label" font \"Helvetica,20\""See more in the examples folder. Also since this is basically just a wrapper for gnuplot itself, you should be able to do anything that it can do (demos: http://gnuplot.sourceforge.net/demo_4.4/ ) gnuplot-2.6.2/test/ 0000755 0000041 0000041 00000000000 12142216002 014206 5 ustar www-data www-data gnuplot-2.6.2/test/multtest.rb 0000644 0000041 0000041 00000001110 12142216002 016405 0 ustar www-data www-data require '../lib/gnuplot' # File.open( "gnuplot.dat", "w") do |gp| Gnuplot.open do |gp| Gnuplot::Plot.new( gp ) do |plot| plot.xrange "[-10:10]" plot.title "Sin Wave Example" plot.ylabel "x" plot.xlabel "sin(x)" x = (0..50).collect { |v| v.to_f } y = x.collect { |v| v ** 2 } plot.data = [ Gnuplot::DataSet.new( "sin(x)" ) { |ds| ds.with = "lines" ds.title = "String function" ds.linewidth = 4 }, Gnuplot::DataSet.new( [x, y] ) { |ds| ds.with = "linespoints" ds.title = "Array data" } ] end end gnuplot-2.6.2/test/sinwave.rb 0000644 0000041 0000041 00000000516 12142216002 016211 0 ustar www-data www-data require '../lib/gnuplot' Gnuplot.open do |gp| Gnuplot::Plot.new( gp ) do |plot| plot.xrange "[-10:10]" plot.title "Sin Wave Example" plot.ylabel "x" plot.xlabel "sin(x)" plot.data << Gnuplot::DataSet.new( "sin(x)" ) do |ds| ds.with = "lines" ds.linewidth = 4 end end end gnuplot-2.6.2/test/histtest.rb 0000644 0000041 0000041 00000000651 12142216002 016404 0 ustar www-data www-data require '../lib/gnuplot' Gnuplot.open do |gp| gp << "bin(x, s) = s*int(x/s)\n" Gnuplot::Plot.new( gp ) do |plot| plot.title "Histogram" plot.xlabel "x" plot.ylabel "frequency" x = (0..500).collect { |v| (rand()-0.5)**3 } plot.data << Gnuplot::DataSet.new( [x] ) do |ds| ds.title = "smooth frequency" ds.using = "(bin($1,.01)):(1.)" ds.smooth = "freq" ds.with = "boxes" end end end gnuplot-2.6.2/test/test_gnuplot.rb 0000644 0000041 0000041 00000005726 12142216002 017274 0 ustar www-data www-data # -*- ruby -*- require '../lib/gnuplot' require 'test/unit' class StdDataTest < Test::Unit::TestCase def test_array_1d data = (0..5).to_a ds = Gnuplot::DataSet.new( data ) assert data == ds.data assert data.join("\n") + "\n", ds.to_gplot end # Test a multidimensional array. def test_array_nd d1 = (0..3).to_a d2 = d1.collect { |v| 3 * v } d3 = d2.collect { |v| 4 * v } data = [ d1, d2, d3 ] ds = Gnuplot::DataSet.new( data ) assert data == ds.data assert "0 0 0\n1 3 12\n2 6 24\n3 9 36\n", ds.to_gplot end end class DataSetTest < Test::Unit::TestCase def test_yield_ctor ds = Gnuplot::DataSet.new do |ds| ds.with = "lines" ds.using = "1:2" ds.data = [ [0, 1, 2], [1, 2, 5] ] end assert "lines", ds.with assert "1:2", ds.using assert nil == ds.title assert [ [0, 1, 2], [1, 2, 5] ] == ds.data assert "'-' using 1:2 with lines", ds.plot_args assert "0 1\n1 2\n2 5\n", ds.to_gplot end end class PlotTest < Test::Unit::TestCase def test_no_data plot = Gnuplot::Plot.new do |p| p.set "output", "'foo'" p.set "terminal", "postscript enhanced" p.unset "border" end assert( plot.settings == [ [:set, "output", "'foo'"], [:set, "terminal", "postscript enhanced"], [:unset, "border"] ] ) assert( plot.to_gplot, \ "set output 'foo'\nset terminal postscript enhanced\n" ) end def test_set plot = Gnuplot::Plot.new do |p| p.set "title", "foo" end assert "'foo'", plot["title"] plot.set "title", "'foo'" assert "'foo'", plot["title"] end def test_unset plot = Gnuplot::Plot.new do |p| p.unset "title" end assert_nil plot["title"] plot.unset "title" assert_nil plot["title"] end end require 'rbconfig' CONFIG = Config::MAKEFILE_CONFIG # This attempts to test the functions that comprise the gnuplot package. Most # of the bug reports that I get for this package have to do with finding the # gnuplot executable under different environments so that makes it difficult # to test on a single environment. To try to get around this I'm using the # rbconfig library and its path to the sh environment variable. class GnuplotModuleTest def test_which # Put the spaces around the command to make sure that it gets stripped # properly. assert( CONFIG["SHELL"], Gnuplot::which(" sh " ) ) assert( CONFIG["SHELL"], Gnuplot::which( CONFIG["SHELL"] ) ) end def test_gnuplot cmd = Gnuplot.gnuplot assert( Gnuplot::which("gnuplot") + " -persist", cmd ) cmd = Gnuplot.gnuplot(false) assert( Gnuplot::which("gnuplot"), cmd ) # If I set the name of the gnuplot environment variable to a different # name (one that is in the path) then I should get the shell name as the # result of the gnuplot call. ENV["RB_GNUPLOT"] = "sh" assert( CONFIG["SHELL"], Gnuplot.gnuplot(false) ) end end gnuplot-2.6.2/test/arrtest.rb 0000644 0000041 0000041 00000000571 12142216002 016222 0 ustar www-data www-data require '../lib/gnuplot' Gnuplot.open do |gp| Gnuplot::Plot.new( gp ) do |plot| plot.title "Array Plot Example" plot.ylabel "x" plot.xlabel "x^2" x = (0..50).collect { |v| v.to_f } y = x.collect { |v| v ** 2 } plot.data << Gnuplot::DataSet.new( [x, y] ) do |ds| ds.with = "linespoints" ds.notitle end end end gnuplot-2.6.2/examples/ 0000755 0000041 0000041 00000000000 12142216002 015045 5 ustar www-data www-data gnuplot-2.6.2/examples/discrete_points.rb 0000644 0000041 0000041 00000000640 12142216002 020570 0 ustar www-data www-data $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__)) require "gnuplot" Gnuplot.open do |gp| Gnuplot::Plot.new( gp ) do |plot| plot.title "Array Plot Example" plot.ylabel "x^2" plot.xlabel "x" x = (0..50).collect { |v| v.to_f } y = x.collect { |v| v ** 2 } plot.data << Gnuplot::DataSet.new( [x, y] ) do |ds| ds.with = "linespoints" ds.notitle end end end gnuplot-2.6.2/examples/histogram.rb 0000644 0000041 0000041 00000001722 12142216002 017371 0 ustar www-data www-data $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__)) require "gnuplot" Gnuplot.open do |gp| Gnuplot::Plot.new(gp) do |plot| plot.title "Histogram example" plot.style "data histograms" plot.xtics "nomirror rotate by -45" titles = %w{decade Austria Hungary Belgium} data = [ ["1891-1900", 234081, 181288, 18167], ["1901-1910", 668209, 808511, 41635], ["1911-1920", 453649, 442693, 33746], ["1921-1930", 32868, 30680, 15846], ["1931-1940", 3563, 7861, 4817], ["1941-1950", 24860, 3469, 12189], ["1951-1960", 67106, 36637, 18575], ["1961-1970", 20621, 5401, 9192], ] x = data.collect{|arr| arr.first} (1..3).each do |col| y = data.collect{|arr| arr[col]} plot.data << Gnuplot::DataSet.new( [x, y] ) do |ds| ds.using = "2:xtic(1)" ds.title = titles[col] end end end end gnuplot-2.6.2/examples/sin_wave.rb 0000644 0000041 0000041 00000000604 12142216002 017205 0 ustar www-data www-data $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__)) require "gnuplot" Gnuplot.open do |gp| Gnuplot::Plot.new( gp ) do |plot| plot.xrange "[-10:10]" plot.title "Sin Wave Example" plot.ylabel "sin(x)" plot.xlabel "x" plot.data << Gnuplot::DataSet.new( "sin(x)" ) do |ds| ds.with = "lines" ds.linewidth = 4 end end sleep 10 end gnuplot-2.6.2/examples/output_image_file.rb 0000644 0000041 0000041 00000001647 12142216002 021103 0 ustar www-data www-data $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__)) require "gnuplot" # See sin_wave.rb first Gnuplot.open do |gp| Gnuplot::Plot.new( gp ) do |plot| # The following lines allow outputting the graph to an image file. # The first set the kind of image that you want, while the second # redirects the output to a given file. # # Typical terminals: gif, png, postscript, latex, texdraw # # See http://mibai.tec.u-ryukyu.ac.jp/~oshiro/Doc/gnuplot_primer/gptermcmp.html # for a list of recognized terminals. # plot.terminal "gif" plot.output File.expand_path("../sin_wave.gif", __FILE__) # see sin_wave.rb plot.xrange "[-10:10]" plot.title "Sin Wave Example" plot.ylabel "sin(x)" plot.xlabel "x" plot.data << Gnuplot::DataSet.new( "sin(x)" ) do |ds| ds.with = "lines" ds.linewidth = 4 end end end puts 'created sin_wave.gif' gnuplot-2.6.2/examples/3d_surface_plot.rb 0000644 0000041 0000041 00000000332 12142216002 020444 0 ustar www-data www-data require "gnuplot" Gnuplot.open do |gp| Gnuplot::SPlot.new( gp ) do |plot| plot.grid plot.data = [ Gnuplot::DataSet.new( "x**2+y**2" ) do |ds| ds.with = "pm3d" end ] end sleep 10 end gnuplot-2.6.2/examples/multiple_data_sets.rb 0000644 0000041 0000041 00000001155 12142216002 021256 0 ustar www-data www-data $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__)) require "gnuplot" Gnuplot.open do |gp| Gnuplot::Plot.new( gp ) do |plot| plot.xrange "[-10:10]" plot.title "Sin Wave Example" plot.ylabel "sin(x)" plot.xlabel "x" x = (0..50).collect { |v| v.to_f } y = x.collect { |v| v ** 2 } plot.data = [ Gnuplot::DataSet.new( "sin(x)" ) { |ds| ds.with = "lines" ds.title = "String function" ds.linewidth = 4 }, Gnuplot::DataSet.new( [x, y] ) { |ds| ds.with = "linespoints" ds.title = "Array data" } ] end end gnuplot-2.6.2/examples/.gitignore 0000644 0000041 0000041 00000000014 12142216002 017030 0 ustar www-data www-data sin_wave.gif gnuplot-2.6.2/Rakefile 0000644 0000041 0000041 00000000716 12142216002 014700 0 ustar www-data www-data require 'jeweler2' Jeweler::Tasks.new do |s| s.name = 'gnuplot' s.description = s.summary = "Utility library to aid in interacting with gnuplot from ruby" s.version = "2.6.2" s.authors='roger pack' s.email = "rogerpack2005@gmail.com" s.homepage = "http://github.com/rdp/ruby_gnuplot/tree/master" end desc 'run unit tests' task :test do Dir.chdir 'test' for file in Dir['*'] system("ruby #{file}") end end Jeweler::RubygemsDotOrgTasks.new gnuplot-2.6.2/ChangeLog 0000644 0000041 0000041 00000007257 12142216002 015014 0 ustar www-data www-data 2.6.2 * llrt: Make SPlot.to_gplot use parent's implementation 2.6.1 * TheKnight Fix bug in SPlot.to_gplot implementation. 2.6.0 * better readme, allow for unsetting variables, thanks @kot-behemoth and @evnu 2.5.0 * save output to instance variable, thanks for the patch. 2.4.1 * Quote escape more strings. Thanks for the tip! 2.4.0 * Allow for 3D plots, fix examples. Thanks everybody! 2.3.6 * Cleanup readme (thanks blambeau again, really, for the snippets) 2.3.5 * Cleanup readme, add examples as real code files (thanks blambeau!) 2.3.4 * Include more files in the gem by switching to Jeweler (thanks Jeweler guyz)! 2.3.3 * Fix issue #4 (thanks Jakobs) * Fix some unit tests (thanks Nobu!) 2.3.2 Feb 2010 * Add an arbitrary_lines specifier 2.3.1 Feb 2010 * Fix a bug I introduced in 2.3.0 2.3.0 Feb 2010 * incorporate a few patch changes 2.2.3.1 July 18 2009 * output the raw "to gnuplot" data if $VERBOSE Version 2.2.2 July 2009 * raise if no executable found, should be windows compat. now Version 2.2 14-Nov-2005 * Formally added the LICENSE.txt file. It is the new BSD license as defined by opensource.org. See that file for details. * Added Gnuplot.which to try and fix the recurring problem of windows users having to hack code to get things working. * Added the Gnuplot.gnuplot function so that I can unit test the finding gnuplot executable routine. * In the Array.to_gplot method the terminating e is added to the output. This is in response to Bug #2209. Version 2.1 17-Nov-2004 * Array.to_gplot and Array.to_gsplot now support passing in arrays of arbitrary objects. This is in response to a request by Yoshiki Tsunesada (Tracker ID 1063) Version 2.0 10-Nov-2004 * The 2.0 version of the gnuplot interface is a cross between the original, object oriented version, and the version 1.0 which was simply a string manipulation library. h3. Version 0.9 bq. My first attempt at a Ruby interface to gnuplot was an object interface encapsulating gnuplot language. This was taken directly from the Python gnuplot interface. In spite of my being very familiar with Gnuplot and Ruby and being the author of the RGnuplot package, I found it non-intuitive to use the RGnuplot package. I found myself constantly looking at the code to figure out what I needed to do. This was not sufficient and did not sit well. h3. Version 1.0 bq. The second attempt at a Ruby interface was to do absolutely nothing but use Ruby's built in string manipulation methods. This meant that I could simply use my knowledge of Gnuplot without having to worry about objects. While in some ways an improvement over Version 0.9, it still did not sit well with me. h3. Version 2.0 bq. After attending RubyConf 2004 I was inspired by Rich Kilmer's use of Ruby to implement domain specific languages. That is the current implementation of Gnuplot and quite probably the one that I'll stick with for some time. This version combines the direct mapping of the gnuplot language without wrapping with the ruby syntax and mechanism of adding methods to existing classes to interface Ruby objects with gnuplot. h2. Setup h3. Version 2.2 If the 'gnuplot' command is in your path then there is no required setup. If the gnuplot executable for your system is called something other than simply 'gnuplot' then set the RB_GNUPLOT environment variable to the name of the executable. This must either be a full path to the gnuplot command or an executable filename that exists in your PATH environment variable. gnuplot-2.6.2/LICENSE.txt 0000644 0000041 0000041 00000003032 12142216002 015050 0 ustar www-data www-data Copyright (c) 2004-2005, Gordon James Miller (gmiller@bittwiddlers.com) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the BitTwiddlers, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. gnuplot-2.6.2/metadata.yml 0000644 0000041 0000041 00000002645 12142216002 015541 0 ustar www-data www-data --- !ruby/object:Gem::Specification name: gnuplot version: !ruby/object:Gem::Version version: 2.6.2 prerelease: platform: ruby authors: - roger pack autorequire: bindir: bin cert_chain: [] date: 2013-01-02 00:00:00.000000000 Z dependencies: [] description: Utility library to aid in interacting with gnuplot from ruby email: rogerpack2005@gmail.com executables: [] extensions: [] extra_rdoc_files: - ChangeLog - LICENSE.txt - README.textile files: - AUTHORS.txt - ChangeLog - LICENSE.txt - README.textile - Rakefile - examples/.gitignore - examples/3d_surface_plot.rb - examples/discrete_points.rb - examples/histogram.rb - examples/multiple_data_sets.rb - examples/output_image_file.rb - examples/sin_wave.rb - lib/gnuplot.rb - test/arrtest.rb - test/histtest.rb - test/multtest.rb - test/sinwave.rb - test/test_gnuplot.rb homepage: http://github.com/rdp/ruby_gnuplot/tree/master licenses: [] post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rubygems_version: 1.8.24 signing_key: specification_version: 3 summary: Utility library to aid in interacting with gnuplot from ruby test_files: [] gnuplot-2.6.2/AUTHORS.txt 0000644 0000041 0000041 00000000110 12142216002 015105 0 ustar www-data www-data Gordon James Miller Ara T. Howard Roger Pack Mike Cahill jakobs blambeau gnuplot-2.6.2/lib/ 0000755 0000041 0000041 00000000000 12142216002 013775 5 ustar www-data www-data gnuplot-2.6.2/lib/gnuplot.rb 0000644 0000041 0000041 00000021002 12142216002 016005 0 ustar www-data www-data # Methods and variables for interacting with the gnuplot process. Most of # these methods are for sending data to a gnuplot process, not for reading from # it. Most of the methods are implemented as added methods to the built in # classes. require 'matrix' module Gnuplot # Trivial implementation of the which command that uses the PATH environment # variable to attempt to find the given application. The application must # be executable and reside in one of the directories in the PATH environment # to be found. The first match that is found will be returned. # # bin [String] The name of the executable to search for. # # Return the full path to the first match or nil if no match is found. # def Gnuplot.which ( bin ) if RUBY_PLATFORM =~ /mswin|mingw/ all = [bin, bin + '.exe'] else all = [bin] end for exec in all if which_helper(exec) return which_helper(exec) end end return nil end def Gnuplot.which_helper bin return bin if File::executable? bin path = ENV['PATH'] path.split(File::PATH_SEPARATOR).each do |dir| candidate = File::join dir, bin.strip return candidate if File::executable? candidate end # This is an implementation that works when the which command is # available. # # IO.popen("which #{bin}") { |io| return io.readline.chomp } return nil end # Find the path to the gnuplot executable. The name of the executable can # be specified using the RB_GNUPLOT environment variable but will default to # the command 'gnuplot'. # # persist [bool] Add the persist flag to the gnuplot executable # # Return the path to the gnuplot executable or nil if one cannot be found. def Gnuplot.gnuplot( persist = true ) exe_loc = which( ENV['RB_GNUPLOT'] || 'gnuplot' ) raise 'gnuplot executable not found on path' unless exe_loc cmd = '"' + exe_loc + '"' cmd += " -persist" if persist cmd end # Open a gnuplot process that exists in the current PATH. If the persist # flag is true then the -persist flag is added to the command line. The # path to the gnuplot executable is determined using the 'which' command. # # See the gnuplot documentation for information on the persist flag. # # todo Add a method to pass the gnuplot path to the function. def Gnuplot.open( persist=true ) cmd = Gnuplot.gnuplot( persist ) IO::popen( cmd, "w+") { |io| yield io io.close_write @output = io.read } return @output end # Holds command information and performs the formatting of that command # information to a Gnuplot process. When constructing a new plot for # gnuplot, this is the first object that must be instantiated. On this # object set the various properties and add data sets. class Plot attr_accessor :cmd, :data, :settings QUOTED = [ "title", "output", "xlabel", "x2label", "ylabel", "y2label", "clabel", "cblabel", "zlabel" ] def initialize (io = nil, cmd = "plot") @cmd = cmd @settings = [] @arbitrary_lines = [] @data = [] yield self if block_given? puts "writing this to gnuplot:\n" + to_gplot + "\n" if $VERBOSE if io io << to_gplot io << store_datasets end end attr_accessor :arbitrary_lines # Invoke the set method on the plot using the name of the invoked method # as the set variable and any arguments that have been passed as the # value. See the +set+ method for more details. def method_missing( methId, *args ) set methId.id2name, *args end # Set a variable to the given value. +Var+ must be a gnuplot variable and # +value+ must be the value to set it to. Automatic quoting will be # performed if the variable requires it. # # This is overloaded by the +method_missing+ method so see that for more # readable code. def set ( var, value = "" ) value = "\"#{value}\"" if QUOTED.include? var unless value =~ /^'.*'$/ @settings << [ :set, var, value ] end # Unset a variable. +Var+ must be a gnuplot variable. def unset ( var ) @settings << [ :unset, var ] end # Return the current value of the variable. This will return the setting # that is currently in the instance, not one that's been given to a # gnuplot process. def [] ( var ) v = @settings.rassoc( var ) if v.nil? or v.first == :unset nil else v[2] end end def add_data ( ds ) @data << ds end def to_gplot (io = "") @settings.each do |setting| io << setting.map(&:to_s).join(" ") << "\n" end @arbitrary_lines.each{|line| io << line << "\n" } io end def store_datasets (io = "") if @data.size > 0 io << @cmd << " " << @data.collect { |e| e.plot_args }.join(", ") io << "\n" v = @data.collect { |ds| ds.to_gplot } io << v.compact.join("e\n") end io end end # Analogous to Plot class, holds command information and performs the formatting of that command # information to a Gnuplot process. Should be used when for drawing 3D plots. class SPlot < Plot def initialize (io = nil, cmd = "splot") super end # Currently using the implementation from parent class Plot. # Leaving the method explicit here, though, as to allow an specific # implementation for SPlot in the future. def to_gplot (io = "") super end end # Container for a single dataset being displayed by gnuplot. Each object # has a reference to the actual data being plotted as well as settings that # control the "plot" command. The data object must support the to_gplot # command. # # +data+ The data that will be plotted. The only requirement is that the # object understands the to_gplot method. # # The following attributes correspond to their related string in the gnuplot # command. See the gnuplot documentation for more information on this. # # title, with # # @todo Use the delegator to delegate to the data property. class DataSet attr_accessor :title, :with, :using, :data, :linewidth, :linecolor, :matrix, :smooth, :axes def initialize (data = nil) @data = data @title = @with = @using = @linewidth = @linecolor = @matrix = @smooth = @axes = nil # avoid warnings yield self if block_given? end def notitle @title = "notitle" end def plot_args (io = "") # Order of these is important or gnuplot barfs on 'em io << ( (@data.instance_of? String) ? @data : "'-'" ) io << " using #{@using}" if @using io << " axes #{@axes}" if @axes io << case @title when /notitle/ then " notitle" when nil then "" else " title '#{@title}'" end io << " matrix" if @matrix io << " smooth #{@smooth}" if @smooth io << " with #{@with}" if @with io << " linecolor #{@linecolor}" if @linecolor io << " linewidth #{@linewidth}" if @linewidth io end def to_gplot case @data when nil then nil when String then nil else @data.to_gplot end end def to_gsplot case @data when nil then nil when String then nil else @data.to_gsplot end end end end class Array def to_gplot if ( self[0].kind_of? Array ) then tmp = self[0].zip( *self[1..-1] ) tmp.collect { |a| a.join(" ") }.join("\n") + "\ne" elsif ( self[0].kind_of? Numeric ) then s = "" self.length.times { |i| s << "#{self[i]}\n" } s else self[0].zip( *self[1..-1] ).to_gplot end end def to_gsplot f = "" if ( self[0].kind_of? Array ) then x = self[0] y = self[1] d = self[2] x.each_with_index do |xv, i| y.each_with_index do |yv, j| f << [ xv, yv, d[i][j] ].join(" ") << "\n" end # f << "\n" end elsif ( self[0].kind_of? Numeric ) then self.length.times do |i| f << "#{self[i]}\n" end else self[0].zip( *self[1..-1] ).to_gsplot end f end end class Matrix def to_gplot (x = nil, y = nil) xgrid = x || (0...self.column_size).to_a ygrid = y || (0...self.row_size).to_a f = "" ygrid.length.times do |j| y = ygrid[j] xgrid.length.times do |i| if ( self[j,i] ) then f << "#{xgrid[i]} #{y} #{self[j,i]}\n" end end end f end end