commit | ab802d5f2319768f8250c1a8819e327e2f9f2843 | [log] [tgz] |
---|---|---|
author | Austin Schuh <austin.linux@gmail.com> | Fri Jul 03 18:11:11 2020 -0700 |
committer | Austin Schuh <austin.linux@gmail.com> | Fri Jul 03 18:11:11 2020 -0700 |
tree | 38ac382df21faee995cee227318bfd03a54c6750 | |
parent | 6c8ec4c167846dd8766f2d3fbccb7cd0da4e22f4 [diff] |
Squashed 'third_party/matplotlib-cpp/' changes from f994996e0..7d0e69540 7d0e69540 include ldflags instead of libs b79ca6dc6 feat: Add keyword argument support to legend() 374dcd032 Added arrow, cla, margins, contour 107912124 a few of the parameters are floats. This is a quick hack to get a couple of them to work. In the future matplotlibcpp should use map<string,any> instead of map<string,string> for kwargs. That should be a separate PR 480af0f4f Added support for axvspan 60dcd64c8 Sprinkle calls to interpreter::get() all over the codebase d612b524e Fix python3.8 segfault for the named_* family of functions f5f8ce3d6 Move Python.h include into first position bf2be7108 Update python-config invocation in Makefile ecf3a8dd0 Add native numpy handling when plotting vectors of (unsigned) long long d74105036 Fix use-after-free bug when plotting unknown numeric types edb407461 Reword libpython dependency; move vcpkg section 1243814da Add vcpkg installation instructions 9595628a8 Replace occurrences of std::unordered_map<> with std::map<> 823de00fb :wrench: Moved all elements related to docker build in contrib a7c38ad72 :pencil: Typo update in Readme.md fa673c670 :sparkle: Added a first CI file 7ef255923 :sparkle: Added a target to build docker image d7839cc47 :sparkle: Added a first version of Dockerfile e5ffc6ce8 ensure interpreter is initialized for suptitle & subplot 2843ebbe6 delete unnecessary "inline" on get_array(vector<string>) ea527fdce add "inline" to get_array, color_bar, axvline 7f7b8528b Fix numpy detection and provide some functions even when numpy is not available 41477fcdb Add experimental documentation target 811ebfb2c Add 3D line plot and zlabel function. 9b23ca06b Adds vim tempfiles to gitignore 52816e2f8 Adds boxplot, get_strarray and get_listlist 1809d7a26 Adds axvline to function scope d283d47d0 Remove indentation around 'imshow()' functions de33a5745 Rename make variable CXXFLAGS -> EXTRA_FLAGS f1af639c4 implement colorbar; requires returned PyObject of mappable object f23347fca Added information about backend renderer issue on MacOS 7219c6187 Updated wording in README. 61da78fbb Updated cmake readme section. d68740570 Added #include "unordered_map" to main header 8297ae81a Implemented wrapper corresponding to tick_params in matplotlib 6fb6a9156 Fix multiple definition of subplot2grid 97729fd2c Add possibility to pass additional parameters to scatter (like color or label) 5adfbe031 Rearrange Makefile. 1ac91f759 subplot2grid implementation and example 6ec72daa6 Fix: Allow for building examples individually You don't necessarily want to build all of them. Now you can do, e.g.: make examples/minimal 1c2a51f50 Add .gitignore file for example binaries dbe8e4c63 Makefile: Better numpy handling and make building more generic Changes: * Use system version of python by default (overridable with PYTHON_BIN) * Find where numpy headers live on system * Remove boilerplate from Makefile and just build all examples/*.cpp files with appropriate flags d3137c53b Fix for imshow multiple definition error #48 f4ad842e7 Implements bar slightly more closely to matplotlib 7fa134ea1 Fixes compiler warnings 277221701 Fix for OpenCV 4 In the latest version of OpenCV, several constants were removed in favour of enum classes. Fix by #define'ing the ones we need. 5dd719498 Add support for plot(y,keywords) bc7e4576b Added basic example for imshow. 20e090ef9 Add support for imshow() 019cd237a check functions with narrower error message scope 4ace1ad94 fix the figsize segfault bug 94c0215d6 Fixed type in update example. c48ed308d Reduced example for dynamic plot class. 07a73fad2 Add dynamic plot class 8babc98e0 Add kwargs for title, xlabel, ylabel f64f1f658 Added missing <array> header d184e1467 Add cumulative parameter to hist() 05087cf86 Additional debug output if python module loading fails d42a969cc Add portability #defines PyLong_FromLong, PyUnicode_FromString d89878b95 Add fill plot with example 0e39f8f56 Load mplot3d module lazily. eae3824b0 Add picture and cpp file for new surface example. 69e58fe25 Add plot_surface 65933e3d4 Officially require C++11. c19e00ca4 Add -std=c++11 for basic in Makefile 94f6c0102 Add bar plot and subplots_adjust 8baa5821c Add missing Py_DECREF in scatter function. 78719eb5f added support for scatter plots 073dd98f6 Add fignum_exists() function c92ad4cd1 Optionally pass figure number to figure() as argument dcb23221b Return figure number from figure function b1242079b Add support for ginput() function e49f4f7cc Chose a better name for the parameter to text 41a46e5d0 Fixed whitespace b60d3384a Added text and suptitle 3d555d226 Add missing Py_DECREF to quiver() 00a4766f7 Fix indentation in basic example, 079194581 Update README and Makefile for quiver plot example. c1ad253e7 Add example of quiver plot 697054cab Add quiver function for 4 vectors of uniform length 16a7fd66c Fix implementation of errorbar() At the moment, the errorbar() function takes an optional parameter s, which is presumably supposed to correspond to the same parameter for e.g. the plot function. The only problem is that a) this argument is unused in the function and b) matplotlib's errorbar() doesn't take a parameter like this anyway. 6e3fcf65c Update windows/VS2017 support 331029fd1 Add support for xticks and yticks 717e98e75 Add figure_size 1d23b2883 added example for fill_inbetween.cpp b74e465ba fix a small typo, no content changes git-subtree-dir: third_party/matplotlib-cpp git-subtree-split: 7d0e695409e7029fd52a4653907a167b4cc725b9
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)
Alternative way (for CMake <= 3.11):
find_package(PythonLibs 2.7) target_include_directories(myproject PRIVATE ${PYTHON_INCLUDE_DIRS}) target_link_libraries(myproject ${PYTHON_LIBRARIES})
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.
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.
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
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.
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 "".'
MacOS: Unable to import matplotlib.pyplot
. Cause: In mac os image rendering back end of matplotlib (what-is-a-backend to render using the API of Cocoa by default). There is Qt4Agg and GTKAgg and as a back-end is not the default. Set the back end of macosx that is differ compare with other windows or linux os. Solution is described here, additional information can be found there too(see links in answers).