# GNUPlot

## class to interface GNUPlot from SuperCollider

Inherits from:: Object

This class allows you to use the powerful plotting capabilities of GNUPlot from within SuperCollider.
You need to have GNUPlot installed in order to be able to use this class!

### Creation / Class Methods

*new
  Create a new instance of GNUPlot.
*plot(data)
  Plots the data array with GNUPlot.
  Note, you can call .gnuplot directly on an ArrayedCollection to plot it with this method.

  - Example -

      // plot example
      GNUPlot.plot( [0,2,3,2,1,0.4] );
      // using the Collection extensions you can also directly use gnuplot on the
      array:
      [0,2,3,2,1,0.4].gnuplot;

*plotenv(env)
  Plot an envelope.
  Note, you can call .gnuplot directly on an Env to plot it with this method

    Env.perc.gnuplot;
    Env.perc(0.1, 1.5).gnuplot;
    Env.adsr.gnuplot;

#### Note for Mac users:

GNUPlot can display its plots in various ways - this quark assumes that you want to plot in Aquaterm. If you want to send plots to X11 instead, run code similar to:

    // for mac users who want X:
    GNUPlot.initCode    = GNUPlot.initCode ++ "\n set term x11 \n";
    GNUPlot.gnuplotpath = GNUPlot.pathToXLauncher.quote + "/opt/local/bin/gnuplot";

### Accessing Instance and Class Variables

start
  Start GNUPlot and creates a pipe to it. (called automatically when creating a new instance.)
stop
  Quit GNUPlot and close the pipe. Since GNUPlot is opened in "persist" mode, the window will not disappear, you will have to close it manually.

#### - Basic plotting -

plot(data,ns,label)
  Plots the data, assuming ns rows, and using the label. This method uses a temporary file to pass on the data to GNUPlot.
  data
    The data to plot.
  ns
    Number of rows. Each row will be plotted as a separate graph line.
  label
    Labels to use.

  - Example -

      // create an instance and plot data:
      g = GNUPlot.new;
      g.plot( [0,2,3,2,1,0.4] );

      // plot several sets of data in one figure:
      g.plot( [ [0,2,3,2,1,0.4], [2,1,2,-2,0.4,0.2] ], 2 )
      g.stop

replot(data,ns,label)
  Add data to previous data and plot it.
  data
    New data to be added.
  ns
    Number of rows in the data (default 1)
  label
    Label to use.
plotd(data,ns,label)
  Plots the data, assuming ns rows, and using the label. This method pipes the data directly to GNUPlot, without using a temporary file.
  data
    The data to plot.
  ns
    Number of rows. Each row will be plotted as a separate graph line.
  label
    Labels to use.
setXrange(min,max)
  Sets the x-range for the data. This turns autoscaling off.
autoscaleX
  Turn on autoscaling for the x-axis
setYrange(min,max)
  Sets the y-range for the data. This turns autoscaling off.
autoscaleY
  Turn on autoscaling for the y-axis.

#### - Histogram plotting -

plotdHisto(data,ns,label,verb)
  Plots the data in a histogram, assuming ns rows, and using the label. This method pipes the data directly to GNUPlot, without using a temporary file.
  verb
    Whether or not to use verbosity while creating the histogram.
histoSteps
histoSteps_
  The number of bins to use in the histogram
histoMin
histoMin_
  Minimum bin value for the histogram
histoMax
histoMax_
  Maximum bin value for the histogram

#### - 3D and scatter -

plot3( data, label )
  Creates a 3D plot.

    g = GNUPlot.new;
    g.plot3([[0,0,0], [1,0,0], [1,1,1], [2,1,2], [3,3,2], [4,5,4]], "wiggle");
    g.plot3({  { 1.0.bilinrand  }.dup(3)  }.dup(1000), "hairball");

    // more plot3
    (
    h = GNUPlot.new;
    t = 2*pi*Array.series(1001, 0, 1/1000);
    )

    ( // helix
    var f1 = 10;
    var f2 = 10;
    d = [sin(f1*t), cos(f2*t), t].flop;
    h.plot3(d, \spiral)
    )

    ( // wound wiggle
    var f1 = 2;
    var f2 = 3;
    d = [sin(f1*t), cos(f2*t), t].flop;
    h.plot3(d, 'wiggly spiral')
    )

    ( // damped helix
    var f1 = 10;
    var f2 = 10;
    d = [sin(f1*t)*exp(t.neg), cos(f2*t)*exp(t.neg), t].flop;
    h.plot3(d, \damped)
    )

