http://xquartz.macosforge.org/landing/
2. Install gnuplot with homebrew (not OS X? install it using your package manager):
brew install gnuplot --with-x11
3. Install gnuplot gem:
gem install gnuplot
1. Instantiate a Plot
or Splot
object and set parameters by gnuplot variable name.
2. 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.
3. Send the Plot
/Splot
object to a Gnuplot
instance for plotting.
Gnuplot.open
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 theFile.open
method.
Plot.new
SPlot.new
Create a new
Plot
orSPlot
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
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 aDataSet
as long as it understands the
to_gplot
method.
to_gplot
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 theto_gplot
method on the following classes:
Array
,String
, andMatrix
.
Simply define ato_gplot
method on your own class to tie the class into
gnuplot.
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
, andxlabel
.
- 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 theDataSet
to the plot.
- When the plot block ends, if an
IO
object is given to thePlot
constructor, the plot commands will be written to theIO
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/output_image_file.rb
.
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 end
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 end
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/ )
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.