Giter VIP home page Giter VIP logo

matplotlib-cpp's Introduction

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::plot(x, z, {{"label", "log(x)"}});
    // 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

Also, matplotlib-cpp also supports being given multiple plot commands. However these have to come in triplets of (x, y, fmt) where fmt is a formatting string, such as r--.

#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), z(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);
        z.at(i) = 12.5 + abs(sin(x.at(i)));
    }

    // 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, z, "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

Eigen support and generic vectors

This fork of the library supports working not only with std::vectors, but with all classes providing the same member functions as std::vector. In particular it is suited to be used with the C++ template library Eigen.

The generalisation is currently a working process. Following functions already support generic vectors:

  • plot
  • loglog
  • semilogx and semilogy

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 add the define WITHOUT_NUMPY 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 libpython2.7 in order to use matplotlib-cpp.

CMake

If you prefer to use CMake as build system, you will want to add something like this to your CMakeLists.txt:

find_package(PythonLibs 2.7)
target_include_directories(myproject PRIVATE ${PYTHON_INCLUDE_DIRS})
target_link_libraries(myproject ${PYTHON_LIBRARIES})

C++11

Currently, c++11 is required to build matplotlib-cpp. The last working commit that did not have this requirement was 717e98e752260245407c5329846f5d62605eff08.

Note that support for c++98 was dropped more or less accidentally, so if you have to work with an ancient compiler and still want to enjoy the latest additional features, I'd probably merge a PR that restores support.

Python 3

This library supports both python2 and python3 (although the python3 support is probably far less tested, so it is recommended to prefer python2.7). To switch the used python version, simply change the compiler flags accordingly.

g++ example.cpp -I/usr/include/python3.6 -lpython3.6

The same technique can 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

Why?

I initially started this library during my diploma thesis. The usual approach of writing data from the c++ algorithm to a file and afterwards parsing and plotting it in python using matplotlib proved insufficient: Keeping the algorithm and plotting code in sync requires a lot of effort when the C++ code frequently and substantially changes. Additionally, the python yaml parser was not able to cope with files that exceed a few hundred megabytes in size.

Therefore, I was looking for a C++ plotting library that was extremely easy to use and to add into an existing codebase, preferably header-only. When I found none, I decided to write one myself, which is basically a C++ wrapper around matplotlib. As you can see from the above examples, plotting data and saving it to an image file can be done as few as two lines of code.

The general approach of providing a simple C++ API for utilizing python code was later generalized and extracted into a separate, more powerful library in another project of mine, wrappy.

Todo/Issues/Wishlist

  • This library is not thread safe. Protect all concurrent access with a mutex. Sadly, this is not easy to fix since it is not caused by the library itself but by the python interpreter, which is itself not thread-safe.

  • It would be nice to have a more object-oriented design with a Plot class which would allow multiple independent plots per program.

  • Right now, only a small subset of matplotlibs functionality is exposed. Stuff like xlabel()/ylabel() etc. should be easy to add.

  • If you use Anaconda on Windows, you might need to set PYTHONHOME to Anaconda home directory and QT_QPA_PLATFORM_PLUGIN_PATH to %PYTHONHOME%Library/plugins/platforms. The latter is for especially when you get the error which says 'This application failed to start because it could not find or load the Qt platform plugin "windows" in "".'

matplotlib-cpp's People

Contributors

cryoris avatar lava avatar alexdewar avatar atsushisakai avatar chachay avatar charasyn avatar mandarancio avatar liuweijunantihos avatar yuma-m avatar torfinnberset avatar tustvold avatar kartikmohta avatar raldridge11 avatar quangtung97 avatar paralax avatar adiba avatar flyvbee avatar williamrob104 avatar valeriomagnago avatar tomix1024 avatar pauljurczak avatar patrikfors avatar okermorgant avatar mdmosley1 avatar kexianshen avatar biphasic avatar christost avatar austinschuh avatar amintahmasbi avatar alessandro-gentilini avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.