surf3( data, label, hidden3d, pm3d )
  Creates a 3D surface, where the input data is a 2D grid of 3D points. "hidden3d" (default=true) specifies whether "hidden line removal" is used.

    g = GNUPlot.new;

    g.surf3([[[0,0.5,0], [ 0.5,0,0], [ 1,-0.5,0]],   [[ 0.5,1,0], [ 1,0.5,0], [ 1.5,0,0]], [[ 1,1.5,0.5], [ 1.5,1,0.5], [ 2,0.5,0.5]]], "deckchair", pm3d: false);

    ~xyz = (-10, -9.5 .. 10).collect{|x| (-10, -9.5 .. 10).collect{|y|  [x,y,sin(x+y)] } }
    g.surf3(~xyz, "undulathon", pm3d: true);

scatter( data, label )
  Creates a scatter plot.

    h = GNUPlot.new;
    // scatter wants pairs of values [x,y]

    // some 2d random distributions
    (
    d = {[1.0.sum3rand, exprand(0.001, 1.0)]}.dup(1000);
    h.scatter(d, 'y: exp/x: qgauss')
    )

    (
    d = {{1.0.sum3rand}.dup(2)}.dup(1000);
    h.scatter(d, '2d quasi-gaussian')
    )

    // walking-stick map (see Henon map)
    (
    var gam, del, eps, ab, numit, wsm, res;
    wsm = {|gamma, delta, eps, ab|
    	var anp1, bnp1;
    	#a, b = ab;
    	anp1 = gamma * a * (1 - a) - b;
    	bnp1 = (delta * b - eps) * (1 - (2 * a));
    	[anp1, bnp1]
    };

    gam = 3.8;
    del = 0.4;
    eps = 0.02;
    numit = 1000;
    res = Array.new(numit+1);
    res = res.add([0.8, 0.00001]);
    numit.do {|i|
    	res = res.add(wsm.value(gam, del, eps, res[i]));
    };
    h.scatter(res, \wsm);
    )

#### - Data monitoring -

monitor(updateF,dt,length,ns,skip)
  Creates a monitor for data.
  Note: See also BusMonitor. There is a convenience method for Bus called monitor to monitor a control bus using this method.
  length
    the number of data points to plot
  dt
    time interval between updates
  ns
    the number of rows in the data
  updateF
    update function; this should return the additional data to be plotted.
  skip
    how many updates are in between plots. If skip is 1 then every dt there is a new plot. If skip=10, then every ten updates of the data, it is actually plotted. This allows you to keep the graphical update rate lower than the data update rate.
startMonitor
  Start the monitor (either a regular monitor or histogram monitor)
monitorReset
  Reset the data of the monitor.
stopMonitor
  Stop the monitor
monitorHisto(updateF,dt,length,ns,skip)
  Creates a histogram monitor for data. Arguments as in monitor, but it also observes the histoStep, histoMin and histoMax variables.
  Note: See also BusHistoMonitor. There is a convenience method for Bus called monitorHisto to monitor a control bus using this method.

#### - Direct interaction with GNUPlot -

sendCmd
  Send an arbitrary gnuplot command to the gnuplot session. This should be something gnuplot understands.

    g.sendCmd("set title \"Ooo look at this\"");
    g.sendCmd("replot");

### Monitor example

    g = GNUPlot.new;
    // one channel of random value data, at 0.3 seconds interval
    g.monitor( { 1.0.rand; }, 0.3, 20, 1 );
    g.startMonitor;
    g.stopMonitor;
    // monitor two values in one plot:
    g.monitor( { [1.0.rand, 2.0.rand] }, 0.3, 20, 2 );
    g.startMonitor;
    g.stopMonitor;
    // clean up:
    g.stop;

#### Private class methods and variables

*makeBackupFolder
  Creates the folder for the temporary files. This is called from *initClass.
*envarray(env)
  Converts an envelope into a plottable format for GNUPlot
*folder
*folder_
  Folder for temporary files (default SC_to_GNUPlot in the working directory)

#### Private methods and variables

lastdata
  The last data plotted. Used to add to from replot.
hisdata
  Stored data from the monitor
putCommand(command,tmpname,label)
  Put a plotting command to gnuplot. Do not use directly.
createTempFile(data,ns)
  Creates a temporary file to feed to gnuplot with the data. Is called from plot.

This helpfile was created with the class HelpFile2