All Projects → rdp → Ruby_gnuplot

rdp / Ruby_gnuplot

Licence: bsd-3-clause
The ruby gnuplot gem [gnuplot] [rgnuplot] (official releases of the gnuplot gem are from rdp branch)

Programming Languages

ruby
36898 projects - #4 most used programming language

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. Pre-requisites and Installation

  1. (mac) Install XQuartz from here: 
     @http://xquartz.macosforge.org/landing/@
  
  2. Install gnuplot with homebrew (not OS X? install it using your package manager):
     @brew install gnuplot [email protected]
  
  3. Install gnuplot gem:
     @gem install [email protected]

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 separate
  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:


  1.     Instantiate a @[email protected] or @[email protected] object and set parameters by gnuplot variable name. 

  2.     Instantiate @[email protected] objects and attach Ruby objects containing the data to be plotted to the @[email protected] Attach properties that modify the plot command using the modifier name.
  
  3.     Send the @[email protected]/@[email protected] object to a @[email protected] instance for plotting.  

  The Version 2.0 interface makes very heavy use of blocks leading to very
  readable code.

@[email protected]

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 @[email protected] method.

@[email protected]

@[email protected]

bq. Create a new @[email protected] or @[email protected] object. @[email protected] 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.

@[email protected]

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 @[email protected] as long as it understands the @[email protected] method.

@[email protected]

bq. Within Gnuplot, plot data is read in very simple formats. The @[email protected] 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 @[email protected] method on the following classes: @[email protected], @[email protected], and @[email protected] Simply define a @[email protected] 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 @[email protected] The constructor initializes this empty array before yielding to the block. This method uses the @<<@ operator to add the @[email protected] to the plot.

  • When the plot block ends, if an @[email protected] object is given to the @[email protected] constructor, the plot commands will be written to the @[email protected] 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.xlabel "x"
    plot.ylabel "sin(x)"
    
    plot.data << Gnuplot::DataSet.new( "sin(x)" ) do |ds|
      ds.with = "lines"
      ds.linewidth = 4
    end
    
  end
  
end

Or 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/[email protected]

h3. Plotting discrete points

Array data can be plotted quite easily since @[email protected] have a defined @[email protected] method.

Simply pass an array of data to the constructor of the @[email protected] object or set the data property of the @[email protected] 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
end

h3. 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 @[email protected] 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
end

h3. Miscellanrous

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

h3. Security

Note that if you pass any user-controlled strings to the gem, it's possible for an attacker to run arbitrary commands.

In addition to title, any other graph properties that accept strings should be affected too. they're all passed to the system command. So only use strings you trust.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].