8000 GitHub - BEAMRobotics/matplotlib-cpp at ef0383f1315d32e0156335e10b82e90b334f6d9f
[go: up one dir, main page]

Skip to content

Extremely simple yet powerful header-only C++ plotting library built on the popular matplotlib

License

Notifications You must be signed in to change notification settings

BEAMRobotics/matplotlib-cpp

Repository files navigation

matplotlib-cpp

Welcome to matplotlib-cpp, possibly the simplest C++ plotting library. It is built to resemble the plotting API used by Matlab and matplotlib.

Usage

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:

Minimal example

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:

Basic example

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:

Modern example

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:

xkcd example

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:

quiver example

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:

surface example

Installation

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 python likes to randomly break compatibility from time to time so some caution is advised when using the bleeding edge.

CMake

The C++ code is compatible to both python2 and python3. However, the CMakeLists.txt file is currently set up to use python3 by default, so if python2 is required this has to be changed manually. (a PR that adds a cmake option for this would be highly welcomed)

NOTE: By design (of python), only a single python interpreter can be created per process. When using this library, no other library that is spawning a python interpreter internally can be used.

To compile the code without using cmake, the compiler invocation should look like this:

g++ example.cpp -I/usr/include/python2.7 -lpython2.7

This can also be used for linking against a custom build of python

g++ example.cpp -I/usr/local/include/fancy-python4 -L/usr/local/lib -lfancy-python4

Vcpkg

You can download and install matplotlib-cpp using the vcpkg dependency manager:

git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
vcpkg install matplotlib-cpp

The matplotlib-cpp port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please create an issue or pull request on the vcpkg repository.

C++11