A header-only C++ interface to Gnuplot. See this video for a demo (running Visual Studio under Windows 10).
This repository contains the file gplot++.h, which provides a way for C++ programs to connect to a Gnuplot instance to produce plots. To use this library, you must first install Gnuplot on your system!
A few features of this library are the following:
- Header-only library: very easy to install
- Plot
std::vector
variables - Multiple series in the same plot
- Multiple plots (via
Gnuplot::multiplot
) - Logarithmic axes (via
Gnuplot::set_logscale
) - Histograms (via
Gnuplot::histogram
) - Custom ranges (via
Gnuplot::set_xrange
andGnuplot::set_yrange
) - Possibility to save the plots in PNG and PDF files
- 3D plots (new in 0.2.0)
- gplot++
- Table of Contents
Created by gh-md-toc
Of course, before using gplot++.h
you must have Gnuplot installed and available in the PATH
! We provide here instructions about how to install Gnuplot under Windows, Mac OS X, and Linux.
Windows users, beware that the standard installation won't work with gplot++.h
because you need to activate a flag during the installation!
Download the Gnuplot installer from the SourceForge website. Be sure not to download the .tar.gz
file; instead, you should download the file ending with .exe
, e.g., gp542-win64-mingw.exe.
When you run the installer, pay attention to the option Add application directory to your PATH environment variable while installing Gnuplot, otherwise gplot++.h
will fail to generate the plots! See this video for help.
Linux users should use their package manager to install Gnuplot:
# Debian, Ubuntu, Linux Mint
sudo apt-get install gnuplot
# Arch, Manjaro
sudo pacman -Syu gnuplot
# Fedora
sudo dns install gnuplot
The preferred way to install Gnuplot is using Homebrew from the terminal:
brew install gnuplot
Once you have Gnuplot installed, download the file gplot++.h and save it in the same folder as your program. That's all.
This video shows how to include gplot++.h in a C++ project created using Visual Studio 2019 (Windows).
Here is the output of one of the examples:
The source code of the example is in file example-complex.cpp
:
#include "gplot++.h"
int main(void) {
Gnuplot plt{};
std::vector<double> x{1, 2, 3, 4, 5}, y{5, 2, 4, 1, 3};
// Save the plot into a PNG file with the desired size (in pixels)
plt.redirect_to_png("complex.png", "800,600");
/* Create two plots with the following layout (2 rows, 1 column):
*
* +------------------------+
* | |
* | Plot #1 |
* | |
* +------------------------+
* | |
* | Plot #2 |
* | |
* +------------------------+
*/
plt.multiplot(2, 1, "Title");
// Plot #1
plt.set_title("Plot #1");
plt.set_xlabel("X axis");
plt.set_ylabel("Y axis");
plt.plot(x, y, "x-y plot");
plt.plot(y, x, "y-x plot", Gnuplot::LineStyle::LINESPOINTS);
plt.show(); // Always call "show"!
// Plot #2
plt.set_title("Plot #2");
plt.set_xlabel("Value");
plt.set_ylabel("Number of counts");
plt.histogram(y, 2, "Histogram");
plt.set_xrange(-1, 7);
plt.set_yrange(0, 5);
plt.show(); // Always call "show"!
}
The only symbol exported by file gplot++.h
is the Gnuplot
class. When you instance an object of this class, it will silently start gnuplot
in the background and open a pipe through it:
#include "gplot++.h"
int main() {
Gnuplot plt{};
// ...
}
If Gnuplot is not available in your PATH
(probably this is most common on Windows system), you can specify the full path to the executable:
#include "gplot++.h"
int main() {
Gnuplot plt{R"(C:\Program Files\Gnuplot\gnuplot.exe)"};
// ...
}
The connection will be automatically closed once the variable plt
goes out of scope; by default, the Gnuplot window will be left open. In this way, you can navigate through the Gnuplot window even after your C++ has completed its execution.
There are two ways to produce a plot; both require you to call the Gnuplot::plot
method:
- Pass one
std::vector
variable, which will be used to set they
coordinates of the points; - Pass two
std::vector
variables; these will be used to set the(x, y)
coordinates of the points.
You can call plot
multiple times, and each time your call will be recorded in a list. When you are ready to produce a plot, call Gnuplot::show
, like in the following example:
several ways to produce a plot. Each of them requires you to pass the data to plot through one or more std::vector
variables:
std::vector<int> x{1, 2, 4}; // No problem to use a vector of ints
std::vector<double> y1{3.1, -4.6, 5.1};
std::vector<double> y2{1.3, 1.6, 4.1};
Gnuplot plt{};
// Just pass the set of y values
plt.plot(y1);
// You can provide a label and a linestyle
plt.plot(x, y2, "Dataset #1", Gnuplot::LineStyle::LINESPOINTS);
// Now produce the plot
plt.show();
New in version 0.7.0: Instead of providing the two vectors, you can call Gnuplot::add_point()
repeatedly and then call Gnuplot::plot()
without specifying vectors. See the example program example-addpoint.cpp.
Gplot++ implements the method Gnuplot::histogram
, which computes the histogram of a series and plot it using Gnuplot. Here is an example (example-histogram.cpp
):
#include "gplot++.h"
int main(void) {
Gnuplot gnuplot{};
std::vector<double> y{5, 2, 4, 1, 3};
gnuplot.histogram(y, 2, "Histogram");
gnuplot.set_xlabel("Value");
gnuplot.set_ylabel("Number of counts");
gnuplot.set_xrange(1, 5);
gnuplot.set_yrange(0, 5);
gnuplot.show();
}
The parameters to Gnuplot::histogram
are the following:
-
A vector containing the values to use in the plot;
-
The number of bins to plot (two bins in the example above);
-
A label for the plot (optional, default is empty)
-
The line style (optional, default is
Gnuplot::LineStyle::BOXES
)
There are several line styles:
-
Gnuplot::LineStyle::DOTS
(only use this when you have many points); -
Gnuplot::LineStyle::LINES
(the default); -
Gnuplot::LineStyle::POINTS
; -
Gnuplot::LineStyle::LINESPOINTS
; -
Gnuplot::LineStyle::STEPS
; -
Gnuplot::LineStyle::BOXES
(only used for histograms). -
Gnuplot::LineStyle::VECTORS
(only used for 2D and 3D vector fields).
You can manually assign a range to the X and Y axes using the methods Gnuplot::set_xlabel
and Gnuplot::set_ylabel
:
Gnuplot plt{};
plt.set_xrange(1.5, 3.5);
plt.set_yrange(); // No parameters means automatic axes
If you are creating multiple plots (see below), you should probably reset the x and y ranges after each call to Gnuplot::show
.
You can also provide a label for both axes:
plt.set_xlabel("Time [s]");
plt.set_ylabel("Speed [cm/s]");
To set a logarithmic scale, use Gnuplot::set_logscale
:
Gnuplot plt{};
plt.set_logscale(Gnuplot::AxisScale::LOGXY);
Possible parameters are:
Gnuplot::AxisScale::LINEAR
(the default);Gnuplot::AxisScale::LOGX
;Gnuplot::AxisScale::LOGY
;Gnuplot::AxisScale::LOGXY
.
You can make several plots within the same window using the method Gnuplot::multiplot
. It accepts the following parameters:
-
The number of rows to use;
-
The number of columns to use;
-
A title (optional, default is no title).
You must paint the several plot in order, and each time you complete one plot you must call Gnuplot::show
.
Starting from version 0.3.1, gplot++.h
supports plots with error bars through these functions:
Gnuplot::plot_xerr(x, y, xerr, label = "");
Gnuplot::plot_yerr(x, y, yerr, label = "");
Gnuplot::plot_xyerr(x, y, xerr, yerr, label = "");
Here is an example (example-errorbars.cpp):
#include "gplot++.h"
int main(void) {
Gnuplot plt{};
std::vector<double> x{1, 2, 3, 4, 5}, y{5, 2, 4, 1, 3};
std::vector<double> xerr{0.2, 0.2, 0.1, 0.1, 0.2},
yerr{0.3, 0.4, 0.2, 0.6, 0.7};
/* Create four plots with the following layout (2 rows, 2 columns):
*
* +------------------------+------------------------+
* | | |
* | Plot #1 | Plot #2 |
* | | |
* +------------------------+------------------------+
* | | |
* | Plot #3 | Plot #4 |
* | | |
* +------------------------+------------------------+
*/
plt.multiplot(2, 2, "Title");
// Plot #1
plt.set_xlabel("X axis");
plt.set_ylabel("Y axis");
plt.plot(x, y, "", Gnuplot::LineStyle::POINTS);
plt.show(); // Always call "show"!
// Plot #2: X error bar
plt.set_xlabel("X axis");
plt.set_ylabel("Y axis");
plt.plot_xerr(x, y, xerr);
plt.show(); // Always call "show"!
// Plot #3: Y error bar
plt.set_xlabel("X axis");
plt.set_ylabel("Y axis");
plt.plot_yerr(x, y, yerr);
plt.show(); // Always call "show"!
// Plot #4: X and Y error bars
plt.set_xlabel("X axis");
plt.set_ylabel("Y axis");
plt.plot_xyerr(x, y, xerr, yerr);
plt.show(); // Always call "show"!
}
You can create 3D plots using the command plot3d
, which takes three vectors. See the file example-3d.cpp
:
#include "gplot++.h"
#include <cmath>
#include <iostream>
int main(void) {
Gnuplot gnuplot{};
std::vector<double> x, y, z;
for (double angle = 0; angle < 6 * M_PI; angle += 0.1) {
x.push_back(cos(angle));
y.push_back(sin(angle));
z.push_back(angle / 2 * M_PI);
}
gnuplot.plot3d(x, y, z);
gnuplot.show();
}
Here is the result:
Starting from version 0.4.0, gplot++ supports vector field plots, both in 2D and 3D, through the methods Gnuplot::plot_vectors
and Gnuplot::plot_vectors3d
:
#include "gplot++.h"
#include <cmath>
#include <vector>
using namespace std;
int main(void) {
Gnuplot gnuplot{};
vector<double> x{}, y{};
vector<double> vx{}, vy{};
// Sample a regular grid. Use a small tilt to avoid sampling
// the grid at the origin
for (double cur_x{-10.1}; cur_x <= 10; cur_x += 1) {
for (double cur_y{-10.1}; cur_y <= 10; cur_y += 1) {
x.push_back(cur_x);
y.push_back(cur_y);
double r{sqrt(pow(cur_x, 2) + pow(cur_y, 2))};
double cur_vx{-cur_x / r};
double cur_vy{-cur_y / r};
vx.push_back(cur_vx);
vy.push_back(cur_vy);
}
}
gnuplot.plot_vectors(x, y, vx, vy);
gnuplot.show();
}
It is often useful to save the plot into a file, instead of opening a window. You can save plots in PNG format if you call the method Gnuplot::redirect_to_png
:
Gnuplot plt{};
// Call this immediately after you constructed the object "plt"
plt.redirect_to_png("image.png", "800,600");
The first parameter is the name of the image file to create, and the second is a string specifying the size of the image, in the format width,height
(in pixels). If you avoid passing the second parameter, a sensible default will be used:
Gnuplot plt{};
// Use the default size
plt.redirect_to_png("image.png");
You can save the plot in a PDF file, which should be the preferred format if you plan to include the plot in a LaTeX document:
Gnuplot plt{};
// Call this immediately after you constructed the object "plt"
plt.redirect_to_pdf("image.pdf", "20cm,15cm");
Unlike Gnuplot::redirect_to_png
, when you create a PDF file you can use several measure units to specify the size of the image. In this case too, you can avoid passing the second parameter, and a reasonable default will be used.
You can save the plot in a SVG file via the method Gnuplot::redirect_to_svg
. In this case, the SVG file will be interactive when opened in a web browser.
Finally, you can use Gnuplot::redirect_to_dumb
to send the plot to the terminal or to a text file. You can pass a Gnuplot::TerminalMode
value to specify if you want to include ANSI escape codes to produce colors, as shown in example-dumb.cpp
:
You can pass commands to Gnuplot using the method Gnuplot::sendcommand
:
Gnuplot plt{};
plt.sendcommand("set xlabel 'X axis'");
plt.sendcommand("plot sin(x)");
There are several other libraries like gplot++ around. These are the ones I referenced while developing my own's:
- gnuplot-iostream: it has much more features than gplot++, but it is slightly more difficult to install and use.
- gnuplot-cpp: another header-only library. It lacks support for high-level stuff like
std::vector
plotting.
- Add
Gnuplot::add_point
,Gnuplot::get_num_of_points()
,Gnuplot::get_points_x()
, andGnuplot::get_points_y()
, as well as a new overloaded methodGnuplot::plot()
which does not require the vectors ofx
andy
.
- Add
Gnuplot::set_title
-
Add
redirect_to_dumb
and theTerminalType
enum class to support thedumb
terminal -
Use a smarter algorithm to specify ranges in
Gnuplot.set_xrange
andGnuplot.set_yrange
: now specifying one of the two extrema asNAN
does not override the specification of the other.
-
Gnuplot::redirect_to_svg
has been added -
Gnuplot::plot_vectors
,Gnuplot::plot_vectors3d
have been added
Gnuplot::plot_xerr
,Gnuplot::plot_yerr
, andGnuplot::plot_xyerr
have been added
- The library is now supported under Windows
- Ensure that commands sent to Gnuplot are executed immediately (#1)
-
New constants
GNUPLOTPP_VERSION
,GNUPLOTPP_MAJOR_VERSION
,GNUPLOTPP_MINOR_VERSION
, andGNUPLOTPP_PATCH_VERSION
-
3D plots (after a suggestion by William Luciani)
- First release