July, 2008.
This is a simple interface between my C++ matrix library, newmat, and the gnuplot graph plotting program.
Gnuplot is a freely available program for plotting simple data. It is available for a wide range of platforms and so provides a portable way of adding simple graph plotting facilities to newmat. See http://www.gnuplot.info/.
My approach is to construct a Plot2 object or a Plot3 object and a variety of objects to be added to this plot.
The interfacing method is to write a command file and data files to disk then call up gnuplot to read the files and present the plot.
I don't regard this program as very satisfactory but it does provide an interim solution to the problem of getting reasonably acceptable graphs without too much hassle.
Here are the descriptions of the classes, member functions and global variables in the gnuplot interface. See the file plotdemo.cpp in the library to see examples of their use.
If you are upgrading from a pre-2004 version of my gnuplot interface then please read the section on compiling for changed recommendations.
If you are upgrading from an early version of my gnuplot interface and use a PC, use forward slashes in the specification of the file name when giving a value to the temporary directory. Otherwise you need to use 4 back slashes.
The name of the directory where the data to be plotted and the command file is to be stored is held in the global variable
String TemporaryDirectory;
The main program should start with a statement like (note the direction of the slash)
TemporaryDirectory = "c:/temp";
or, for Unix systems, like
TemporaryDirectory = "temp";
to define this directory. This directory should already exist when the program is run.
LineSeries(const String& title, const Matrix& data, const int colour);
Construct a line plot with (n-1) segments and a given title and colour. The matrix, data, is n x 2 for a two dimensional plot and n x 3 for a 3 dimensional plot. A row beginning with a value 1e50 or greater is used to break a line plot (ie insert a blank line in the file to be read by the Gnuplot program).
ImpulseSeries(const String& title, const Matrix& data, const int colour);
Construct a plot of n vertical lines from the X-axis or X,Y plane to the points stored in the matrix, data. This matrix is n x 2 for a two dimensional plot and n x 3 for a 3 dimensional plot. A row beginning with a value 1e50 or greater is assumed to be missing.
StepSeries(const String& title, const Matrix& data, const int colour);
Construct a plot of n points connected by steps. Available only for two dimensional plots. The matrix, data, is n x 2.
BoxSeries(const String& title, const Matrix& data, const int colour);
Construct a plot of boxes. See Gnuplot documentation.
DotSeries(const String& title, const Matrix& data, const int colour);
Construct a plot of n dots. The matrix, data, is n x 2 for a two dimensional plot and n x 3 for a 3 dimensional plot. The dots tend to be too small to be easily visible.
PointSeries(const String& title, const Matrix& data, const int colour, const int shape);
Construct a plot of n points with the given shape. The matrix, data, is n x 2 for a two dimensional plot and n x 3 for a 3 dimensional plot.
XErrorBarSeries(const String& title, const Matrix& data, const int colour, const int shape)
Construct a plot of n points with the given shape with horizontal error bars. The matrix, data, is n x 3 or n x 4. This class is applicable only to two dimensional plots. If the matrix has 3 columns, the third column gives the distance from the left and right error bars to the points given by the second column. If it has four columns the third and fourth columns give the left and right x coordinates of the ends of the error bars.
YErrorBarSeries(const String& title, const Matrix& data, const int colour, const int shape)
Construct a plot of n points with the given shape with vertical error bars. The matrix, data, is n x 3 or n x 4. This class is applicable only to two dimensional plots. If the matrix has 3 columns, the third column gives the distance from the upper and low error bars to the points given by the second column. If it has four columns the third and fourth columns give the lower and upper y coordinates of the ends of the error bars.
XYErrorBarSeries(const String& title, const Matrix& data, const int colour, const int shape)
Construct a plot of n points with the given shape with both horizontal and vertical error bars. The matrix, data, is n x 4 or n x 6. This class is applicable only to two dimensional plots. If the matrix has 4 columns, the third and fourth columns give the distances from the ends of the horizontal and vertical error bars to the point given by the first and second columns. If it has 6 columns the third and fourth columns give the left and right x coordinates of the horizontal error bar and the fifth and sixth columns give the lower and upper y coordinates of the ends of the vertical error bars.
Line(Real x1, Real y1, Real x2, Real y2);
Line(Real x1, Real y1, Real z1, Real x2, Real y2, Real z2);
Construct a straight line on a graph. The colour corresponds to colour=1. The first version is for two dimensional plots and the second is for three dimensional plots.
Arrow(Real x1, Real y1, Real x2, Real y2);
Arrow(Real x1, Real y1, Real z1, Real x2, Real y2, Real z2);
Construct an arrow on a graph. The head of the arrow is at the second set of coordinates. The colour corresponds to colour=1. The first version is for two dimensional plots and the second is for three dimensional plots.
Label(const String& label, Real x, Real y, Justification j);
Label(const String& label, Real x, Real y, Real z, Justification j);
Construct a label for a graph. The justification gives the alignment on the label with respect to the coordinates. It may take on one of the following 4 values: Label::left, Label::right, Label::centre, Label::center.
Axis(const String& title);
Construct an axis with the given title; use "" for no label.
void Axis::SetLog(bool il = true);
Use a log scale.
void Axis::SetRange(Real min, Real max) ;
Set the range (if not set, the range is calculated from the data).
void Axis::SetZeroAxis(bool za = true) ;
Show the zero axis.
Plot2(const String& title);
Construct a two dimensional plot.
Plot2& Plot2::operator<< (const BaseSeries& bs);
Plot2& Plot2::operator<< (const GraphObject& go);
Add a series or an object (such as a line) to a plot.
void Plot2::AddCommand(const String& command);
Add a Gnuplot command such set set contour to a plot.
void Plot2::PartCommand(const String& command);
Same as AddCommand except that there is no terminating newline. This is used for building up a command from several components.
void Plot2::Set(const String& command);
Same as AddCommand except that the line is prefixed with Set.
void Plot2::AddFunction(const String& function);
Add a function to a plot (as opposed to plotting data).
void Plot2::Set_X_Axis(const Axis& xa);
void Plot2::Set_Y_Axis(const Axis& ya);
Add axes to a plot
void Plot2::WantKey(bool wk = true);
void Plot2::WantKey(double ks, bool wk = true);
Include a key in the plot; ks rescales the vertical spacing of the key.
void Plot2::DoPlot();
Actually plot the plot.
The following functions are the same as or analogous to the corresponding functions in Plot2 and are used for a three dimensional (or surface) plot:
Plot3(const String& title);
Plot3& Plot3::operator<< (const BaseSeries& bs);
Plot3& Plot3::operator<< (const GraphObject& go);
void Plot3::AddCommand(const String& command);
void Plot3::PartCommand(const String& command);
void Plot3::Set(const String& command);
void Plot3::AddFunction(const String& function);
void Plot3::Set_X_Axis(const Axis& xa);
void Plot3::Set_Y_Axis(const Axis& ya);
void Plot3::Set_Z_Axis(const Axis& za);
void Plot3::WantKey(bool wk = true) ;
void Plot3::WantKey(double ks, bool wk = true);
void Plot3::DoPlot();
Plot3 sets parametric by default. If you are plotting a function with AddFunction you should include a command
plot3.Set("noparametric");
where plot3 is the name of the Plot3 object.
Use a MultiPlot object to put several plots on one page. Build the plots with Plot2 and load them into a MultiPlot object with <<. Not all GnuPlot functions work correctly with MultiPlot. I have been unable to rescale the font sizes so they tend to be too large. In Windows you can reduce the font sizes using the menu on the graph window. To reduce the space used by the axes, I suggest you don't label the axes.
MultiPlot;Construct a MultiPlot object - no title.
MultiPlot(const String& title);Construct a MultiPlot object. (Works under version 4.2).
void MultiPlot::Size(Real x, Real y);Set the size of the graph (x=1, y=1 for a graph filling the whole page).
void MultiPlot::Origin(Real x, Real y);Set the location of the bottom left corner of the graph (x=0, y=0 for the lower left corner, x=1, y=1 corresponds to the top right corner).
void MultiPlot::PointSize(Real ps);Change the scale of the points in a graph.
MultiPlot& MultiPlot::operator<< (const Plot2& plot);MultiPlot& MultiPlot::operator<< (const Plot3& plot);Load a plot into a MultiPlot object, with the scaling and location set by the Size and Origin commands.
void MultiPlot::DoPlot();Actually plot the plot.
I have tested this program with Borland 5.6,5.8, Microsoft 6,7,8 Intel 10 and OpenWatcom 1.7a (all under 32 bit console mode) under Windows XP and Gnu C++ 4 and Intel 10 under Linux.
Make files for compiling the demonstration program plotdemo with these compilers are included in this package. This make file assumes you are using a recent version of newmat11. Other make files can be generated with my genmake utility.
You need to include newmat and my string library (including the string functions) in your project.
This program recognises the namespace option in include.h. The gnuplot classes and functions are put in namespace RBD_LIBRARIES (doesn't work with Open Watcom).
Several files need editing according to the operating system and the version of gnuplot you are using.
The selections in the distribution are suitable for Windows. If you activate the line (by removing the characters // at the beginning of the line)
//#define set_unix_options // set if running UNIX or LINUX
the options will be suitable for Linux. But note the need for temporary directories as noted below.
callplot.cpp: There are 8 options under the heading CALLING METHOD. Activate the appropriate statement.
On a PC running Windows 9X, NT, 2000, XP, etc. I suggest using SPAWNLP32 with gnuplot 3.xx and SPAWNLP with gnuplot 4.xx. SPAWNLP32 will use wgnupl32.exe rather wgnuplot.exe and I recommend this option with version 3. With version 4 wgnuplot.exe is the 32 bit version so you need SPAWNLP.
gnuplot.cpp: Don't change the option under the heading FILE SEPARATOR.
Under the option EXIT OPTION choose DASH if you are running gnuplot 3.71 or later on a PC. Otherwise use PAUSE_M1 on a PC.
plotdemo.cpp: Set the TemporaryDirectory to something appropriate for your system. Make sure you use a forward slash in the file name under Windows (or 4 back slashes).
If you want to save up the plots until your program has completed and then display them, don't select any options in callplot.cpp and select HOLD in gnuplot.cpp. When your program has finished, go to the temporary directory and run gnuplot with the .gp file that has been generated as an argument. You can set the file name of the file that will hold the gnuplot commands by setting the global variable CommandFile to the desired name in your main program. You need this option if you are using MSDOS.
I haven't found an entirely satisfactory approach with Linux with version 4 of gnuplot.
callplot.cpp: I suggest using the FORK_PERSIST option. Under gnuplot 4 the mouse doesn't work correctly with this option. I hope this will be fixed in a later version of gnuplot and so haven't tried very hard to find a workaround. You may prefer to use the FORK option.
gnuplot.cpp: If you are using the FORK_PERSIST option in callplot.cpp try PAUSE3600 here. If this starts using 100% CPU time try SKIP instead.
You might need to activate the statement fout << "set nomultiplot" << endl; in MultiPlot::DoPlot().
plotdemo.cpp: Set the TemporaryDirectory to something appropriate for your system. I tend to make a subdirectory temp and so put TemporaryDirectory = "temp".
On Windows systems you want either wgnupl32.exe or wgnuplot.dll and wgnuplot.exe for version 3 or wgnuplot.exe for version 4 (download from http://www.gnuplot.info/ as gp371w32.zip or gp371w16.zip or gp400win32.zip) in your path.
If you are using the CREATEPROCESS option rather than the SPAWNLP option the gnuplot file needs to be in the current directory.
If you are using the 16 bit version of gnuplot under Windows 95 or Windows 3.1 do not try to have two graphs present at the same time.
To print the graph or copy it to the clipboard click the top left corner of the graph and select options. For pasting into other applications you may want to paste from the clipboard using paste special and the device independent bitmap format.
On Unix systems gnuplot needs to be available on your system.
The gnuplot interface does not clean up the files in the temporary directory, so every so often you might want to delete these.
The program files include comments in a format suitable for interpretation by the Doxygen documentation system. I suggest you set Doxygen options
gnuplot.h | header file for gnuplot interface program |
gnuplot.cpp | bodies for gnuplot interface program |
callplot.h | header for calling gnuplot |
callplot.cpp | bodies for calling gnuplot |
plotdemo.cpp | demonstration program |
gp_b55.mak | make file for Borland 5.5 |
gp_b56.mak | make file for Borland 5.6 |
gp_b58.mak | make file for Borland 5.8 |
gp_m6.mak | make file for Visual C++ 6, 7, 7.1 |
gp_m8.mak | make file for Visual C++ 8 |
gp_i8.mak | make file for Intel C++ 8, 9 under Windows |
gp_i10.mak | make file for Intel C++ 10 under Windows |
gp_ow.mak | make file for Open Watcom C++ |
gp_gnu.mak | make program for Gnu C++ |
gp_il8.mak | make file for Intel C++ 8, 9, 10 under Linux |
gp_targ.txt | target file used by genmake for generating make files |
gnuplot.htm | this file |
rbd.css | style sheet for gnuplot.htm |
_gnuplot.dox | description file for doxygen |
Go to the download page page to download the package.
July, 2008 - minor updates
April, 2006 - update for G++ 4.1
September, 2005 - update for gnuplot 4, other fixes and extensions, namespace options, doxygen comments.
January, 2002 - multiple graphs on one page
July, 2001 - compatibility upgrade for my other libraries and gnuplot 3.71.
August, 1998 - minor fix
January, 1998 - first release as separate package
October, 1995 - developed as part of Points point process simulation package