Welcome to matplotlib-cpp, possibly the simplest C++ plotting library. It is built to resemble the plotting API used by Matlab and matplotlib.
Complete minimal example:
#include "matplotlibcpp.h"
namespace plt = matplotlibcpp;
int main() {
plt::plot({1,3,2,4});
plt::show();
}
g++ minimal.cpp -std=c++11 -I/usr/include/python2.7 -lpython2.7
Result:
A more comprehensive example:
#include "matplotlibcpp.h"
#include <cmath>
namespace plt = matplotlibcpp;
int main()
{
// Prepare data.
int n = 5000;
std::vector<double> x(n), y(n), z(n), w(n,2);
for(int i=0; i<n; ++i) {
x.at(i) = i*i;
y.at(i) = sin(2*M_PI*i/360.0);
z.at(i) = log(i);
}
// Set the size of output image to 1200x780 pixels
plt::figure_size(1200, 780);
// Plot line from given x and y data. Color is selected automatically.
plt::plot(x, y);
// Plot a red dashed line from given x and y data.
plt::plot(x, w,"r--");
// Plot a line whose name will show up as "log(x)" in the legend.
plt::named_plot("log(x)", x, z);
// Set x-axis to interval [0,1000000]
plt::xlim(0, 1000*1000);
// Add graph title
plt::title("Sample figure");
// Enable legend.
plt::legend();
// Save the image (file format is determined by the extension)
plt::save("./basic.png");
}
g++ basic.cpp -I/usr/include/python2.7 -lpython2.7
Result:
Alternatively, matplotlib-cpp also supports some C++11-powered syntactic sugar:
#include <cmath>
#include "matplotlibcpp.h"
using namespace std;
namespace plt = matplotlibcpp;
int main()
{
// Prepare data.
int n = 5000; // number of data points
vector<double> x(n),y(n);
for(int i=0; i<n; ++i) {
double t = 2*M_PI*i/n;
x.at(i) = 16*sin(t)*sin(t)*sin(t);
y.at(i) = 13*cos(t) - 5*cos(2*t) - 2*cos(3*t) - cos(4*t);
}
// plot() takes an arbitrary number of (x,y,format)-triples.
// x must be iterable (that is, anything providing begin(x) and end(x)),
// y must either be callable (providing operator() const) or iterable.
plt::plot(x, y, "r-", x, [](double d) { return 12.5+abs(sin(d)); }, "k-");
// show plots
plt::show();
}
g++ modern.cpp -std=c++11 -I/usr/include/python2.7 -lpython
Result:
Or some funny-looking xkcd-styled example:
#include "matplotlibcpp.h"
#include <vector>
#include <cmath>
namespace plt = matplotlibcpp;
int main() {
std::vector<double> t(1000);
std::vector<double> x(t.size());
for(size_t i = 0; i < t.size(); i++) {
t[i] = i / 100.0;
x[i] = sin(2.0 * M_PI * 1.0 * t[i]);
}
plt::xkcd();
plt::plot(t, x);
plt::title("AN ORDINARY SIN WAVE");
plt::save("xkcd.png");
}
g++ xkcd.cpp -std=c++11 -I/usr/include/python2.7 -lpython2.7
Result:
When working with vector fields, you might be interested in quiver plots:
#include "../matplotlibcpp.h"
namespace plt = matplotlibcpp;
int main()
{
// u and v are respectively the x and y components of the arrows we're plotting
std::vector<int> x, y, u, v;
for (int i = -5; i <= 5; i++) {
for (int j = -5; j <= 5; j++) {
x.push_back(i);
u.push_back(-i);
y.push_back(j);
v.push_back(-j);
}
}
plt::quiver(x, y, u, v);
plt::show();
}
g++ quiver.cpp -std=c++11 -I/usr/include/python2.7 -lpython2.7
Result:
When working with 3d functions, you might be interested in 3d plots:
#include "../matplotlibcpp.h"
namespace plt = matplotlibcpp;
int main()
{
std::vector<std::vector<double>> x, y, z;
for (double i = -5; i <= 5; i += 0.25) {
std::vector<double> x_row, y_row, z_row;
for (double j = -5; j <= 5; j += 0.25) {
x_row.push_back(i);
y_row.push_back(j);
z_row.push_back(::std::sin(::std::hypot(i, j)));
}
x.push_back(x_row);
y.push_back(y_row);
z.push_back(z_row);
}
plt::plot_surface(x, y, z);
plt::show();
}
Result:
matplotlib-cpp works by wrapping the popular python plotting library matplotlib. (matplotlib.org) This means you have to have a working python installation, including development headers. On Ubuntu:
sudo apt-get install python-matplotlib python-numpy python2.7-dev
If, for some reason, you're unable to get a working installation of numpy on your system,
you can define the macro WITHOUT_NUMPY
before including the header file to erase this
dependency.
The C++-part of the library consists of the single header file matplotlibcpp.h
which can be placed
anywhere.
Since a python interpreter is opened internally, it is necessary to link against libpython
in order
to user matplotlib-cpp. Most versions should work, although libpython2.7
and libpython3.6
are
probably the most regularly testedr.
If you prefer to use CMake as build system, you will want to add something like this to your CMakeLists.txt:
Recommended way (since CMake 3.12):
It's easy to use cmake official docs to find Python 2(or 3) interpreter, compiler and development environment (include directories and libraries).
NumPy is optional here, delete it from cmake script, if you don't need it.
find_package(Python2 COMPONENTS Development NumPy)
target_include_directories(myproject PRIVATE ${Python2_INCLUDE_DIRS} ${Python2_NumPy_INCLUDE_DIRS})
target_link_libraries(myproject Python2::Python Python2::NumPy)