Gnuplot-iostream interface

This interface allows gnuplot to be controlled from C++ and is designed to be the lowest hanging fruit. In other words, if you know how gnuplot works it should only take 30 seconds to learn this library. Basically it is just an iostream pipe to gnuplot with some extra functions for pushing data arrays and getting mouse clicks. Data sources include STL containers (eg. vector or map) and one or two dimensional Blitz++ arrays (of scalars or TinyVectors). Support for other data sources should be easy to add.

Basically there are two functions defined: send() sends arrays of data values (it is overloaded to do the right thing based upon what type of variable you pass) and getMouse() gets the position of a mouse click. Everything else is accomplished by sending commands manually to gnuplot via the iostream interface. This is in my opinion the easiest way to do it if you are already comfortable with using gnuplot. If you would like a more abstract interface check out the gnuplot-cpp library.

To retrieve the source code from GIT:

git clone git://gitorious.org/gnuplot-iostream/gnuplot-iostream.git

Synopsis

#include <map>
#include <vector>

#include <math.h>

//#define GNUPLOT_ENABLE_BLITZ
#include "gnuplot-iostream.h"

int main() {
	Gnuplot gp;
	// For debugging or manual editing of commands:
	//Gnuplot gp("cat > plot.gp");
	// or
	//Gnuplot gp("tee plot.gp | gnuplot");

	gp << "set terminal png\n";

	std::vector<double> y_pts;
	for(int i=0; i<1000; i++) {
		double y = (i/500.0-1) * (i/500.0-1);
		y_pts.push_back(y);
	}

	gp << "set output 'my_graph_1.png'\n";
	gp << "p '-' w l, sin(x/200) w l\n";
	gp.send(y_pts);
	// Or this:
	//gp.send(y_pts.begin(), y_pts.end());

	// NOTE: we can use map here because the X values are intended to be
	// sorted.  If this was not the case, vector<pair<double,double>> could be
	// used instead.

	std::map<double, double> xy_pts_A;
	for(double x=-2; x<2; x+=0.01) {
		double y = x*x*x;
		xy_pts_A[x] = y;
	}

	std::map<double, double> xy_pts_B;
	for(double alpha=0; alpha<1; alpha+=1.0/24.0) {
		double theta = alpha*2.0*3.14159;
		xy_pts_B[cos(theta)] = sin(theta);
	}

	gp << "set output 'my_graph_2.png'\n";
	gp << "set xrange [-2:2]\nset yrange [-2:2]\n";
	gp << "p '-' w l t 'cubic', '-' w p t 'circle'\n";
	gp.send(xy_pts_A).send(xy_pts_B);
	// Or this:
	//gp.send(xy_pts_A.begin(), xy_pts_A.end());
	//gp.send(xy_pts_B.begin(), xy_pts_B.end());

#ifdef GNUPLOT_ENABLE_BLITZ
	gp << "set output 'my_graph_3.png'\n";
	gp << "set auto x\n";
	gp << "set auto y\n";
	blitz::Array<double, 1> y_arr(100);
	blitz::Array<blitz::TinyVector<double, 2>, 1> xy_arr(100);
	blitz::firstIndex bi;
	y_arr = cos(bi * 0.1);
	xy_arr[0] = cos(bi * 0.1) * 100;
	xy_arr[1] = sin(bi * 0.1);
	gp << "p '-' w l, '-' w l\n";
	gp.send(y_arr);
	gp.send(xy_arr);
#endif // GNUPLOT_ENABLE_BLITZ

	// If this was an interactive session (i.e. not a png terminal),
	// this would get a mouse press:
	//double mx, my;
	//int mb;
	//gp.getMouse(mx, my, mb);
	//printf("You pressed mouse button %d at x=%f y=%f\n", mb, mx, my);
}

<-- Back