Advanced plotting in Ruby with Gnuplot

Posted . Visible to the public.

Besides Plotting graphs in Ruby with Gruff, which comes handy for many uses cases, you sometimes might need configuration for more advanced plots, e.g. for academic concerns. Then using Gnuplot Show archive.org snapshot , the first academic open source plotting software, might be a good option.

There are several wrappers for Ruby available and I mainly looked at one of the two most frequently used ones, which are ruby_gnuplot Show archive.org snapshot and numo-gnuplot Show archive.org snapshot .
I will shortly add some guidance on how to get started using either one of these two and which I found the simpler one to use for my own purpose.

Both offer some examples on how to get started:

Both versions are equally good, if you just have to pass some data-arrays, where each array holds the data for x-, y- or z-axis. The major benefit of numo-gnuplot is that it supports advanced numpy like array operations, like multi array indexing, broadcasting and advanced calculations along the specified axis.

How to use using

I personally found the most tricky part getting accustomed with the using syntax Show archive.org snapshot , even though is quite powerful in it's flexibility. Understanding it, is required for several types of plots like histograms or boxplots. It is basically is a way advanced way of controlling the reading of a file by the scanf C-operation for plotting.

In the most simple application plot 'file' using 1:2 just means plot the content of the first column (as x-axis) against the content of the second column (as y-axis).
In more advanced versions you can combine this with logical operations or different functions such as the example from the doc: plot 'file' using 1:($2+$3) '%lf,%lf,%lf', where you reference the n-th column by $n and '%lf,%lf,%lf' specifies the file format (comma separated floating point numbers).

ruby_gnuplot

ruby_gnuplot hides some of that "complexity" by creating it's own Dataset class for that as shown in their readme:

Gnuplot.open do |gp|
  Gnuplot::Plot.new( gp ) do |plot|
    plot.xrange "[-10:10]"
    
    ... # more plot settings
    
    plot.data << Gnuplot::DataSet.new( "sin(x)" ) do |ds|
      ds.with = "lines"
      ds.linewidth = 4
    end
  end
end
  • So this might come handy if you don't bother too much about the internals, but requires a little bit more understanding of what the DataSet class is exactly doing for translating different examples and use cases where you need to plot more than one column of data.
  • Yet on the other hand allows to work more directly with array-like data streams in your script.

numo-gnuplot

numo-gnuplot on the other hand does directly wrap the using syntax, which requires you to write your data to some kind of file format before you can use it for plotting:

Numo.gnuplot do 
   .. # more plot settings
   
  plot "'test.csv'", u: "(hist($#{column_to_plot},width)):(1.0)"
                              s: true,
                              f: true,
                              ... 
  output "hist.jpg"
end

The good news is that you can write any array files into a temporary csv file before passing it Numo.gnuplot:

CSV.open('test.csv', 'w') do |csv|
  random_values.zip(additional_values, absolute_values, other_values).each_with_index do |zipped_data, index|
    csv << [index].append(*zipped_data)
  end
end
Felix Eschey
Last edit
Felix Eschey
License
Source code in this card is licensed under the MIT License.
Posted by Felix Eschey to makandra dev (2023-09-20 23:05)