From 4a0fc880b374d6e3348ec10f5246ad764490333d Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Mon, 26 Sep 2022 13:27:06 +0800 Subject: [PATCH 01/31] =?UTF-8?q?[09/26/2022]=20=E5=A2=9E=E5=8A=A0anaconda?= =?UTF-8?q?3=E7=9A=84=E7=BC=96=E8=AF=91=E5=92=8C=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加anaconda3的编译和运行说明 --- README.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0f8479f..fd299d4 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,19 @@ int main() { plt::show(); } ``` - g++ minimal.cpp -std=c++11 -I/usr/include/python2.7 -lpython2.7 +**一般方式编译** + +```bash +g++ minimal.cpp -std=c++11 -I/usr/include/python2.7 -lpython2.7 +``` + +**Anaconda方式编译** + +```bash +g++ minimal.cpp -std=c++11 -I${CONDA_PREFIX}/include/python3.7m -I${CONDA_PREFIX}/lib/python3.7/site-packages/numpy/core/include -L${CONDA_PREFIX}/lib -lpython3.7m -o minimal +``` + +如果是`python3.8`,那么相关地方修改成`3.8`即可。在运行的时候,必须把`libpython3.7m.so`的目录放在`LD_LIBRARY_PATH`中,否则`mininal`程序无法运行。 **Result:** @@ -240,7 +252,7 @@ You can download and install matplotlib-cpp using the [vcpkg](https://github.com ./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](https://github.com/Microsoft/vcpkg) on the vcpkg repository. From 424d2469e6586be1d17513a0760b38c941698640 Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Mon, 26 Sep 2022 13:28:40 +0800 Subject: [PATCH 02/31] =?UTF-8?q?[09/26/2022]=20=E5=91=BD=E5=90=8D?= =?UTF-8?q?=E8=BE=93=E5=87=BA=E6=96=87=E4=BB=B6=E4=BE=BF=E4=BA=8E=E8=BF=90?= =?UTF-8?q?=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 命名输出文件便于运行 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fd299d4..3a4a521 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ int main() { **一般方式编译** ```bash -g++ minimal.cpp -std=c++11 -I/usr/include/python2.7 -lpython2.7 +g++ minimal.cpp -std=c++11 -I/usr/include/python2.7 -lpython2.7 -o minimal ``` **Anaconda方式编译** From 3ca02f69bc7331cc0b01fc62428ffd6cfa6e9f7b Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Mon, 26 Sep 2022 14:10:05 +0800 Subject: [PATCH 03/31] =?UTF-8?q?[09/26/2022]=20=E9=95=BF=E8=A1=8Cshell?= =?UTF-8?q?=E5=91=BD=E4=BB=A4=E5=88=86=E6=88=90=E8=8B=A5=E5=B9=B2=E5=A4=9A?= =?UTF-8?q?=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 长行shell命令分成若干多行 --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3a4a521..cb11ca9 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,13 @@ g++ minimal.cpp -std=c++11 -I/usr/include/python2.7 -lpython2.7 -o minimal **Anaconda方式编译** ```bash -g++ minimal.cpp -std=c++11 -I${CONDA_PREFIX}/include/python3.7m -I${CONDA_PREFIX}/lib/python3.7/site-packages/numpy/core/include -L${CONDA_PREFIX}/lib -lpython3.7m -o minimal +g++ minimal.cpp \ + -std=c++11 \ + -I${CONDA_PREFIX}/include/python3.7m \ + -I${CONDA_PREFIX}/lib/python3.7/site-packages/numpy/core/include \ + -L${CONDA_PREFIX}/lib + -lpython3.7m \ + -o minimal ``` 如果是`python3.8`,那么相关地方修改成`3.8`即可。在运行的时候,必须把`libpython3.7m.so`的目录放在`LD_LIBRARY_PATH`中,否则`mininal`程序无法运行。 From 4f0cfcfd0ebf6a065193e79255af5c32be1bcf0c Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Mon, 26 Sep 2022 20:24:48 +0800 Subject: [PATCH 04/31] [09/26/2022] ignore dist and build folders ignore dist and build folders --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 1c4a1b0..c7f4178 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,7 @@ # vim temp files *.sw* + +build/* +dist/* + From 6de5a5011133e644a23eb4fffe8dee3a11fa64b8 Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Mon, 26 Sep 2022 21:19:56 +0800 Subject: [PATCH 05/31] =?UTF-8?q?[09/26/2022]=20=E4=BD=BF=E7=94=A8>=3DCMak?= =?UTF-8?q?e3.15=E7=89=88=E6=9C=AC=E6=9D=A5=E6=AD=A3=E7=A1=AE=E8=AF=86?= =?UTF-8?q?=E5=88=ABAnaconda=E4=B8=AD=E7=9A=84python3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 使用>=CMake3.15版本来正确识别Anaconda中的python3 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bb2decd..8d4b3f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.8 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15 FATAL_ERROR) project(matplotlib_cpp LANGUAGES CXX) include(GNUInstallDirs) From e078c375610ef0c284013127fa922fb514f0041c Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Mon, 26 Sep 2022 21:20:51 +0800 Subject: [PATCH 06/31] =?UTF-8?q?[09/26/2022]=20=E5=9C=A8Windows=E4=B8=8Bl?= =?UTF-8?q?onglong=E4=B8=8Eint64=E6=98=AF=E4=B8=80=E6=A0=B7=E7=9A=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在Windows下longlong与int64是一样的 --- matplotlibcpp.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/matplotlibcpp.h b/matplotlibcpp.h index d95d46a..f3d5692 100644 --- a/matplotlibcpp.h +++ b/matplotlibcpp.h @@ -350,10 +350,12 @@ template <> struct select_npy_type { const static NPY_TYPES type = NPY // Sanity checks; comment them out or change the numpy type below if you're compiling on // a platform where they don't apply +#ifndef _WIN32 static_assert(sizeof(long long) == 8); template <> struct select_npy_type { const static NPY_TYPES type = NPY_INT64; }; static_assert(sizeof(unsigned long long) == 8); template <> struct select_npy_type { const static NPY_TYPES type = NPY_UINT64; }; +#endif template PyObject* get_array(const std::vector& v) From a681365d6ad848221890b07d59ab578ff105bea0 Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Mon, 26 Sep 2022 21:27:53 +0800 Subject: [PATCH 07/31] =?UTF-8?q?[09/26/2022]=20=E5=9C=A8Windows=E4=B8=8B?= =?UTF-8?q?=E7=BC=96=E8=AF=91matplotlib-cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在Windows下编译matplotlib-cpp --- README.md | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index cb11ca9..85f47be 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,18 @@ 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. +## 编译matplotlib-cpp +### Windows + +```bash +mkdir build +cd build +cmake .. -G "Visual Studio 15 2017 Win64" -DCMAKE_INSTALL_PREFIX=..\dist +%comspec% /k "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" +msbuild /maxcpucount:4 /p:Configuration=Release /p:PreferredToolArchitecture=x64 ALL_BUILD.vcxproj +msbuild /maxcpucount:4 /p:Configuration=Release /p:PreferredToolArchitecture=x64 INSTALL.vcxproj +``` Usage ----- @@ -17,25 +28,7 @@ int main() { plt::show(); } ``` -**一般方式编译** - -```bash -g++ minimal.cpp -std=c++11 -I/usr/include/python2.7 -lpython2.7 -o minimal -``` - -**Anaconda方式编译** - -```bash -g++ minimal.cpp \ - -std=c++11 \ - -I${CONDA_PREFIX}/include/python3.7m \ - -I${CONDA_PREFIX}/lib/python3.7/site-packages/numpy/core/include \ - -L${CONDA_PREFIX}/lib - -lpython3.7m \ - -o minimal -``` - -如果是`python3.8`,那么相关地方修改成`3.8`即可。在运行的时候,必须把`libpython3.7m.so`的目录放在`LD_LIBRARY_PATH`中,否则`mininal`程序无法运行。 + g++ minimal.cpp -std=c++11 -I/usr/include/python2.7 -lpython2.7 **Result:** From 7729f724ddaa230a658da18c19caf0813833796e Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Mon, 26 Sep 2022 22:14:10 +0800 Subject: [PATCH 08/31] =?UTF-8?q?[09/26/2022]=20=E5=A2=9E=E5=8A=A0minimal.?= =?UTF-8?q?cpp=E7=BC=96=E8=AF=91=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加minimal.cpp编译方式 --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index 85f47be..9ee4050 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,28 @@ int main() { plt::show(); } ``` +**source**: [minimal.cpp](https://github.com/SNSerHello/matplotlib-cpp/blob/master/examples/minimal.cpp) + +**一般方式编译** + +```bash +g++ minimal.cpp -std=c++11 -I/usr/include/python2.7 -lpython2.7 -o minimal +``` + +**Anaconda方式编译** + +```bash +g++ minimal.cpp \ + -std=c++11 \ + -I${CONDA_PREFIX}/include/python3.7m \ + -I${CONDA_PREFIX}/lib/python3.7/site-packages/numpy/core/include \ + -L${CONDA_PREFIX}/lib + -lpython3.7m \ + -o minimal +``` + +如果是`python3.8`,那么相关地方修改成`3.8`即可。在运行的时候,必须把`libpython3.7m.so`的目录放在`LD_LIBRARY_PATH`中,否则`mininal`程序无法运行。 + g++ minimal.cpp -std=c++11 -I/usr/include/python2.7 -lpython2.7 **Result:** From 132b5a32e328cab2988a3b5bff4147692609471e Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Mon, 26 Sep 2022 22:56:36 +0800 Subject: [PATCH 09/31] =?UTF-8?q?[09/26/2022]=20=E5=9C=A8Ubuntu=E4=B8=8B?= =?UTF-8?q?=E7=BC=96=E8=AF=91matplotlib-cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在Ubuntu下编译matplotlib-cpp --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 9ee4050..d37f96e 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,19 @@ msbuild /maxcpucount:4 /p:Configuration=Release /p:PreferredToolArchitecture=x64 msbuild /maxcpucount:4 /p:Configuration=Release /p:PreferredToolArchitecture=x64 INSTALL.vcxproj ``` +### Ubuntu + +```bash +mkdir build +cd build +cmake .. -DCMAKE_INSTALL_PREFIX=../dist +make -j4 +make install +``` + Usage ----- + Complete minimal example: ```cpp #include "matplotlibcpp.h" From 18aab9e410e87d3c3b10d30749ec0c1309dc6bc4 Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Mon, 26 Sep 2022 23:22:36 +0800 Subject: [PATCH 10/31] =?UTF-8?q?[09/26/2022]=20=E4=BD=BF=E7=94=A8PYTHONHO?= =?UTF-8?q?ME=E5=92=8CPYTHONPATH=E6=9D=A5=E8=AE=BE=E7=BD=AE=E8=BF=90?= =?UTF-8?q?=E8=A1=8C=E7=8E=AF=E5=A2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 使用PYTHONHOME和PYTHONPATH来设置运行环境 --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index d37f96e..85b088d 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,14 @@ g++ minimal.cpp \ 如果是`python3.8`,那么相关地方修改成`3.8`即可。在运行的时候,必须把`libpython3.7m.so`的目录放在`LD_LIBRARY_PATH`中,否则`mininal`程序无法运行。 +### Anaconda环境下运行 + +```bash +export PYTHONHOME=$CONDA_PREFIX/lib/python3.7 +export PYTHONPATH=$PYTHONHOME:$CONDA_PREFIX/lib/python3.7/site-packages:$CONDA_PREFIX/lib/python3.7/lib-dynload +./minimal +``` + g++ minimal.cpp -std=c++11 -I/usr/include/python2.7 -lpython2.7 **Result:** From e2896fd4d31702f9cc2c0165ab3f33988ce7020d Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Tue, 27 Sep 2022 00:01:15 +0800 Subject: [PATCH 11/31] =?UTF-8?q?[09/27/2022]=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=97=A0=E7=94=A8=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 删除无用信息 --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 85b088d..1c07d8f 100644 --- a/README.md +++ b/README.md @@ -59,9 +59,7 @@ g++ minimal.cpp \ -o minimal ``` -如果是`python3.8`,那么相关地方修改成`3.8`即可。在运行的时候,必须把`libpython3.7m.so`的目录放在`LD_LIBRARY_PATH`中,否则`mininal`程序无法运行。 - -### Anaconda环境下运行 +**Anaconda环境下运行** ```bash export PYTHONHOME=$CONDA_PREFIX/lib/python3.7 From 4be7f4d77847afaac319cb3c951cf5c8ecd8eaa0 Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Tue, 27 Sep 2022 00:03:49 +0800 Subject: [PATCH 12/31] =?UTF-8?q?[09/27/2022]=20=E4=BD=BF=E7=94=A8PYTHONHO?= =?UTF-8?q?ME=E6=9D=A5=E7=AE=80=E5=8C=96=E4=BE=9D=E8=B5=96=E5=85=B3?= =?UTF-8?q?=E7=B3=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 使用PYTHONHOME来简化依赖关系 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1c07d8f..f92b94b 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ g++ minimal.cpp \ ```bash export PYTHONHOME=$CONDA_PREFIX/lib/python3.7 -export PYTHONPATH=$PYTHONHOME:$CONDA_PREFIX/lib/python3.7/site-packages:$CONDA_PREFIX/lib/python3.7/lib-dynload +export PYTHONPATH=$PYTHONHOME:$PYTHONHOME/site-packages:$PYTHONHOME/lib-dynload ./minimal ``` From 2479368fd97f3636c86db5ed0fc5326e99b32c99 Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Tue, 27 Sep 2022 08:04:02 +0800 Subject: [PATCH 13/31] =?UTF-8?q?[09/27/2022]=20=E5=88=A0=E9=99=A4Sanity?= =?UTF-8?q?=20check=E5=9B=A0=E4=B8=BA=E5=AE=83=E9=9C=80=E8=A6=81stdc++17?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 删除Sanity check因为它需要stdc++17 --- matplotlibcpp.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/matplotlibcpp.h b/matplotlibcpp.h index f3d5692..cd22258 100644 --- a/matplotlibcpp.h +++ b/matplotlibcpp.h @@ -348,15 +348,6 @@ template <> struct select_npy_type { const static NPY_TYPES type = NPY template <> struct select_npy_type { const static NPY_TYPES type = NPY_ULONG; }; template <> struct select_npy_type { const static NPY_TYPES type = NPY_UINT64; }; -// Sanity checks; comment them out or change the numpy type below if you're compiling on -// a platform where they don't apply -#ifndef _WIN32 -static_assert(sizeof(long long) == 8); -template <> struct select_npy_type { const static NPY_TYPES type = NPY_INT64; }; -static_assert(sizeof(unsigned long long) == 8); -template <> struct select_npy_type { const static NPY_TYPES type = NPY_UINT64; }; -#endif - template PyObject* get_array(const std::vector& v) { From f50ce5e5041a4ea7dff386f226b81b072c14448e Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Tue, 27 Sep 2022 08:08:13 +0800 Subject: [PATCH 14/31] =?UTF-8?q?[09/27/2022]=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8F=E7=9A=84=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E4=BD=BF=E5=85=B6=E8=83=BD=E5=A4=9F=E8=87=AA=E5=8A=A8=E8=BF=90?= =?UTF-8?q?=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加环境变量的设置使其能够自动运行 --- README.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f92b94b..9e91cb9 100644 --- a/README.md +++ b/README.md @@ -33,10 +33,22 @@ Usage Complete minimal example: ```cpp #include "matplotlibcpp.h" -namespace plt = matplotlibcpp; +#define plt matplotlibcpp + int main() { - plt::plot({1,3,2,4}); - plt::show(); + // 增加环境变量设置可以免除在运行的时候手动的增加 + const std::string PYTHONHOME = + std::string(getenv("CONDA_PREFIX")) + "/lib/python3.7m"; + const std::string PYTHONPATH = PYTHONHOME + ":" + PYTHONHOME + + "/site-packages:" + PYTHONHOME + + "/lib-dynload"; + setenv("PYTHONHOME", PYTHONHOME.c_str(), 1); + setenv("PYTHONPATH", PYTHONPATH.c_str(), 1); + + plt::plot({1,3,2,4}); + plt::show(); + + return 0; } ``` **source**: [minimal.cpp](https://github.com/SNSerHello/matplotlib-cpp/blob/master/examples/minimal.cpp) From 5653b53e458addb1db55c0430420d14de64572ba Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Tue, 27 Sep 2022 08:12:37 +0800 Subject: [PATCH 15/31] [09/27/2022] python2.7 -> python3.7 python2.7 -> python3.7 --- README.md | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 9e91cb9..eb431ad 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ int main() { **一般方式编译** ```bash -g++ minimal.cpp -std=c++11 -I/usr/include/python2.7 -lpython2.7 -o minimal +g++ minimal.cpp -std=c++11 -I/usr/include/python3.7 -lpython3.7 -o minimal ``` **Anaconda方式编译** @@ -79,8 +79,6 @@ export PYTHONPATH=$PYTHONHOME:$PYTHONHOME/site-packages:$PYTHONHOME/lib-dynload ./minimal ``` - g++ minimal.cpp -std=c++11 -I/usr/include/python2.7 -lpython2.7 - **Result:** ![Minimal example](./examples/minimal.png) @@ -121,7 +119,9 @@ int main() plt::save("./basic.png"); } ``` - g++ basic.cpp -I/usr/include/python2.7 -lpython2.7 +```bash +g++ basic.cpp -I/usr/include/python3.7 -lpython3.7 +``` **Result:** @@ -156,7 +156,9 @@ int main() plt::show(); } ``` - g++ modern.cpp -std=c++11 -I/usr/include/python2.7 -lpython +```bash +g++ modern.cpp -std=c++11 -I/usr/include/python3.7 -lpython3.7 +``` **Result:** @@ -186,7 +188,9 @@ int main() { } ``` - g++ xkcd.cpp -std=c++11 -I/usr/include/python2.7 -lpython2.7 +```bash +g++ xkcd.cpp -std=c++11 -I/usr/include/python3.7 -lpython3.7 +``` **Result:** @@ -258,7 +262,9 @@ matplotlib-cpp works by wrapping the popular python plotting library matplotlib. 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 +```bash +sudo apt-get install python-matplotlib python-numpy python3.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 @@ -287,21 +293,27 @@ 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 +```bash +g++ example.cpp -I/usr/include/python3.7 -lpython3.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 +```bash +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](https://github.com/Microsoft/vcpkg) dependency manager: - git clone https://github.com/Microsoft/vcpkg.git - cd vcpkg - ./bootstrap-vcpkg.sh - ./vcpkg integrate install - vcpkg install matplotlib-cpp +```bash +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](https://github.com/Microsoft/vcpkg) on the vcpkg repository. From 1d7838dba112f5e96b441c3bf67c6414bf8fdfa8 Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Tue, 27 Sep 2022 08:14:11 +0800 Subject: [PATCH 16/31] =?UTF-8?q?[09/27/2022]=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E9=81=97=E6=BC=8F=E9=83=A8=E5=88=86=EF=BC=9Apython2.7=20->=20p?= =?UTF-8?q?ython3.7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加遗漏部分:python2.7 -> python3.7 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eb431ad..1d3e753 100644 --- a/README.md +++ b/README.md @@ -219,7 +219,7 @@ int main() plt::show(); } ``` - g++ quiver.cpp -std=c++11 -I/usr/include/python2.7 -lpython2.7 + g++ quiver.cpp -std=c++11 -I/usr/include/python3.7 -lpython3.7 **Result:** From 55349d3e37e0000747493bafc41c292eba2f7a2f Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Tue, 27 Sep 2022 10:37:16 +0800 Subject: [PATCH 17/31] =?UTF-8?q?[09/27/2022]=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E8=AE=BE=E7=BD=AE=E7=8E=AF=E5=A2=83=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加自动设置环境变量的代码 --- README.md | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1d3e753..b51e097 100644 --- a/README.md +++ b/README.md @@ -32,13 +32,54 @@ Usage Complete minimal example: ```cpp +#include +#include +#include +#include + +#define PY_MAJOR_VERSION 3 #include "matplotlibcpp.h" #define plt matplotlibcpp +std::string to_strip(const std::string &str, + const std::string &whitespace = " \n\r\t\f\v") { + size_t from = str.find_first_not_of(whitespace); + + if (from == std::string::npos) { + return ""; + } + size_t to = str.find_last_not_of(whitespace); + assert(to != std::string::npos); + + return str.substr(from, (to - from) + 1); +} + +std::string COMMAND(const std::string &cmd) { + using pipe_ptr = std::unique_ptr; + pipe_ptr pipe(popen(cmd.c_str(), "r"), pclose); + if (pipe == nullptr) { + std::cout << "error: failed to execute: " << cmd << std::endl; + return ""; + } + + const int BUF_SIZE = 1023; + char buf[BUF_SIZE + 1]; + buf[BUF_SIZE] = '\0'; + std::stringstream out; + while (fgets(buf, BUF_SIZE, pipe.get()) != NULL) { + out << buf; + } + pclose(pipe.release()); + + return out.str(); +} + int main() { // 增加环境变量设置可以免除在运行的时候手动的增加 + const std::string PYTHON_VERSION = + to_strip(COMMAND("python3 --version | cut -d ' ' -f2 | cut -d '.' -f-2")); const std::string PYTHONHOME = - std::string(getenv("CONDA_PREFIX")) + "/lib/python3.7m"; + std::string(getenv("CONDA_PREFIX")) + "/lib/python" + PYTHON_VERSION; const std::string PYTHONPATH = PYTHONHOME + ":" + PYTHONHOME + "/site-packages:" + PYTHONHOME + "/lib-dynload"; @@ -64,7 +105,7 @@ g++ minimal.cpp -std=c++11 -I/usr/include/python3.7 -lpython3.7 -o minimal ```bash g++ minimal.cpp \ -std=c++11 \ - -I${CONDA_PREFIX}/include/python3.7m \ + -I${CONDA_PREFIX}/include/python3.7 \ -I${CONDA_PREFIX}/lib/python3.7/site-packages/numpy/core/include \ -L${CONDA_PREFIX}/lib -lpython3.7m \ From 2193b906307b2104730712b2833e962de6fa4744 Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Wed, 28 Sep 2022 21:30:56 +0800 Subject: [PATCH 18/31] =?UTF-8?q?[09/28/2022]=20=E8=B0=83=E6=95=B4source?= =?UTF-8?q?=20codes=E6=A0=BC=E5=BC=8F=E7=AC=A6=E5=90=88LLVM=E9=A3=8E?= =?UTF-8?q?=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 调整source codes格式符合LLVM风格 --- matplotlibcpp.h | 3972 +++++++++++++++++++++++++---------------------- 1 file changed, 2086 insertions(+), 1886 deletions(-) diff --git a/matplotlibcpp.h b/matplotlibcpp.h index cd22258..a052067 100644 --- a/matplotlibcpp.h +++ b/matplotlibcpp.h @@ -4,289 +4,291 @@ // they define _POSIX_C_SOURCE #include -#include -#include -#include -#include #include -#include -#include +#include #include // requires c++11 support #include +#include +#include +#include +#include #include // std::stod +#include #ifndef WITHOUT_NUMPY -# define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION -# include +#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION +#include -# ifdef WITH_OPENCV -# include -# endif // WITH_OPENCV +#ifdef WITH_OPENCV +#include +#endif // WITH_OPENCV /* * A bunch of constants were removed in OpenCV 4 in favour of enum classes, so * define the ones we need here. */ -# if CV_MAJOR_VERSION > 3 -# define CV_BGR2RGB cv::COLOR_BGR2RGB -# define CV_BGRA2RGBA cv::COLOR_BGRA2RGBA -# endif +#if CV_MAJOR_VERSION > 3 +#define CV_BGR2RGB cv::COLOR_BGR2RGB +#define CV_BGRA2RGBA cv::COLOR_BGRA2RGBA +#endif #endif // WITHOUT_NUMPY #if PY_MAJOR_VERSION >= 3 -# define PyString_FromString PyUnicode_FromString -# define PyInt_FromLong PyLong_FromLong -# define PyString_FromString PyUnicode_FromString +#define PyString_FromString PyUnicode_FromString +#define PyInt_FromLong PyLong_FromLong +#define PyString_FromString PyUnicode_FromString #endif - namespace matplotlibcpp { namespace detail { static std::string s_backend; struct _interpreter { - PyObject* s_python_function_arrow; - PyObject *s_python_function_show; - PyObject *s_python_function_close; - PyObject *s_python_function_draw; - PyObject *s_python_function_pause; - PyObject *s_python_function_save; - PyObject *s_python_function_figure; - PyObject *s_python_function_fignum_exists; - PyObject *s_python_function_plot; - PyObject *s_python_function_quiver; - PyObject* s_python_function_contour; - PyObject *s_python_function_semilogx; - PyObject *s_python_function_semilogy; - PyObject *s_python_function_loglog; - PyObject *s_python_function_fill; - PyObject *s_python_function_fill_between; - PyObject *s_python_function_hist; - PyObject *s_python_function_imshow; - PyObject *s_python_function_scatter; - PyObject *s_python_function_boxplot; - PyObject *s_python_function_subplot; - PyObject *s_python_function_subplot2grid; - PyObject *s_python_function_legend; - PyObject *s_python_function_xlim; - PyObject *s_python_function_ion; - PyObject *s_python_function_ginput; - PyObject *s_python_function_ylim; - PyObject *s_python_function_title; - PyObject *s_python_function_axis; - PyObject *s_python_function_axhline; - PyObject *s_python_function_axvline; - PyObject *s_python_function_axvspan; - PyObject *s_python_function_xlabel; - PyObject *s_python_function_ylabel; - PyObject *s_python_function_gca; - PyObject *s_python_function_xticks; - PyObject *s_python_function_yticks; - PyObject* s_python_function_margins; - PyObject *s_python_function_tick_params; - PyObject *s_python_function_grid; - PyObject* s_python_function_cla; - PyObject *s_python_function_clf; - PyObject *s_python_function_errorbar; - PyObject *s_python_function_annotate; - PyObject *s_python_function_tight_layout; - PyObject *s_python_colormap; - PyObject *s_python_empty_tuple; - PyObject *s_python_function_stem; - PyObject *s_python_function_xkcd; - PyObject *s_python_function_text; - PyObject *s_python_function_suptitle; - PyObject *s_python_function_bar; - PyObject *s_python_function_barh; - PyObject *s_python_function_colorbar; - PyObject *s_python_function_subplots_adjust; - PyObject *s_python_function_rcparams; - PyObject *s_python_function_spy; - - /* For now, _interpreter is implemented as a singleton since its currently not possible to have - multiple independent embedded python interpreters without patching the python source code - or starting a separate process for each. [1] - Furthermore, many python objects expect that they are destructed in the same thread as they - were constructed. [2] So for advanced usage, a `kill()` function is provided so that library - users can manually ensure that the interpreter is constructed and destroyed within the - same thread. - - 1: http://bytes.com/topic/python/answers/793370-multiple-independent-python-interpreters-c-c-program - 2: https://github.com/lava/matplotlib-cpp/pull/202#issue-436220256 - */ - - static _interpreter& get() { - return interkeeper(false); - } - - static _interpreter& kill() { - return interkeeper(true); - } - - // Stores the actual singleton object referenced by `get()` and `kill()`. - static _interpreter& interkeeper(bool should_kill) { - static _interpreter ctx; - if (should_kill) - ctx.~_interpreter(); - return ctx; - } + PyObject *s_python_function_arrow; + PyObject *s_python_function_show; + PyObject *s_python_function_close; + PyObject *s_python_function_draw; + PyObject *s_python_function_pause; + PyObject *s_python_function_save; + PyObject *s_python_function_figure; + PyObject *s_python_function_fignum_exists; + PyObject *s_python_function_plot; + PyObject *s_python_function_quiver; + PyObject *s_python_function_contour; + PyObject *s_python_function_semilogx; + PyObject *s_python_function_semilogy; + PyObject *s_python_function_loglog; + PyObject *s_python_function_fill; + PyObject *s_python_function_fill_between; + PyObject *s_python_function_hist; + PyObject *s_python_function_imshow; + PyObject *s_python_function_scatter; + PyObject *s_python_function_boxplot; + PyObject *s_python_function_subplot; + PyObject *s_python_function_subplot2grid; + PyObject *s_python_function_legend; + PyObject *s_python_function_xlim; + PyObject *s_python_function_ion; + PyObject *s_python_function_ginput; + PyObject *s_python_function_ylim; + PyObject *s_python_function_title; + PyObject *s_python_function_axis; + PyObject *s_python_function_axhline; + PyObject *s_python_function_axvline; + PyObject *s_python_function_axvspan; + PyObject *s_python_function_xlabel; + PyObject *s_python_function_ylabel; + PyObject *s_python_function_gca; + PyObject *s_python_function_xticks; + PyObject *s_python_function_yticks; + PyObject *s_python_function_margins; + PyObject *s_python_function_tick_params; + PyObject *s_python_function_grid; + PyObject *s_python_function_cla; + PyObject *s_python_function_clf; + PyObject *s_python_function_errorbar; + PyObject *s_python_function_annotate; + PyObject *s_python_function_tight_layout; + PyObject *s_python_colormap; + PyObject *s_python_empty_tuple; + PyObject *s_python_function_stem; + PyObject *s_python_function_xkcd; + PyObject *s_python_function_text; + PyObject *s_python_function_suptitle; + PyObject *s_python_function_bar; + PyObject *s_python_function_barh; + PyObject *s_python_function_colorbar; + PyObject *s_python_function_subplots_adjust; + PyObject *s_python_function_rcparams; + PyObject *s_python_function_spy; + + /* For now, _interpreter is implemented as a singleton since its currently not + possible to have multiple independent embedded python interpreters without + patching the python source code or starting a separate process for each. + [1] Furthermore, many python objects expect that they are destructed in the + same thread as they were constructed. [2] So for advanced usage, a `kill()` + function is provided so that library users can manually ensure that the + interpreter is constructed and destroyed within the same thread. + + 1: + http://bytes.com/topic/python/answers/793370-multiple-independent-python-interpreters-c-c-program + 2: https://github.com/lava/matplotlib-cpp/pull/202#issue-436220256 + */ + + static _interpreter &get() { return interkeeper(false); } + + static _interpreter &kill() { return interkeeper(true); } + + // Stores the actual singleton object referenced by `get()` and `kill()`. + static _interpreter &interkeeper(bool should_kill) { + static _interpreter ctx; + if (should_kill) + ctx.~_interpreter(); + return ctx; + } - PyObject* safe_import(PyObject* module, std::string fname) { - PyObject* fn = PyObject_GetAttrString(module, fname.c_str()); + PyObject *safe_import(PyObject *module, std::string fname) { + PyObject *fn = PyObject_GetAttrString(module, fname.c_str()); - if (!fn) - throw std::runtime_error(std::string("Couldn't find required function: ") + fname); + if (!fn) + throw std::runtime_error( + std::string("Couldn't find required function: ") + fname); - if (!PyFunction_Check(fn)) - throw std::runtime_error(fname + std::string(" is unexpectedly not a PyFunction.")); + if (!PyFunction_Check(fn)) + throw std::runtime_error( + fname + std::string(" is unexpectedly not a PyFunction.")); - return fn; - } + return fn; + } private: - #ifndef WITHOUT_NUMPY -# if PY_MAJOR_VERSION >= 3 +#if PY_MAJOR_VERSION >= 3 - void *import_numpy() { - import_array(); // initialize C-API - return NULL; - } + void *import_numpy() { + import_array(); // initialize C-API + return NULL; + } -# else +#else - void import_numpy() { - import_array(); // initialize C-API - } + void import_numpy() { + import_array(); // initialize C-API + } -# endif +#endif #endif - _interpreter() { + _interpreter() { - // optional but recommended + // optional but recommended #if PY_MAJOR_VERSION >= 3 - wchar_t name[] = L"plotting"; + wchar_t name[] = L"plotting"; #else - char name[] = "plotting"; + char name[] = "plotting"; #endif - Py_SetProgramName(name); - Py_Initialize(); + Py_SetProgramName(name); + Py_Initialize(); - wchar_t const *dummy_args[] = {L"Python", NULL}; // const is needed because literals must not be modified - wchar_t const **argv = dummy_args; - int argc = sizeof(dummy_args)/sizeof(dummy_args[0])-1; + wchar_t const *dummy_args[] = { + L"Python", + NULL}; // const is needed because literals must not be modified + wchar_t const **argv = dummy_args; + int argc = sizeof(dummy_args) / sizeof(dummy_args[0]) - 1; #if PY_MAJOR_VERSION >= 3 - PySys_SetArgv(argc, const_cast(argv)); + PySys_SetArgv(argc, const_cast(argv)); #else - PySys_SetArgv(argc, (char **)(argv)); + PySys_SetArgv(argc, (char **)(argv)); #endif #ifndef WITHOUT_NUMPY - import_numpy(); // initialize numpy C-API + import_numpy(); // initialize numpy C-API #endif - PyObject* matplotlibname = PyString_FromString("matplotlib"); - PyObject* pyplotname = PyString_FromString("matplotlib.pyplot"); - PyObject* cmname = PyString_FromString("matplotlib.cm"); - PyObject* pylabname = PyString_FromString("pylab"); - if (!pyplotname || !pylabname || !matplotlibname || !cmname) { - throw std::runtime_error("couldnt create string"); - } - - PyObject* matplotlib = PyImport_Import(matplotlibname); - - Py_DECREF(matplotlibname); - if (!matplotlib) { - PyErr_Print(); - throw std::runtime_error("Error loading module matplotlib!"); - } - - // matplotlib.use() must be called *before* pylab, matplotlib.pyplot, - // or matplotlib.backends is imported for the first time - if (!s_backend.empty()) { - PyObject_CallMethod(matplotlib, const_cast("use"), const_cast("s"), s_backend.c_str()); - } - - - - PyObject* pymod = PyImport_Import(pyplotname); - Py_DECREF(pyplotname); - if (!pymod) { throw std::runtime_error("Error loading module matplotlib.pyplot!"); } - - s_python_colormap = PyImport_Import(cmname); - Py_DECREF(cmname); - if (!s_python_colormap) { throw std::runtime_error("Error loading module matplotlib.cm!"); } - - PyObject* pylabmod = PyImport_Import(pylabname); - Py_DECREF(pylabname); - if (!pylabmod) { throw std::runtime_error("Error loading module pylab!"); } - - s_python_function_arrow = safe_import(pymod, "arrow"); - s_python_function_show = safe_import(pymod, "show"); - s_python_function_close = safe_import(pymod, "close"); - s_python_function_draw = safe_import(pymod, "draw"); - s_python_function_pause = safe_import(pymod, "pause"); - s_python_function_figure = safe_import(pymod, "figure"); - s_python_function_fignum_exists = safe_import(pymod, "fignum_exists"); - s_python_function_plot = safe_import(pymod, "plot"); - s_python_function_quiver = safe_import(pymod, "quiver"); - s_python_function_contour = safe_import(pymod, "contour"); - s_python_function_semilogx = safe_import(pymod, "semilogx"); - s_python_function_semilogy = safe_import(pymod, "semilogy"); - s_python_function_loglog = safe_import(pymod, "loglog"); - s_python_function_fill = safe_import(pymod, "fill"); - s_python_function_fill_between = safe_import(pymod, "fill_between"); - s_python_function_hist = safe_import(pymod,"hist"); - s_python_function_scatter = safe_import(pymod,"scatter"); - s_python_function_boxplot = safe_import(pymod,"boxplot"); - s_python_function_subplot = safe_import(pymod, "subplot"); - s_python_function_subplot2grid = safe_import(pymod, "subplot2grid"); - s_python_function_legend = safe_import(pymod, "legend"); - s_python_function_xlim = safe_import(pymod, "xlim"); - s_python_function_ylim = safe_import(pymod, "ylim"); - s_python_function_title = safe_import(pymod, "title"); - s_python_function_axis = safe_import(pymod, "axis"); - s_python_function_axhline = safe_import(pymod, "axhline"); - s_python_function_axvline = safe_import(pymod, "axvline"); - s_python_function_axvspan = safe_import(pymod, "axvspan"); - s_python_function_xlabel = safe_import(pymod, "xlabel"); - s_python_function_ylabel = safe_import(pymod, "ylabel"); - s_python_function_gca = safe_import(pymod, "gca"); - s_python_function_xticks = safe_import(pymod, "xticks"); - s_python_function_yticks = safe_import(pymod, "yticks"); - s_python_function_margins = safe_import(pymod, "margins"); - s_python_function_tick_params = safe_import(pymod, "tick_params"); - s_python_function_grid = safe_import(pymod, "grid"); - s_python_function_ion = safe_import(pymod, "ion"); - s_python_function_ginput = safe_import(pymod, "ginput"); - s_python_function_save = safe_import(pylabmod, "savefig"); - s_python_function_annotate = safe_import(pymod,"annotate"); - s_python_function_cla = safe_import(pymod, "cla"); - s_python_function_clf = safe_import(pymod, "clf"); - s_python_function_errorbar = safe_import(pymod, "errorbar"); - s_python_function_tight_layout = safe_import(pymod, "tight_layout"); - s_python_function_stem = safe_import(pymod, "stem"); - s_python_function_xkcd = safe_import(pymod, "xkcd"); - s_python_function_text = safe_import(pymod, "text"); - s_python_function_suptitle = safe_import(pymod, "suptitle"); - s_python_function_bar = safe_import(pymod,"bar"); - s_python_function_barh = safe_import(pymod, "barh"); - s_python_function_colorbar = PyObject_GetAttrString(pymod, "colorbar"); - s_python_function_subplots_adjust = safe_import(pymod,"subplots_adjust"); - s_python_function_rcparams = PyObject_GetAttrString(pymod, "rcParams"); - s_python_function_spy = PyObject_GetAttrString(pymod, "spy"); -#ifndef WITHOUT_NUMPY - s_python_function_imshow = safe_import(pymod, "imshow"); -#endif - s_python_empty_tuple = PyTuple_New(0); + PyObject *matplotlibname = PyString_FromString("matplotlib"); + PyObject *pyplotname = PyString_FromString("matplotlib.pyplot"); + PyObject *cmname = PyString_FromString("matplotlib.cm"); + PyObject *pylabname = PyString_FromString("pylab"); + if (!pyplotname || !pylabname || !matplotlibname || !cmname) { + throw std::runtime_error("couldnt create string"); + } + + PyObject *matplotlib = PyImport_Import(matplotlibname); + + Py_DECREF(matplotlibname); + if (!matplotlib) { + PyErr_Print(); + throw std::runtime_error("Error loading module matplotlib!"); + } + + // matplotlib.use() must be called *before* pylab, matplotlib.pyplot, + // or matplotlib.backends is imported for the first time + if (!s_backend.empty()) { + PyObject_CallMethod(matplotlib, const_cast("use"), + const_cast("s"), s_backend.c_str()); + } + + PyObject *pymod = PyImport_Import(pyplotname); + Py_DECREF(pyplotname); + if (!pymod) { + throw std::runtime_error("Error loading module matplotlib.pyplot!"); + } + + s_python_colormap = PyImport_Import(cmname); + Py_DECREF(cmname); + if (!s_python_colormap) { + throw std::runtime_error("Error loading module matplotlib.cm!"); } - ~_interpreter() { - Py_Finalize(); + PyObject *pylabmod = PyImport_Import(pylabname); + Py_DECREF(pylabname); + if (!pylabmod) { + throw std::runtime_error("Error loading module pylab!"); } + + s_python_function_arrow = safe_import(pymod, "arrow"); + s_python_function_show = safe_import(pymod, "show"); + s_python_function_close = safe_import(pymod, "close"); + s_python_function_draw = safe_import(pymod, "draw"); + s_python_function_pause = safe_import(pymod, "pause"); + s_python_function_figure = safe_import(pymod, "figure"); + s_python_function_fignum_exists = safe_import(pymod, "fignum_exists"); + s_python_function_plot = safe_import(pymod, "plot"); + s_python_function_quiver = safe_import(pymod, "quiver"); + s_python_function_contour = safe_import(pymod, "contour"); + s_python_function_semilogx = safe_import(pymod, "semilogx"); + s_python_function_semilogy = safe_import(pymod, "semilogy"); + s_python_function_loglog = safe_import(pymod, "loglog"); + s_python_function_fill = safe_import(pymod, "fill"); + s_python_function_fill_between = safe_import(pymod, "fill_between"); + s_python_function_hist = safe_import(pymod, "hist"); + s_python_function_scatter = safe_import(pymod, "scatter"); + s_python_function_boxplot = safe_import(pymod, "boxplot"); + s_python_function_subplot = safe_import(pymod, "subplot"); + s_python_function_subplot2grid = safe_import(pymod, "subplot2grid"); + s_python_function_legend = safe_import(pymod, "legend"); + s_python_function_xlim = safe_import(pymod, "xlim"); + s_python_function_ylim = safe_import(pymod, "ylim"); + s_python_function_title = safe_import(pymod, "title"); + s_python_function_axis = safe_import(pymod, "axis"); + s_python_function_axhline = safe_import(pymod, "axhline"); + s_python_function_axvline = safe_import(pymod, "axvline"); + s_python_function_axvspan = safe_import(pymod, "axvspan"); + s_python_function_xlabel = safe_import(pymod, "xlabel"); + s_python_function_ylabel = safe_import(pymod, "ylabel"); + s_python_function_gca = safe_import(pymod, "gca"); + s_python_function_xticks = safe_import(pymod, "xticks"); + s_python_function_yticks = safe_import(pymod, "yticks"); + s_python_function_margins = safe_import(pymod, "margins"); + s_python_function_tick_params = safe_import(pymod, "tick_params"); + s_python_function_grid = safe_import(pymod, "grid"); + s_python_function_ion = safe_import(pymod, "ion"); + s_python_function_ginput = safe_import(pymod, "ginput"); + s_python_function_save = safe_import(pylabmod, "savefig"); + s_python_function_annotate = safe_import(pymod, "annotate"); + s_python_function_cla = safe_import(pymod, "cla"); + s_python_function_clf = safe_import(pymod, "clf"); + s_python_function_errorbar = safe_import(pymod, "errorbar"); + s_python_function_tight_layout = safe_import(pymod, "tight_layout"); + s_python_function_stem = safe_import(pymod, "stem"); + s_python_function_xkcd = safe_import(pymod, "xkcd"); + s_python_function_text = safe_import(pymod, "text"); + s_python_function_suptitle = safe_import(pymod, "suptitle"); + s_python_function_bar = safe_import(pymod, "bar"); + s_python_function_barh = safe_import(pymod, "barh"); + s_python_function_colorbar = PyObject_GetAttrString(pymod, "colorbar"); + s_python_function_subplots_adjust = safe_import(pymod, "subplots_adjust"); + s_python_function_rcparams = PyObject_GetAttrString(pymod, "rcParams"); + s_python_function_spy = PyObject_GetAttrString(pymod, "spy"); +#ifndef WITHOUT_NUMPY + s_python_function_imshow = safe_import(pymod, "imshow"); +#endif + s_python_empty_tuple = PyTuple_New(0); + } + + ~_interpreter() { Py_Finalize(); } }; } // end namespace detail @@ -299,116 +301,135 @@ struct _interpreter { /// Mainly useful to select the non-interactive 'Agg' backend when running /// matplotlibcpp in headless mode, for example on a machine with no display. /// -/// See also: https://matplotlib.org/2.0.2/api/matplotlib_configuration_api.html#matplotlib.use -inline void backend(const std::string& name) -{ - detail::s_backend = name; -} +/// See also: +/// https://matplotlib.org/2.0.2/api/matplotlib_configuration_api.html#matplotlib.use +inline void backend(const std::string &name) { detail::s_backend = name; } -inline bool annotate(std::string annotation, double x, double y) -{ - detail::_interpreter::get(); +inline bool annotate(std::string annotation, double x, double y) { + detail::_interpreter::get(); - PyObject * xy = PyTuple_New(2); - PyObject * str = PyString_FromString(annotation.c_str()); + PyObject *xy = PyTuple_New(2); + PyObject *str = PyString_FromString(annotation.c_str()); - PyTuple_SetItem(xy,0,PyFloat_FromDouble(x)); - PyTuple_SetItem(xy,1,PyFloat_FromDouble(y)); + PyTuple_SetItem(xy, 0, PyFloat_FromDouble(x)); + PyTuple_SetItem(xy, 1, PyFloat_FromDouble(y)); - PyObject* kwargs = PyDict_New(); - PyDict_SetItemString(kwargs, "xy", xy); + PyObject *kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "xy", xy); - PyObject* args = PyTuple_New(1); - PyTuple_SetItem(args, 0, str); + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, str); - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_annotate, args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_annotate, args, kwargs); - Py_DECREF(args); - Py_DECREF(kwargs); + Py_DECREF(args); + Py_DECREF(kwargs); - if(res) Py_DECREF(res); + if (res) + Py_DECREF(res); - return res; + return res; } namespace detail { #ifndef WITHOUT_NUMPY // Type selector for numpy array conversion -template struct select_npy_type { const static NPY_TYPES type = NPY_NOTYPE; }; //Default -template <> struct select_npy_type { const static NPY_TYPES type = NPY_DOUBLE; }; -template <> struct select_npy_type { const static NPY_TYPES type = NPY_FLOAT; }; -template <> struct select_npy_type { const static NPY_TYPES type = NPY_BOOL; }; -template <> struct select_npy_type { const static NPY_TYPES type = NPY_INT8; }; -template <> struct select_npy_type { const static NPY_TYPES type = NPY_SHORT; }; -template <> struct select_npy_type { const static NPY_TYPES type = NPY_INT; }; -template <> struct select_npy_type { const static NPY_TYPES type = NPY_INT64; }; -template <> struct select_npy_type { const static NPY_TYPES type = NPY_UINT8; }; -template <> struct select_npy_type { const static NPY_TYPES type = NPY_USHORT; }; -template <> struct select_npy_type { const static NPY_TYPES type = NPY_ULONG; }; -template <> struct select_npy_type { const static NPY_TYPES type = NPY_UINT64; }; - -template -PyObject* get_array(const std::vector& v) -{ - npy_intp vsize = v.size(); - NPY_TYPES type = select_npy_type::type; - if (type == NPY_NOTYPE) { - size_t memsize = v.size()*sizeof(double); - double* dp = static_cast(::malloc(memsize)); - for (size_t i=0; i(varray), NPY_ARRAY_OWNDATA); - return varray; - } +template struct select_npy_type { + const static NPY_TYPES type = NPY_NOTYPE; +}; // Default +template <> struct select_npy_type { + const static NPY_TYPES type = NPY_DOUBLE; +}; +template <> struct select_npy_type { + const static NPY_TYPES type = NPY_FLOAT; +}; +template <> struct select_npy_type { + const static NPY_TYPES type = NPY_BOOL; +}; +template <> struct select_npy_type { + const static NPY_TYPES type = NPY_INT8; +}; +template <> struct select_npy_type { + const static NPY_TYPES type = NPY_SHORT; +}; +template <> struct select_npy_type { + const static NPY_TYPES type = NPY_INT; +}; +template <> struct select_npy_type { + const static NPY_TYPES type = NPY_INT64; +}; +template <> struct select_npy_type { + const static NPY_TYPES type = NPY_UINT8; +}; +template <> struct select_npy_type { + const static NPY_TYPES type = NPY_USHORT; +}; +template <> struct select_npy_type { + const static NPY_TYPES type = NPY_ULONG; +}; +template <> struct select_npy_type { + const static NPY_TYPES type = NPY_UINT64; +}; - PyObject* varray = PyArray_SimpleNewFromData(1, &vsize, type, (void*)(v.data())); +template PyObject *get_array(const std::vector &v) { + npy_intp vsize = v.size(); + NPY_TYPES type = select_npy_type::type; + if (type == NPY_NOTYPE) { + size_t memsize = v.size() * sizeof(double); + double *dp = static_cast(::malloc(memsize)); + for (size_t i = 0; i < v.size(); ++i) + dp[i] = v[i]; + PyObject *varray = PyArray_SimpleNewFromData(1, &vsize, NPY_DOUBLE, dp); + PyArray_UpdateFlags(reinterpret_cast(varray), + NPY_ARRAY_OWNDATA); return varray; -} + } + PyObject *varray = + PyArray_SimpleNewFromData(1, &vsize, type, (void *)(v.data())); + return varray; +} -template -PyObject* get_2darray(const std::vector<::std::vector>& v) -{ - if (v.size() < 1) throw std::runtime_error("get_2d_array v too small"); +template +PyObject *get_2darray(const std::vector<::std::vector> &v) { + if (v.size() < 1) + throw std::runtime_error("get_2d_array v too small"); - npy_intp vsize[2] = {static_cast(v.size()), - static_cast(v[0].size())}; + npy_intp vsize[2] = {static_cast(v.size()), + static_cast(v[0].size())}; - PyArrayObject *varray = - (PyArrayObject *)PyArray_SimpleNew(2, vsize, NPY_DOUBLE); + PyArrayObject *varray = + (PyArrayObject *)PyArray_SimpleNew(2, vsize, NPY_DOUBLE); - double *vd_begin = static_cast(PyArray_DATA(varray)); + double *vd_begin = static_cast(PyArray_DATA(varray)); - for (const ::std::vector &v_row : v) { - if (v_row.size() != static_cast(vsize[1])) - throw std::runtime_error("Missmatched array size"); - std::copy(v_row.begin(), v_row.end(), vd_begin); - vd_begin += vsize[1]; - } + for (const ::std::vector &v_row : v) { + if (v_row.size() != static_cast(vsize[1])) + throw std::runtime_error("Missmatched array size"); + std::copy(v_row.begin(), v_row.end(), vd_begin); + vd_begin += vsize[1]; + } - return reinterpret_cast(varray); + return reinterpret_cast(varray); } #else // fallback if we don't have numpy: copy every element of the given vector -template -PyObject* get_array(const std::vector& v) -{ - PyObject* list = PyList_New(v.size()); - for(size_t i = 0; i < v.size(); ++i) { - PyList_SetItem(list, i, PyFloat_FromDouble(v.at(i))); - } - return list; +template PyObject *get_array(const std::vector &v) { + PyObject *list = PyList_New(v.size()); + for (size_t i = 0; i < v.size(); ++i) { + PyList_SetItem(list, i, PyFloat_FromDouble(v.at(i))); + } + return list; } #endif // WITHOUT_NUMPY // sometimes, for labels and such, we need string arrays -inline PyObject * get_array(const std::vector& strings) -{ - PyObject* list = PyList_New(strings.size()); +inline PyObject *get_array(const std::vector &strings) { + PyObject *list = PyList_New(strings.size()); for (std::size_t i = 0; i < strings.size(); ++i) { PyList_SetItem(list, i, PyString_FromString(strings[i].c_str())); } @@ -416,10 +437,9 @@ inline PyObject * get_array(const std::vector& strings) } // not all matplotlib need 2d arrays, some prefer lists of lists -template -PyObject* get_listlist(const std::vector>& ll) -{ - PyObject* listlist = PyList_New(ll.size()); +template +PyObject *get_listlist(const std::vector> &ll) { + PyObject *listlist = PyList_New(ll.size()); for (std::size_t i = 0; i < ll.size(); ++i) { PyList_SetItem(listlist, i, get_array(ll[i])); } @@ -431,36 +451,39 @@ PyObject* get_listlist(const std::vector>& ll) /// Plot a line through the given x and y data points.. /// /// See: https://matplotlib.org/3.2.1/api/_as_gen/matplotlib.pyplot.plot.html -template -bool plot(const std::vector &x, const std::vector &y, const std::map& keywords) -{ - assert(x.size() == y.size()); +template +bool plot(const std::vector &x, const std::vector &y, + const std::map &keywords) { + assert(x.size() == y.size()); - detail::_interpreter::get(); + detail::_interpreter::get(); - // using numpy arrays - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); + // using numpy arrays + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); - // construct positional args - PyObject* args = PyTuple_New(2); - PyTuple_SetItem(args, 0, xarray); - PyTuple_SetItem(args, 1, yarray); - - // construct keyword args - PyObject* kwargs = PyDict_New(); - for(std::map::const_iterator it = keywords.begin(); it != keywords.end(); ++it) - { - PyDict_SetItemString(kwargs, it->first.c_str(), PyString_FromString(it->second.c_str())); - } + // construct positional args + PyObject *args = PyTuple_New(2); + PyTuple_SetItem(args, 0, xarray); + PyTuple_SetItem(args, 1, yarray); - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_plot, args, kwargs); + // construct keyword args + PyObject *kwargs = PyDict_New(); + for (std::map::const_iterator it = keywords.begin(); + it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyString_FromString(it->second.c_str())); + } - Py_DECREF(args); - Py_DECREF(kwargs); - if(res) Py_DECREF(res); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_plot, args, kwargs); - return res; + Py_DECREF(args); + Py_DECREF(kwargs); + if (res) + Py_DECREF(res); + + return res; } // TODO - it should be possible to make this work by implementing @@ -472,8 +495,7 @@ void plot_surface(const std::vector<::std::vector> &x, const std::vector<::std::vector> &z, const std::map &keywords = std::map(), - const long fig_number=0) -{ + const long fig_number = 0) { detail::_interpreter::get(); // We lazily load the modules here the first time this function is called @@ -484,17 +506,23 @@ void plot_surface(const std::vector<::std::vector> &x, if (!mpl_toolkitsmod) { detail::_interpreter::get(); - PyObject* mpl_toolkits = PyString_FromString("mpl_toolkits"); - PyObject* axis3d = PyString_FromString("mpl_toolkits.mplot3d"); - if (!mpl_toolkits || !axis3d) { throw std::runtime_error("couldnt create string"); } + PyObject *mpl_toolkits = PyString_FromString("mpl_toolkits"); + PyObject *axis3d = PyString_FromString("mpl_toolkits.mplot3d"); + if (!mpl_toolkits || !axis3d) { + throw std::runtime_error("couldnt create string"); + } mpl_toolkitsmod = PyImport_Import(mpl_toolkits); Py_DECREF(mpl_toolkits); - if (!mpl_toolkitsmod) { throw std::runtime_error("Error loading module mpl_toolkits!"); } + if (!mpl_toolkitsmod) { + throw std::runtime_error("Error loading module mpl_toolkits!"); + } axis3dmod = PyImport_Import(axis3d); Py_DECREF(axis3d); - if (!axis3dmod) { throw std::runtime_error("Error loading module mpl_toolkits.mplot3d!"); } + if (!axis3dmod) { + throw std::runtime_error("Error loading module mpl_toolkits.mplot3d!"); + } } assert(x.size() == y.size()); @@ -525,63 +553,68 @@ void plot_surface(const std::vector<::std::vector> &x, it != keywords.end(); ++it) { if (it->first == "linewidth" || it->first == "alpha") { PyDict_SetItemString(kwargs, it->first.c_str(), - PyFloat_FromDouble(std::stod(it->second))); + PyFloat_FromDouble(std::stod(it->second))); } else { PyDict_SetItemString(kwargs, it->first.c_str(), - PyString_FromString(it->second.c_str())); + PyString_FromString(it->second.c_str())); } } PyObject *fig_args = PyTuple_New(1); - PyObject* fig = nullptr; + PyObject *fig = nullptr; PyTuple_SetItem(fig_args, 0, PyLong_FromLong(fig_number)); - PyObject *fig_exists = - PyObject_CallObject( - detail::_interpreter::get().s_python_function_fignum_exists, fig_args); + PyObject *fig_exists = PyObject_CallObject( + detail::_interpreter::get().s_python_function_fignum_exists, fig_args); if (!PyObject_IsTrue(fig_exists)) { - fig = PyObject_CallObject(detail::_interpreter::get().s_python_function_figure, - detail::_interpreter::get().s_python_empty_tuple); + fig = PyObject_CallObject( + detail::_interpreter::get().s_python_function_figure, + detail::_interpreter::get().s_python_empty_tuple); } else { - fig = PyObject_CallObject(detail::_interpreter::get().s_python_function_figure, - fig_args); + fig = PyObject_CallObject( + detail::_interpreter::get().s_python_function_figure, fig_args); } Py_DECREF(fig_exists); - if (!fig) throw std::runtime_error("Call to figure() failed."); + if (!fig) + throw std::runtime_error("Call to figure() failed."); PyObject *gca_kwargs = PyDict_New(); PyDict_SetItemString(gca_kwargs, "projection", PyString_FromString("3d")); PyObject *gca = PyObject_GetAttrString(fig, "gca"); - if (!gca) throw std::runtime_error("No gca"); + if (!gca) + throw std::runtime_error("No gca"); Py_INCREF(gca); PyObject *axis = PyObject_Call( gca, detail::_interpreter::get().s_python_empty_tuple, gca_kwargs); - if (!axis) throw std::runtime_error("No axis"); + if (!axis) + throw std::runtime_error("No axis"); Py_INCREF(axis); Py_DECREF(gca); Py_DECREF(gca_kwargs); PyObject *plot_surface = PyObject_GetAttrString(axis, "plot_surface"); - if (!plot_surface) throw std::runtime_error("No surface"); + if (!plot_surface) + throw std::runtime_error("No surface"); Py_INCREF(plot_surface); PyObject *res = PyObject_Call(plot_surface, args, kwargs); - if (!res) throw std::runtime_error("failed surface"); + if (!res) + throw std::runtime_error("failed surface"); Py_DECREF(plot_surface); Py_DECREF(axis); Py_DECREF(args); Py_DECREF(kwargs); - if (res) Py_DECREF(res); + if (res) + Py_DECREF(res); } template void contour(const std::vector<::std::vector> &x, const std::vector<::std::vector> &y, const std::vector<::std::vector> &z, - const std::map &keywords = {}) -{ + const std::map &keywords = {}) { detail::_interpreter::get(); // using numpy arrays @@ -609,20 +642,21 @@ void contour(const std::vector<::std::vector> &x, PyString_FromString(it->second.c_str())); } - PyObject *res = PyObject_Call(detail::_interpreter::get().s_python_function_contour, args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_contour, args, kwargs); if (!res) throw std::runtime_error("failed contour"); Py_DECREF(args); Py_DECREF(kwargs); - if (res) Py_DECREF(res); + if (res) + Py_DECREF(res); } template void spy(const std::vector<::std::vector> &x, - const double markersize = -1, // -1 for default matplotlib size - const std::map &keywords = {}) -{ + const double markersize = -1, // -1 for default matplotlib size + const std::map &keywords = {}) { detail::_interpreter::get(); PyObject *xarray = detail::get_2darray(x); @@ -645,18 +679,17 @@ void spy(const std::vector<::std::vector> &x, Py_DECREF(plot_args); Py_DECREF(kwargs); - if (res) Py_DECREF(res); + if (res) + Py_DECREF(res); } #endif // WITHOUT_NUMPY template -void plot3(const std::vector &x, - const std::vector &y, - const std::vector &z, - const std::map &keywords = - std::map(), - const long fig_number=0) -{ +void plot3(const std::vector &x, const std::vector &y, + const std::vector &z, + const std::map &keywords = + std::map(), + const long fig_number = 0) { detail::_interpreter::get(); // Same as with plot_surface: We lazily load the modules here the first time @@ -667,17 +700,23 @@ void plot3(const std::vector &x, if (!mpl_toolkitsmod) { detail::_interpreter::get(); - PyObject* mpl_toolkits = PyString_FromString("mpl_toolkits"); - PyObject* axis3d = PyString_FromString("mpl_toolkits.mplot3d"); - if (!mpl_toolkits || !axis3d) { throw std::runtime_error("couldnt create string"); } + PyObject *mpl_toolkits = PyString_FromString("mpl_toolkits"); + PyObject *axis3d = PyString_FromString("mpl_toolkits.mplot3d"); + if (!mpl_toolkits || !axis3d) { + throw std::runtime_error("couldnt create string"); + } mpl_toolkitsmod = PyImport_Import(mpl_toolkits); Py_DECREF(mpl_toolkits); - if (!mpl_toolkitsmod) { throw std::runtime_error("Error loading module mpl_toolkits!"); } + if (!mpl_toolkitsmod) { + throw std::runtime_error("Error loading module mpl_toolkits!"); + } axis3dmod = PyImport_Import(axis3d); Py_DECREF(axis3d); - if (!axis3dmod) { throw std::runtime_error("Error loading module mpl_toolkits.mplot3d!"); } + if (!axis3dmod) { + throw std::runtime_error("Error loading module mpl_toolkits.mplot3d!"); + } } assert(x.size() == y.size()); @@ -703,384 +742,415 @@ void plot3(const std::vector &x, } PyObject *fig_args = PyTuple_New(1); - PyObject* fig = nullptr; + PyObject *fig = nullptr; PyTuple_SetItem(fig_args, 0, PyLong_FromLong(fig_number)); - PyObject *fig_exists = - PyObject_CallObject(detail::_interpreter::get().s_python_function_fignum_exists, fig_args); + PyObject *fig_exists = PyObject_CallObject( + detail::_interpreter::get().s_python_function_fignum_exists, fig_args); if (!PyObject_IsTrue(fig_exists)) { - fig = PyObject_CallObject(detail::_interpreter::get().s_python_function_figure, - detail::_interpreter::get().s_python_empty_tuple); + fig = PyObject_CallObject( + detail::_interpreter::get().s_python_function_figure, + detail::_interpreter::get().s_python_empty_tuple); } else { - fig = PyObject_CallObject(detail::_interpreter::get().s_python_function_figure, - fig_args); + fig = PyObject_CallObject( + detail::_interpreter::get().s_python_function_figure, fig_args); } - if (!fig) throw std::runtime_error("Call to figure() failed."); + if (!fig) + throw std::runtime_error("Call to figure() failed."); PyObject *gca_kwargs = PyDict_New(); PyDict_SetItemString(gca_kwargs, "projection", PyString_FromString("3d")); PyObject *gca = PyObject_GetAttrString(fig, "gca"); - if (!gca) throw std::runtime_error("No gca"); + if (!gca) + throw std::runtime_error("No gca"); Py_INCREF(gca); PyObject *axis = PyObject_Call( gca, detail::_interpreter::get().s_python_empty_tuple, gca_kwargs); - if (!axis) throw std::runtime_error("No axis"); + if (!axis) + throw std::runtime_error("No axis"); Py_INCREF(axis); Py_DECREF(gca); Py_DECREF(gca_kwargs); PyObject *plot3 = PyObject_GetAttrString(axis, "plot"); - if (!plot3) throw std::runtime_error("No 3D line plot"); + if (!plot3) + throw std::runtime_error("No 3D line plot"); Py_INCREF(plot3); PyObject *res = PyObject_Call(plot3, args, kwargs); - if (!res) throw std::runtime_error("Failed 3D line plot"); + if (!res) + throw std::runtime_error("Failed 3D line plot"); Py_DECREF(plot3); Py_DECREF(axis); Py_DECREF(args); Py_DECREF(kwargs); - if (res) Py_DECREF(res); + if (res) + Py_DECREF(res); } -template -bool stem(const std::vector &x, const std::vector &y, const std::map& keywords) -{ - assert(x.size() == y.size()); +template +bool stem(const std::vector &x, const std::vector &y, + const std::map &keywords) { + assert(x.size() == y.size()); - detail::_interpreter::get(); + detail::_interpreter::get(); - // using numpy arrays - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); + // using numpy arrays + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); - // construct positional args - PyObject* args = PyTuple_New(2); - PyTuple_SetItem(args, 0, xarray); - PyTuple_SetItem(args, 1, yarray); - - // construct keyword args - PyObject* kwargs = PyDict_New(); - for (std::map::const_iterator it = - keywords.begin(); it != keywords.end(); ++it) { - PyDict_SetItemString(kwargs, it->first.c_str(), - PyString_FromString(it->second.c_str())); - } + // construct positional args + PyObject *args = PyTuple_New(2); + PyTuple_SetItem(args, 0, xarray); + PyTuple_SetItem(args, 1, yarray); - PyObject* res = PyObject_Call( - detail::_interpreter::get().s_python_function_stem, args, kwargs); + // construct keyword args + PyObject *kwargs = PyDict_New(); + for (std::map::const_iterator it = keywords.begin(); + it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyString_FromString(it->second.c_str())); + } - Py_DECREF(args); - Py_DECREF(kwargs); - if (res) - Py_DECREF(res); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_stem, args, kwargs); - return res; + Py_DECREF(args); + Py_DECREF(kwargs); + if (res) + Py_DECREF(res); + + return res; } -template< typename Numeric > -bool fill(const std::vector& x, const std::vector& y, const std::map& keywords) -{ - assert(x.size() == y.size()); +template +bool fill(const std::vector &x, const std::vector &y, + const std::map &keywords) { + assert(x.size() == y.size()); - detail::_interpreter::get(); + detail::_interpreter::get(); + + // using numpy arrays + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); - // using numpy arrays - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); + // construct positional args + PyObject *args = PyTuple_New(2); + PyTuple_SetItem(args, 0, xarray); + PyTuple_SetItem(args, 1, yarray); - // construct positional args - PyObject* args = PyTuple_New(2); - PyTuple_SetItem(args, 0, xarray); - PyTuple_SetItem(args, 1, yarray); - - // construct keyword args - PyObject* kwargs = PyDict_New(); - for (auto it = keywords.begin(); it != keywords.end(); ++it) { - PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str())); - } + // construct keyword args + PyObject *kwargs = PyDict_New(); + for (auto it = keywords.begin(); it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyUnicode_FromString(it->second.c_str())); + } - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_fill, args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_fill, args, kwargs); - Py_DECREF(args); - Py_DECREF(kwargs); + Py_DECREF(args); + Py_DECREF(kwargs); - if (res) Py_DECREF(res); + if (res) + Py_DECREF(res); - return res; + return res; } -template< typename Numeric > -bool fill_between(const std::vector& x, const std::vector& y1, const std::vector& y2, const std::map& keywords) -{ - assert(x.size() == y1.size()); - assert(x.size() == y2.size()); +template +bool fill_between(const std::vector &x, const std::vector &y1, + const std::vector &y2, + const std::map &keywords) { + assert(x.size() == y1.size()); + assert(x.size() == y2.size()); - detail::_interpreter::get(); + detail::_interpreter::get(); - // using numpy arrays - PyObject* xarray = detail::get_array(x); - PyObject* y1array = detail::get_array(y1); - PyObject* y2array = detail::get_array(y2); + // using numpy arrays + PyObject *xarray = detail::get_array(x); + PyObject *y1array = detail::get_array(y1); + PyObject *y2array = detail::get_array(y2); - // construct positional args - PyObject* args = PyTuple_New(3); - PyTuple_SetItem(args, 0, xarray); - PyTuple_SetItem(args, 1, y1array); - PyTuple_SetItem(args, 2, y2array); - - // construct keyword args - PyObject* kwargs = PyDict_New(); - for(std::map::const_iterator it = keywords.begin(); it != keywords.end(); ++it) { - PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str())); - } + // construct positional args + PyObject *args = PyTuple_New(3); + PyTuple_SetItem(args, 0, xarray); + PyTuple_SetItem(args, 1, y1array); + PyTuple_SetItem(args, 2, y2array); + + // construct keyword args + PyObject *kwargs = PyDict_New(); + for (std::map::const_iterator it = keywords.begin(); + it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyUnicode_FromString(it->second.c_str())); + } - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_fill_between, args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_fill_between, args, kwargs); - Py_DECREF(args); - Py_DECREF(kwargs); - if(res) Py_DECREF(res); + Py_DECREF(args); + Py_DECREF(kwargs); + if (res) + Py_DECREF(res); - return res; + return res; } template -bool arrow(Numeric x, Numeric y, Numeric end_x, Numeric end_y, const std::string& fc = "r", - const std::string ec = "k", Numeric head_length = 0.25, Numeric head_width = 0.1625) { - PyObject* obj_x = PyFloat_FromDouble(x); - PyObject* obj_y = PyFloat_FromDouble(y); - PyObject* obj_end_x = PyFloat_FromDouble(end_x); - PyObject* obj_end_y = PyFloat_FromDouble(end_y); - - PyObject* kwargs = PyDict_New(); - PyDict_SetItemString(kwargs, "fc", PyString_FromString(fc.c_str())); - PyDict_SetItemString(kwargs, "ec", PyString_FromString(ec.c_str())); - PyDict_SetItemString(kwargs, "head_width", PyFloat_FromDouble(head_width)); - PyDict_SetItemString(kwargs, "head_length", PyFloat_FromDouble(head_length)); - - PyObject* plot_args = PyTuple_New(4); - PyTuple_SetItem(plot_args, 0, obj_x); - PyTuple_SetItem(plot_args, 1, obj_y); - PyTuple_SetItem(plot_args, 2, obj_end_x); - PyTuple_SetItem(plot_args, 3, obj_end_y); - - PyObject* res = - PyObject_Call(detail::_interpreter::get().s_python_function_arrow, plot_args, kwargs); +bool arrow(Numeric x, Numeric y, Numeric end_x, Numeric end_y, + const std::string &fc = "r", const std::string ec = "k", + Numeric head_length = 0.25, Numeric head_width = 0.1625) { + PyObject *obj_x = PyFloat_FromDouble(x); + PyObject *obj_y = PyFloat_FromDouble(y); + PyObject *obj_end_x = PyFloat_FromDouble(end_x); + PyObject *obj_end_y = PyFloat_FromDouble(end_y); - Py_DECREF(plot_args); - Py_DECREF(kwargs); - if (res) - Py_DECREF(res); + PyObject *kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "fc", PyString_FromString(fc.c_str())); + PyDict_SetItemString(kwargs, "ec", PyString_FromString(ec.c_str())); + PyDict_SetItemString(kwargs, "head_width", PyFloat_FromDouble(head_width)); + PyDict_SetItemString(kwargs, "head_length", PyFloat_FromDouble(head_length)); - return res; -} + PyObject *plot_args = PyTuple_New(4); + PyTuple_SetItem(plot_args, 0, obj_x); + PyTuple_SetItem(plot_args, 1, obj_y); + PyTuple_SetItem(plot_args, 2, obj_end_x); + PyTuple_SetItem(plot_args, 3, obj_end_y); -template< typename Numeric> -bool hist(const std::vector& y, long bins=10,std::string color="b", - double alpha=1.0, bool cumulative=false) -{ - detail::_interpreter::get(); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_arrow, plot_args, kwargs); + + Py_DECREF(plot_args); + Py_DECREF(kwargs); + if (res) + Py_DECREF(res); - PyObject* yarray = detail::get_array(y); + return res; +} - PyObject* kwargs = PyDict_New(); - PyDict_SetItemString(kwargs, "bins", PyLong_FromLong(bins)); - PyDict_SetItemString(kwargs, "color", PyString_FromString(color.c_str())); - PyDict_SetItemString(kwargs, "alpha", PyFloat_FromDouble(alpha)); - PyDict_SetItemString(kwargs, "cumulative", cumulative ? Py_True : Py_False); +template +bool hist(const std::vector &y, long bins = 10, + std::string color = "b", double alpha = 1.0, + bool cumulative = false) { + detail::_interpreter::get(); - PyObject* plot_args = PyTuple_New(1); + PyObject *yarray = detail::get_array(y); - PyTuple_SetItem(plot_args, 0, yarray); + PyObject *kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "bins", PyLong_FromLong(bins)); + PyDict_SetItemString(kwargs, "color", PyString_FromString(color.c_str())); + PyDict_SetItemString(kwargs, "alpha", PyFloat_FromDouble(alpha)); + PyDict_SetItemString(kwargs, "cumulative", cumulative ? Py_True : Py_False); + PyObject *plot_args = PyTuple_New(1); - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_hist, plot_args, kwargs); + PyTuple_SetItem(plot_args, 0, yarray); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_hist, plot_args, kwargs); - Py_DECREF(plot_args); - Py_DECREF(kwargs); - if(res) Py_DECREF(res); + Py_DECREF(plot_args); + Py_DECREF(kwargs); + if (res) + Py_DECREF(res); - return res; + return res; } #ifndef WITHOUT_NUMPY namespace detail { -inline void imshow(void *ptr, const NPY_TYPES type, const int rows, const int columns, const int colors, const std::map &keywords, PyObject** out) -{ - assert(type == NPY_UINT8 || type == NPY_FLOAT); - assert(colors == 1 || colors == 3 || colors == 4); +inline void imshow(void *ptr, const NPY_TYPES type, const int rows, + const int columns, const int colors, + const std::map &keywords, + PyObject **out) { + assert(type == NPY_UINT8 || type == NPY_FLOAT); + assert(colors == 1 || colors == 3 || colors == 4); - detail::_interpreter::get(); + detail::_interpreter::get(); - // construct args - npy_intp dims[3] = { rows, columns, colors }; - PyObject *args = PyTuple_New(1); - PyTuple_SetItem(args, 0, PyArray_SimpleNewFromData(colors == 1 ? 2 : 3, dims, type, ptr)); + // construct args + npy_intp dims[3] = {rows, columns, colors}; + PyObject *args = PyTuple_New(1); + PyTuple_SetItem( + args, 0, PyArray_SimpleNewFromData(colors == 1 ? 2 : 3, dims, type, ptr)); - // construct keyword args - PyObject* kwargs = PyDict_New(); - for(std::map::const_iterator it = keywords.begin(); it != keywords.end(); ++it) - { - PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str())); - } + // construct keyword args + PyObject *kwargs = PyDict_New(); + for (std::map::const_iterator it = keywords.begin(); + it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyUnicode_FromString(it->second.c_str())); + } - PyObject *res = PyObject_Call(detail::_interpreter::get().s_python_function_imshow, args, kwargs); - Py_DECREF(args); - Py_DECREF(kwargs); - if (!res) - throw std::runtime_error("Call to imshow() failed"); - if (out) - *out = res; - else - Py_DECREF(res); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_imshow, args, kwargs); + Py_DECREF(args); + Py_DECREF(kwargs); + if (!res) + throw std::runtime_error("Call to imshow() failed"); + if (out) + *out = res; + else + Py_DECREF(res); } } // namespace detail -inline void imshow(const unsigned char *ptr, const int rows, const int columns, const int colors, const std::map &keywords = {}, PyObject** out = nullptr) -{ - detail::imshow((void *) ptr, NPY_UINT8, rows, columns, colors, keywords, out); +inline void imshow(const unsigned char *ptr, const int rows, const int columns, + const int colors, + const std::map &keywords = {}, + PyObject **out = nullptr) { + detail::imshow((void *)ptr, NPY_UINT8, rows, columns, colors, keywords, out); } -inline void imshow(const float *ptr, const int rows, const int columns, const int colors, const std::map &keywords = {}, PyObject** out = nullptr) -{ - detail::imshow((void *) ptr, NPY_FLOAT, rows, columns, colors, keywords, out); +inline void imshow(const float *ptr, const int rows, const int columns, + const int colors, + const std::map &keywords = {}, + PyObject **out = nullptr) { + detail::imshow((void *)ptr, NPY_FLOAT, rows, columns, colors, keywords, out); } #ifdef WITH_OPENCV -void imshow(const cv::Mat &image, const std::map &keywords = {}) -{ - // Convert underlying type of matrix, if needed - cv::Mat image2; - NPY_TYPES npy_type = NPY_UINT8; - switch (image.type() & CV_MAT_DEPTH_MASK) { - case CV_8U: - image2 = image; - break; - case CV_32F: - image2 = image; - npy_type = NPY_FLOAT; - break; - default: - image.convertTo(image2, CV_MAKETYPE(CV_8U, image.channels())); - } +void imshow(const cv::Mat &image, + const std::map &keywords = {}) { + // Convert underlying type of matrix, if needed + cv::Mat image2; + NPY_TYPES npy_type = NPY_UINT8; + switch (image.type() & CV_MAT_DEPTH_MASK) { + case CV_8U: + image2 = image; + break; + case CV_32F: + image2 = image; + npy_type = NPY_FLOAT; + break; + default: + image.convertTo(image2, CV_MAKETYPE(CV_8U, image.channels())); + } - // If color image, convert from BGR to RGB - switch (image2.channels()) { - case 3: - cv::cvtColor(image2, image2, CV_BGR2RGB); - break; - case 4: - cv::cvtColor(image2, image2, CV_BGRA2RGBA); - } + // If color image, convert from BGR to RGB + switch (image2.channels()) { + case 3: + cv::cvtColor(image2, image2, CV_BGR2RGB); + break; + case 4: + cv::cvtColor(image2, image2, CV_BGRA2RGBA); + } - detail::imshow(image2.data, npy_type, image2.rows, image2.cols, image2.channels(), keywords); + detail::imshow(image2.data, npy_type, image2.rows, image2.cols, + image2.channels(), keywords); } #endif // WITH_OPENCV #endif // WITHOUT_NUMPY -template -bool scatter(const std::vector& x, - const std::vector& y, - const double s=1.0, // The marker size in points**2 - const std::map & keywords = {}) -{ - detail::_interpreter::get(); +template +bool scatter(const std::vector &x, const std::vector &y, + const double s = 1.0, // The marker size in points**2 + const std::map &keywords = {}) { + detail::_interpreter::get(); - assert(x.size() == y.size()); + assert(x.size() == y.size()); - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); - PyObject* kwargs = PyDict_New(); - PyDict_SetItemString(kwargs, "s", PyLong_FromLong(s)); - for (const auto& it : keywords) - { - PyDict_SetItemString(kwargs, it.first.c_str(), PyString_FromString(it.second.c_str())); - } + PyObject *kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "s", PyLong_FromLong(s)); + for (const auto &it : keywords) { + PyDict_SetItemString(kwargs, it.first.c_str(), + PyString_FromString(it.second.c_str())); + } - PyObject* plot_args = PyTuple_New(2); - PyTuple_SetItem(plot_args, 0, xarray); - PyTuple_SetItem(plot_args, 1, yarray); + PyObject *plot_args = PyTuple_New(2); + PyTuple_SetItem(plot_args, 0, xarray); + PyTuple_SetItem(plot_args, 1, yarray); - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_scatter, plot_args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_scatter, plot_args, kwargs); - Py_DECREF(plot_args); - Py_DECREF(kwargs); - if(res) Py_DECREF(res); + Py_DECREF(plot_args); + Py_DECREF(kwargs); + if (res) + Py_DECREF(res); - return res; + return res; } -template - bool scatter_colored(const std::vector& x, - const std::vector& y, - const std::vector& colors, - const double s=1.0, // The marker size in points**2 - const std::map & keywords = {}) - { - detail::_interpreter::get(); +template +bool scatter_colored(const std::vector &x, + const std::vector &y, + const std::vector &colors, + const double s = 1.0, // The marker size in points**2 + const std::map &keywords = {}) { + detail::_interpreter::get(); - assert(x.size() == y.size()); + assert(x.size() == y.size()); - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); - PyObject* colors_array = detail::get_array(colors); + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); + PyObject *colors_array = detail::get_array(colors); - PyObject* kwargs = PyDict_New(); - PyDict_SetItemString(kwargs, "s", PyLong_FromLong(s)); - PyDict_SetItemString(kwargs, "c", colors_array); + PyObject *kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "s", PyLong_FromLong(s)); + PyDict_SetItemString(kwargs, "c", colors_array); - for (const auto& it : keywords) - { - PyDict_SetItemString(kwargs, it.first.c_str(), PyString_FromString(it.second.c_str())); - } + for (const auto &it : keywords) { + PyDict_SetItemString(kwargs, it.first.c_str(), + PyString_FromString(it.second.c_str())); + } - PyObject* plot_args = PyTuple_New(2); - PyTuple_SetItem(plot_args, 0, xarray); - PyTuple_SetItem(plot_args, 1, yarray); + PyObject *plot_args = PyTuple_New(2); + PyTuple_SetItem(plot_args, 0, xarray); + PyTuple_SetItem(plot_args, 1, yarray); - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_scatter, plot_args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_scatter, plot_args, kwargs); - Py_DECREF(plot_args); - Py_DECREF(kwargs); - if(res) Py_DECREF(res); + Py_DECREF(plot_args); + Py_DECREF(kwargs); + if (res) + Py_DECREF(res); - return res; - } - + return res; +} -template -bool scatter(const std::vector& x, - const std::vector& y, - const std::vector& z, - const double s=1.0, // The marker size in points**2 - const std::map & keywords = {}, - const long fig_number=0) { +template +bool scatter(const std::vector &x, const std::vector &y, + const std::vector &z, + const double s = 1.0, // The marker size in points**2 + const std::map &keywords = {}, + const long fig_number = 0) { detail::_interpreter::get(); - // Same as with plot_surface: We lazily load the modules here the first time - // this function is called because I'm not sure that we can assume "matplotlib - // installed" implies "mpl_toolkits installed" on all platforms, and we don't + // Same as with plot_surface: We lazily load the modules here the first time + // this function is called because I'm not sure that we can assume "matplotlib + // installed" implies "mpl_toolkits installed" on all platforms, and we don't // want to require it for people who don't need 3d plots. static PyObject *mpl_toolkitsmod = nullptr, *axis3dmod = nullptr; if (!mpl_toolkitsmod) { detail::_interpreter::get(); - PyObject* mpl_toolkits = PyString_FromString("mpl_toolkits"); - PyObject* axis3d = PyString_FromString("mpl_toolkits.mplot3d"); - if (!mpl_toolkits || !axis3d) { throw std::runtime_error("couldnt create string"); } + PyObject *mpl_toolkits = PyString_FromString("mpl_toolkits"); + PyObject *axis3d = PyString_FromString("mpl_toolkits.mplot3d"); + if (!mpl_toolkits || !axis3d) { + throw std::runtime_error("couldnt create string"); + } mpl_toolkitsmod = PyImport_Import(mpl_toolkits); Py_DECREF(mpl_toolkits); - if (!mpl_toolkitsmod) { throw std::runtime_error("Error loading module mpl_toolkits!"); } + if (!mpl_toolkitsmod) { + throw std::runtime_error("Error loading module mpl_toolkits!"); + } axis3dmod = PyImport_Import(axis3d); Py_DECREF(axis3d); - if (!axis3dmod) { throw std::runtime_error("Error loading module mpl_toolkits.mplot3d!"); } + if (!axis3dmod) { + throw std::runtime_error("Error loading module mpl_toolkits.mplot3d!"); + } } assert(x.size() == y.size()); @@ -1105,377 +1175,402 @@ bool scatter(const std::vector& x, PyString_FromString(it->second.c_str())); } PyObject *fig_args = PyTuple_New(1); - PyObject* fig = nullptr; + PyObject *fig = nullptr; PyTuple_SetItem(fig_args, 0, PyLong_FromLong(fig_number)); - PyObject *fig_exists = - PyObject_CallObject(detail::_interpreter::get().s_python_function_fignum_exists, fig_args); + PyObject *fig_exists = PyObject_CallObject( + detail::_interpreter::get().s_python_function_fignum_exists, fig_args); if (!PyObject_IsTrue(fig_exists)) { - fig = PyObject_CallObject(detail::_interpreter::get().s_python_function_figure, - detail::_interpreter::get().s_python_empty_tuple); + fig = PyObject_CallObject( + detail::_interpreter::get().s_python_function_figure, + detail::_interpreter::get().s_python_empty_tuple); } else { - fig = PyObject_CallObject(detail::_interpreter::get().s_python_function_figure, - fig_args); + fig = PyObject_CallObject( + detail::_interpreter::get().s_python_function_figure, fig_args); } Py_DECREF(fig_exists); - if (!fig) throw std::runtime_error("Call to figure() failed."); + if (!fig) + throw std::runtime_error("Call to figure() failed."); PyObject *gca_kwargs = PyDict_New(); PyDict_SetItemString(gca_kwargs, "projection", PyString_FromString("3d")); PyObject *gca = PyObject_GetAttrString(fig, "gca"); - if (!gca) throw std::runtime_error("No gca"); + if (!gca) + throw std::runtime_error("No gca"); Py_INCREF(gca); PyObject *axis = PyObject_Call( gca, detail::_interpreter::get().s_python_empty_tuple, gca_kwargs); - if (!axis) throw std::runtime_error("No axis"); + if (!axis) + throw std::runtime_error("No axis"); Py_INCREF(axis); Py_DECREF(gca); Py_DECREF(gca_kwargs); PyObject *plot3 = PyObject_GetAttrString(axis, "scatter"); - if (!plot3) throw std::runtime_error("No 3D line plot"); + if (!plot3) + throw std::runtime_error("No 3D line plot"); Py_INCREF(plot3); PyObject *res = PyObject_Call(plot3, args, kwargs); - if (!res) throw std::runtime_error("Failed 3D line plot"); + if (!res) + throw std::runtime_error("Failed 3D line plot"); Py_DECREF(plot3); Py_DECREF(axis); Py_DECREF(args); Py_DECREF(kwargs); Py_DECREF(fig); - if (res) Py_DECREF(res); + if (res) + Py_DECREF(res); return res; - } -template -bool boxplot(const std::vector>& data, - const std::vector& labels = {}, - const std::map & keywords = {}) -{ - detail::_interpreter::get(); +template +bool boxplot(const std::vector> &data, + const std::vector &labels = {}, + const std::map &keywords = {}) { + detail::_interpreter::get(); - PyObject* listlist = detail::get_listlist(data); - PyObject* args = PyTuple_New(1); - PyTuple_SetItem(args, 0, listlist); + PyObject *listlist = detail::get_listlist(data); + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, listlist); - PyObject* kwargs = PyDict_New(); + PyObject *kwargs = PyDict_New(); - // kwargs needs the labels, if there are (the correct number of) labels - if (!labels.empty() && labels.size() == data.size()) { - PyDict_SetItemString(kwargs, "labels", detail::get_array(labels)); - } + // kwargs needs the labels, if there are (the correct number of) labels + if (!labels.empty() && labels.size() == data.size()) { + PyDict_SetItemString(kwargs, "labels", detail::get_array(labels)); + } - // take care of the remaining keywords - for (const auto& it : keywords) - { - PyDict_SetItemString(kwargs, it.first.c_str(), PyString_FromString(it.second.c_str())); - } + // take care of the remaining keywords + for (const auto &it : keywords) { + PyDict_SetItemString(kwargs, it.first.c_str(), + PyString_FromString(it.second.c_str())); + } - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_boxplot, args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_boxplot, args, kwargs); - Py_DECREF(args); - Py_DECREF(kwargs); + Py_DECREF(args); + Py_DECREF(kwargs); - if(res) Py_DECREF(res); + if (res) + Py_DECREF(res); - return res; + return res; } -template -bool boxplot(const std::vector& data, - const std::map & keywords = {}) -{ - detail::_interpreter::get(); +template +bool boxplot(const std::vector &data, + const std::map &keywords = {}) { + detail::_interpreter::get(); - PyObject* vector = detail::get_array(data); - PyObject* args = PyTuple_New(1); - PyTuple_SetItem(args, 0, vector); + PyObject *vector = detail::get_array(data); + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, vector); - PyObject* kwargs = PyDict_New(); - for (const auto& it : keywords) - { - PyDict_SetItemString(kwargs, it.first.c_str(), PyString_FromString(it.second.c_str())); - } + PyObject *kwargs = PyDict_New(); + for (const auto &it : keywords) { + PyDict_SetItemString(kwargs, it.first.c_str(), + PyString_FromString(it.second.c_str())); + } - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_boxplot, args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_boxplot, args, kwargs); - Py_DECREF(args); - Py_DECREF(kwargs); + Py_DECREF(args); + Py_DECREF(kwargs); - if(res) Py_DECREF(res); + if (res) + Py_DECREF(res); - return res; + return res; } template -bool bar(const std::vector & x, - const std::vector & y, - std::string ec = "black", - std::string ls = "-", - double lw = 1.0, - const std::map & keywords = {}) -{ +bool bar(const std::vector &x, const std::vector &y, + std::string ec = "black", std::string ls = "-", double lw = 1.0, + const std::map &keywords = {}) { detail::_interpreter::get(); - PyObject * xarray = detail::get_array(x); - PyObject * yarray = detail::get_array(y); + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); - PyObject * kwargs = PyDict_New(); + PyObject *kwargs = PyDict_New(); PyDict_SetItemString(kwargs, "ec", PyString_FromString(ec.c_str())); PyDict_SetItemString(kwargs, "ls", PyString_FromString(ls.c_str())); PyDict_SetItemString(kwargs, "lw", PyFloat_FromDouble(lw)); - for (std::map::const_iterator it = - keywords.begin(); - it != keywords.end(); - ++it) { - PyDict_SetItemString( - kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str())); + for (std::map::const_iterator it = keywords.begin(); + it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyUnicode_FromString(it->second.c_str())); } - PyObject * plot_args = PyTuple_New(2); + PyObject *plot_args = PyTuple_New(2); PyTuple_SetItem(plot_args, 0, xarray); PyTuple_SetItem(plot_args, 1, yarray); - PyObject * res = PyObject_Call( - detail::_interpreter::get().s_python_function_bar, plot_args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_bar, plot_args, kwargs); Py_DECREF(plot_args); Py_DECREF(kwargs); - if (res) Py_DECREF(res); + if (res) + Py_DECREF(res); return res; } template -bool bar(const std::vector & y, - std::string ec = "black", - std::string ls = "-", - double lw = 1.0, - const std::map & keywords = {}) -{ +bool bar(const std::vector &y, std::string ec = "black", + std::string ls = "-", double lw = 1.0, + const std::map &keywords = {}) { using T = typename std::remove_reference::type::value_type; detail::_interpreter::get(); std::vector x; - for (std::size_t i = 0; i < y.size(); i++) { x.push_back(i); } + for (std::size_t i = 0; i < y.size(); i++) { + x.push_back(i); + } return bar(x, y, ec, ls, lw, keywords); } +template +bool barh(const std::vector &x, const std::vector &y, + std::string ec = "black", std::string ls = "-", double lw = 1.0, + const std::map &keywords = {}) { + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); -template -bool barh(const std::vector &x, const std::vector &y, std::string ec = "black", std::string ls = "-", double lw = 1.0, const std::map &keywords = { }) { - PyObject *xarray = detail::get_array(x); - PyObject *yarray = detail::get_array(y); - - PyObject *kwargs = PyDict_New(); + PyObject *kwargs = PyDict_New(); - PyDict_SetItemString(kwargs, "ec", PyString_FromString(ec.c_str())); - PyDict_SetItemString(kwargs, "ls", PyString_FromString(ls.c_str())); - PyDict_SetItemString(kwargs, "lw", PyFloat_FromDouble(lw)); + PyDict_SetItemString(kwargs, "ec", PyString_FromString(ec.c_str())); + PyDict_SetItemString(kwargs, "ls", PyString_FromString(ls.c_str())); + PyDict_SetItemString(kwargs, "lw", PyFloat_FromDouble(lw)); - for (std::map::const_iterator it = keywords.begin(); it != keywords.end(); ++it) { - PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str())); - } + for (std::map::const_iterator it = keywords.begin(); + it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyUnicode_FromString(it->second.c_str())); + } - PyObject *plot_args = PyTuple_New(2); - PyTuple_SetItem(plot_args, 0, xarray); - PyTuple_SetItem(plot_args, 1, yarray); + PyObject *plot_args = PyTuple_New(2); + PyTuple_SetItem(plot_args, 0, xarray); + PyTuple_SetItem(plot_args, 1, yarray); - PyObject *res = PyObject_Call(detail::_interpreter::get().s_python_function_barh, plot_args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_barh, plot_args, kwargs); - Py_DECREF(plot_args); - Py_DECREF(kwargs); - if (res) Py_DECREF(res); + Py_DECREF(plot_args); + Py_DECREF(kwargs); + if (res) + Py_DECREF(res); - return res; + return res; } +inline bool +subplots_adjust(const std::map &keywords = {}) { + detail::_interpreter::get(); -inline bool subplots_adjust(const std::map& keywords = {}) -{ - detail::_interpreter::get(); - - PyObject* kwargs = PyDict_New(); - for (std::map::const_iterator it = - keywords.begin(); it != keywords.end(); ++it) { - PyDict_SetItemString(kwargs, it->first.c_str(), - PyFloat_FromDouble(it->second)); - } - + PyObject *kwargs = PyDict_New(); + for (std::map::const_iterator it = keywords.begin(); + it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyFloat_FromDouble(it->second)); + } - PyObject* plot_args = PyTuple_New(0); + PyObject *plot_args = PyTuple_New(0); - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_subplots_adjust, plot_args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_subplots_adjust, plot_args, + kwargs); - Py_DECREF(plot_args); - Py_DECREF(kwargs); - if(res) Py_DECREF(res); + Py_DECREF(plot_args); + Py_DECREF(kwargs); + if (res) + Py_DECREF(res); - return res; + return res; } -template< typename Numeric> -bool named_hist(std::string label,const std::vector& y, long bins=10, std::string color="b", double alpha=1.0) -{ - detail::_interpreter::get(); - - PyObject* yarray = detail::get_array(y); +template +bool named_hist(std::string label, const std::vector &y, + long bins = 10, std::string color = "b", double alpha = 1.0) { + detail::_interpreter::get(); - PyObject* kwargs = PyDict_New(); - PyDict_SetItemString(kwargs, "label", PyString_FromString(label.c_str())); - PyDict_SetItemString(kwargs, "bins", PyLong_FromLong(bins)); - PyDict_SetItemString(kwargs, "color", PyString_FromString(color.c_str())); - PyDict_SetItemString(kwargs, "alpha", PyFloat_FromDouble(alpha)); + PyObject *yarray = detail::get_array(y); + PyObject *kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "label", PyString_FromString(label.c_str())); + PyDict_SetItemString(kwargs, "bins", PyLong_FromLong(bins)); + PyDict_SetItemString(kwargs, "color", PyString_FromString(color.c_str())); + PyDict_SetItemString(kwargs, "alpha", PyFloat_FromDouble(alpha)); - PyObject* plot_args = PyTuple_New(1); - PyTuple_SetItem(plot_args, 0, yarray); + PyObject *plot_args = PyTuple_New(1); + PyTuple_SetItem(plot_args, 0, yarray); - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_hist, plot_args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_hist, plot_args, kwargs); - Py_DECREF(plot_args); - Py_DECREF(kwargs); - if(res) Py_DECREF(res); + Py_DECREF(plot_args); + Py_DECREF(kwargs); + if (res) + Py_DECREF(res); - return res; + return res; } -template -bool plot(const std::vector& x, const std::vector& y, const std::string& s = "") -{ - assert(x.size() == y.size()); +template +bool plot(const std::vector &x, const std::vector &y, + const std::string &s = "") { + assert(x.size() == y.size()); - detail::_interpreter::get(); + detail::_interpreter::get(); - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); - PyObject* pystring = PyString_FromString(s.c_str()); + PyObject *pystring = PyString_FromString(s.c_str()); - PyObject* plot_args = PyTuple_New(3); - PyTuple_SetItem(plot_args, 0, xarray); - PyTuple_SetItem(plot_args, 1, yarray); - PyTuple_SetItem(plot_args, 2, pystring); + PyObject *plot_args = PyTuple_New(3); + PyTuple_SetItem(plot_args, 0, xarray); + PyTuple_SetItem(plot_args, 1, yarray); + PyTuple_SetItem(plot_args, 2, pystring); - PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_plot, plot_args); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_plot, plot_args); - Py_DECREF(plot_args); - if(res) Py_DECREF(res); + Py_DECREF(plot_args); + if (res) + Py_DECREF(res); - return res; + return res; } template -bool contour(const std::vector& x, const std::vector& y, - const std::vector& z, - const std::map& keywords = {}) { - assert(x.size() == y.size() && x.size() == z.size()); +bool contour(const std::vector &x, const std::vector &y, + const std::vector &z, + const std::map &keywords = {}) { + assert(x.size() == y.size() && x.size() == z.size()); - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); - PyObject* zarray = detail::get_array(z); + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); + PyObject *zarray = detail::get_array(z); - PyObject* plot_args = PyTuple_New(3); - PyTuple_SetItem(plot_args, 0, xarray); - PyTuple_SetItem(plot_args, 1, yarray); - PyTuple_SetItem(plot_args, 2, zarray); + PyObject *plot_args = PyTuple_New(3); + PyTuple_SetItem(plot_args, 0, xarray); + PyTuple_SetItem(plot_args, 1, yarray); + PyTuple_SetItem(plot_args, 2, zarray); - // construct keyword args - PyObject* kwargs = PyDict_New(); - for (std::map::const_iterator it = keywords.begin(); - it != keywords.end(); ++it) { - PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str())); - } + // construct keyword args + PyObject *kwargs = PyDict_New(); + for (std::map::const_iterator it = keywords.begin(); + it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyUnicode_FromString(it->second.c_str())); + } - PyObject* res = - PyObject_Call(detail::_interpreter::get().s_python_function_contour, plot_args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_contour, plot_args, kwargs); - Py_DECREF(kwargs); - Py_DECREF(plot_args); - if (res) - Py_DECREF(res); + Py_DECREF(kwargs); + Py_DECREF(plot_args); + if (res) + Py_DECREF(res); - return res; + return res; } -template -bool quiver(const std::vector& x, const std::vector& y, const std::vector& u, const std::vector& w, const std::map& keywords = {}) -{ - assert(x.size() == y.size() && x.size() == u.size() && u.size() == w.size()); +template +bool quiver(const std::vector &x, const std::vector &y, + const std::vector &u, const std::vector &w, + const std::map &keywords = {}) { + assert(x.size() == y.size() && x.size() == u.size() && u.size() == w.size()); - detail::_interpreter::get(); + detail::_interpreter::get(); + + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); + PyObject *uarray = detail::get_array(u); + PyObject *warray = detail::get_array(w); - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); - PyObject* uarray = detail::get_array(u); - PyObject* warray = detail::get_array(w); + PyObject *plot_args = PyTuple_New(4); + PyTuple_SetItem(plot_args, 0, xarray); + PyTuple_SetItem(plot_args, 1, yarray); + PyTuple_SetItem(plot_args, 2, uarray); + PyTuple_SetItem(plot_args, 3, warray); - PyObject* plot_args = PyTuple_New(4); - PyTuple_SetItem(plot_args, 0, xarray); - PyTuple_SetItem(plot_args, 1, yarray); - PyTuple_SetItem(plot_args, 2, uarray); - PyTuple_SetItem(plot_args, 3, warray); - - // construct keyword args - PyObject* kwargs = PyDict_New(); - for(std::map::const_iterator it = keywords.begin(); it != keywords.end(); ++it) - { - PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str())); - } + // construct keyword args + PyObject *kwargs = PyDict_New(); + for (std::map::const_iterator it = keywords.begin(); + it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyUnicode_FromString(it->second.c_str())); + } - PyObject* res = PyObject_Call( - detail::_interpreter::get().s_python_function_quiver, plot_args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_quiver, plot_args, kwargs); - Py_DECREF(kwargs); - Py_DECREF(plot_args); - if (res) - Py_DECREF(res); + Py_DECREF(kwargs); + Py_DECREF(plot_args); + if (res) + Py_DECREF(res); - return res; + return res; } -template -bool quiver(const std::vector& x, const std::vector& y, const std::vector& z, const std::vector& u, const std::vector& w, const std::vector& v, const std::map& keywords = {}) -{ - //set up 3d axes stuff +template +bool quiver(const std::vector &x, const std::vector &y, + const std::vector &z, const std::vector &u, + const std::vector &w, const std::vector &v, + const std::map &keywords = {}) { + // set up 3d axes stuff static PyObject *mpl_toolkitsmod = nullptr, *axis3dmod = nullptr; if (!mpl_toolkitsmod) { detail::_interpreter::get(); - PyObject* mpl_toolkits = PyString_FromString("mpl_toolkits"); - PyObject* axis3d = PyString_FromString("mpl_toolkits.mplot3d"); - if (!mpl_toolkits || !axis3d) { throw std::runtime_error("couldnt create string"); } + PyObject *mpl_toolkits = PyString_FromString("mpl_toolkits"); + PyObject *axis3d = PyString_FromString("mpl_toolkits.mplot3d"); + if (!mpl_toolkits || !axis3d) { + throw std::runtime_error("couldnt create string"); + } mpl_toolkitsmod = PyImport_Import(mpl_toolkits); Py_DECREF(mpl_toolkits); - if (!mpl_toolkitsmod) { throw std::runtime_error("Error loading module mpl_toolkits!"); } + if (!mpl_toolkitsmod) { + throw std::runtime_error("Error loading module mpl_toolkits!"); + } axis3dmod = PyImport_Import(axis3d); Py_DECREF(axis3d); - if (!axis3dmod) { throw std::runtime_error("Error loading module mpl_toolkits.mplot3d!"); } + if (!axis3dmod) { + throw std::runtime_error("Error loading module mpl_toolkits.mplot3d!"); + } } - - //assert sizes match up - assert(x.size() == y.size() && x.size() == u.size() && u.size() == w.size() && x.size() == z.size() && x.size() == v.size() && u.size() == v.size()); - //set up parameters + // assert sizes match up + assert(x.size() == y.size() && x.size() == u.size() && u.size() == w.size() && + x.size() == z.size() && x.size() == v.size() && u.size() == v.size()); + + // set up parameters detail::_interpreter::get(); - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); - PyObject* zarray = detail::get_array(z); - PyObject* uarray = detail::get_array(u); - PyObject* warray = detail::get_array(w); - PyObject* varray = detail::get_array(v); + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); + PyObject *zarray = detail::get_array(z); + PyObject *uarray = detail::get_array(u); + PyObject *warray = detail::get_array(w); + PyObject *varray = detail::get_array(v); - PyObject* plot_args = PyTuple_New(6); + PyObject *plot_args = PyTuple_New(6); PyTuple_SetItem(plot_args, 0, xarray); PyTuple_SetItem(plot_args, 1, yarray); PyTuple_SetItem(plot_args, 2, zarray); @@ -1484,1496 +1579,1601 @@ bool quiver(const std::vector& x, const std::vector& y, cons PyTuple_SetItem(plot_args, 5, varray); // construct keyword args - PyObject* kwargs = PyDict_New(); - for(std::map::const_iterator it = keywords.begin(); it != keywords.end(); ++it) - { - PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str())); + PyObject *kwargs = PyDict_New(); + for (std::map::const_iterator it = keywords.begin(); + it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyUnicode_FromString(it->second.c_str())); } - - //get figure gca to enable 3d projection + + // get figure gca to enable 3d projection PyObject *fig = PyObject_CallObject(detail::_interpreter::get().s_python_function_figure, detail::_interpreter::get().s_python_empty_tuple); - if (!fig) throw std::runtime_error("Call to figure() failed."); + if (!fig) + throw std::runtime_error("Call to figure() failed."); PyObject *gca_kwargs = PyDict_New(); PyDict_SetItemString(gca_kwargs, "projection", PyString_FromString("3d")); PyObject *gca = PyObject_GetAttrString(fig, "gca"); - if (!gca) throw std::runtime_error("No gca"); + if (!gca) + throw std::runtime_error("No gca"); Py_INCREF(gca); PyObject *axis = PyObject_Call( gca, detail::_interpreter::get().s_python_empty_tuple, gca_kwargs); - if (!axis) throw std::runtime_error("No axis"); + if (!axis) + throw std::runtime_error("No axis"); Py_INCREF(axis); Py_DECREF(gca); Py_DECREF(gca_kwargs); - - //plot our boys bravely, plot them strongly, plot them with a wink and clap + + // plot our boys bravely, plot them strongly, plot them with a wink and clap PyObject *plot3 = PyObject_GetAttrString(axis, "quiver"); - if (!plot3) throw std::runtime_error("No 3D line plot"); + if (!plot3) + throw std::runtime_error("No 3D line plot"); Py_INCREF(plot3); - PyObject* res = PyObject_Call( - plot3, plot_args, kwargs); - if (!res) throw std::runtime_error("Failed 3D plot"); + PyObject *res = PyObject_Call(plot3, plot_args, kwargs); + if (!res) + throw std::runtime_error("Failed 3D plot"); Py_DECREF(plot3); Py_DECREF(axis); Py_DECREF(kwargs); Py_DECREF(plot_args); if (res) - Py_DECREF(res); + Py_DECREF(res); return res; } -template -bool stem(const std::vector& x, const std::vector& y, const std::string& s = "") -{ - assert(x.size() == y.size()); +template +bool stem(const std::vector &x, const std::vector &y, + const std::string &s = "") { + assert(x.size() == y.size()); - detail::_interpreter::get(); + detail::_interpreter::get(); - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); - PyObject* pystring = PyString_FromString(s.c_str()); + PyObject *pystring = PyString_FromString(s.c_str()); - PyObject* plot_args = PyTuple_New(3); - PyTuple_SetItem(plot_args, 0, xarray); - PyTuple_SetItem(plot_args, 1, yarray); - PyTuple_SetItem(plot_args, 2, pystring); + PyObject *plot_args = PyTuple_New(3); + PyTuple_SetItem(plot_args, 0, xarray); + PyTuple_SetItem(plot_args, 1, yarray); + PyTuple_SetItem(plot_args, 2, pystring); - PyObject* res = PyObject_CallObject( - detail::_interpreter::get().s_python_function_stem, plot_args); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_stem, plot_args); - Py_DECREF(plot_args); - if (res) - Py_DECREF(res); + Py_DECREF(plot_args); + if (res) + Py_DECREF(res); - return res; + return res; } -template -bool semilogx(const std::vector& x, const std::vector& y, const std::string& s = "") -{ - assert(x.size() == y.size()); +template +bool semilogx(const std::vector &x, const std::vector &y, + const std::string &s = "") { + assert(x.size() == y.size()); - detail::_interpreter::get(); + detail::_interpreter::get(); - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); - PyObject* pystring = PyString_FromString(s.c_str()); + PyObject *pystring = PyString_FromString(s.c_str()); - PyObject* plot_args = PyTuple_New(3); - PyTuple_SetItem(plot_args, 0, xarray); - PyTuple_SetItem(plot_args, 1, yarray); - PyTuple_SetItem(plot_args, 2, pystring); + PyObject *plot_args = PyTuple_New(3); + PyTuple_SetItem(plot_args, 0, xarray); + PyTuple_SetItem(plot_args, 1, yarray); + PyTuple_SetItem(plot_args, 2, pystring); - PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_semilogx, plot_args); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_semilogx, plot_args); - Py_DECREF(plot_args); - if(res) Py_DECREF(res); + Py_DECREF(plot_args); + if (res) + Py_DECREF(res); - return res; + return res; } -template -bool semilogy(const std::vector& x, const std::vector& y, const std::string& s = "") -{ - assert(x.size() == y.size()); +template +bool semilogy(const std::vector &x, const std::vector &y, + const std::string &s = "") { + assert(x.size() == y.size()); - detail::_interpreter::get(); + detail::_interpreter::get(); - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); - PyObject* pystring = PyString_FromString(s.c_str()); + PyObject *pystring = PyString_FromString(s.c_str()); - PyObject* plot_args = PyTuple_New(3); - PyTuple_SetItem(plot_args, 0, xarray); - PyTuple_SetItem(plot_args, 1, yarray); - PyTuple_SetItem(plot_args, 2, pystring); + PyObject *plot_args = PyTuple_New(3); + PyTuple_SetItem(plot_args, 0, xarray); + PyTuple_SetItem(plot_args, 1, yarray); + PyTuple_SetItem(plot_args, 2, pystring); - PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_semilogy, plot_args); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_semilogy, plot_args); - Py_DECREF(plot_args); - if(res) Py_DECREF(res); + Py_DECREF(plot_args); + if (res) + Py_DECREF(res); - return res; + return res; } -template -bool loglog(const std::vector& x, const std::vector& y, const std::string& s = "") -{ - assert(x.size() == y.size()); +template +bool loglog(const std::vector &x, const std::vector &y, + const std::string &s = "") { + assert(x.size() == y.size()); - detail::_interpreter::get(); + detail::_interpreter::get(); - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); - PyObject* pystring = PyString_FromString(s.c_str()); + PyObject *pystring = PyString_FromString(s.c_str()); - PyObject* plot_args = PyTuple_New(3); - PyTuple_SetItem(plot_args, 0, xarray); - PyTuple_SetItem(plot_args, 1, yarray); - PyTuple_SetItem(plot_args, 2, pystring); + PyObject *plot_args = PyTuple_New(3); + PyTuple_SetItem(plot_args, 0, xarray); + PyTuple_SetItem(plot_args, 1, yarray); + PyTuple_SetItem(plot_args, 2, pystring); - PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_loglog, plot_args); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_loglog, plot_args); - Py_DECREF(plot_args); - if(res) Py_DECREF(res); + Py_DECREF(plot_args); + if (res) + Py_DECREF(res); - return res; + return res; } -template -bool errorbar(const std::vector &x, const std::vector &y, const std::vector &yerr, const std::map &keywords = {}) -{ - assert(x.size() == y.size()); +template +bool errorbar(const std::vector &x, const std::vector &y, + const std::vector &yerr, + const std::map &keywords = {}) { + assert(x.size() == y.size()); - detail::_interpreter::get(); + detail::_interpreter::get(); - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); - PyObject* yerrarray = detail::get_array(yerr); + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); + PyObject *yerrarray = detail::get_array(yerr); - // construct keyword args - PyObject* kwargs = PyDict_New(); - for(std::map::const_iterator it = keywords.begin(); it != keywords.end(); ++it) - { - PyDict_SetItemString(kwargs, it->first.c_str(), PyString_FromString(it->second.c_str())); - } + // construct keyword args + PyObject *kwargs = PyDict_New(); + for (std::map::const_iterator it = keywords.begin(); + it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyString_FromString(it->second.c_str())); + } - PyDict_SetItemString(kwargs, "yerr", yerrarray); + PyDict_SetItemString(kwargs, "yerr", yerrarray); - PyObject *plot_args = PyTuple_New(2); - PyTuple_SetItem(plot_args, 0, xarray); - PyTuple_SetItem(plot_args, 1, yarray); + PyObject *plot_args = PyTuple_New(2); + PyTuple_SetItem(plot_args, 0, xarray); + PyTuple_SetItem(plot_args, 1, yarray); - PyObject *res = PyObject_Call(detail::_interpreter::get().s_python_function_errorbar, plot_args, kwargs); + PyObject *res = + PyObject_Call(detail::_interpreter::get().s_python_function_errorbar, + plot_args, kwargs); - Py_DECREF(kwargs); - Py_DECREF(plot_args); + Py_DECREF(kwargs); + Py_DECREF(plot_args); - if (res) - Py_DECREF(res); - else - throw std::runtime_error("Call to errorbar() failed."); + if (res) + Py_DECREF(res); + else + throw std::runtime_error("Call to errorbar() failed."); - return res; + return res; } -template -bool named_plot(const std::string& name, const std::vector& y, const std::string& format = "") -{ - detail::_interpreter::get(); +template +bool named_plot(const std::string &name, const std::vector &y, + const std::string &format = "") { + detail::_interpreter::get(); - PyObject* kwargs = PyDict_New(); - PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); + PyObject *kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); - PyObject* yarray = detail::get_array(y); + PyObject *yarray = detail::get_array(y); - PyObject* pystring = PyString_FromString(format.c_str()); + PyObject *pystring = PyString_FromString(format.c_str()); - PyObject* plot_args = PyTuple_New(2); + PyObject *plot_args = PyTuple_New(2); - PyTuple_SetItem(plot_args, 0, yarray); - PyTuple_SetItem(plot_args, 1, pystring); + PyTuple_SetItem(plot_args, 0, yarray); + PyTuple_SetItem(plot_args, 1, pystring); - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_plot, plot_args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_plot, plot_args, kwargs); - Py_DECREF(kwargs); - Py_DECREF(plot_args); - if (res) Py_DECREF(res); + Py_DECREF(kwargs); + Py_DECREF(plot_args); + if (res) + Py_DECREF(res); - return res; + return res; } -template -bool named_plot(const std::string& name, const std::vector& x, const std::vector& y, const std::string& format = "") -{ - detail::_interpreter::get(); +template +bool named_plot(const std::string &name, const std::vector &x, + const std::vector &y, + const std::string &format = "") { + detail::_interpreter::get(); - PyObject* kwargs = PyDict_New(); - PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); + PyObject *kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); - PyObject* pystring = PyString_FromString(format.c_str()); + PyObject *pystring = PyString_FromString(format.c_str()); - PyObject* plot_args = PyTuple_New(3); - PyTuple_SetItem(plot_args, 0, xarray); - PyTuple_SetItem(plot_args, 1, yarray); - PyTuple_SetItem(plot_args, 2, pystring); + PyObject *plot_args = PyTuple_New(3); + PyTuple_SetItem(plot_args, 0, xarray); + PyTuple_SetItem(plot_args, 1, yarray); + PyTuple_SetItem(plot_args, 2, pystring); - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_plot, plot_args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_plot, plot_args, kwargs); - Py_DECREF(kwargs); - Py_DECREF(plot_args); - if (res) Py_DECREF(res); + Py_DECREF(kwargs); + Py_DECREF(plot_args); + if (res) + Py_DECREF(res); - return res; + return res; } -template -bool named_semilogx(const std::string& name, const std::vector& x, const std::vector& y, const std::string& format = "") -{ - detail::_interpreter::get(); +template +bool named_semilogx(const std::string &name, const std::vector &x, + const std::vector &y, + const std::string &format = "") { + detail::_interpreter::get(); - PyObject* kwargs = PyDict_New(); - PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); + PyObject *kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); - PyObject* pystring = PyString_FromString(format.c_str()); + PyObject *pystring = PyString_FromString(format.c_str()); - PyObject* plot_args = PyTuple_New(3); - PyTuple_SetItem(plot_args, 0, xarray); - PyTuple_SetItem(plot_args, 1, yarray); - PyTuple_SetItem(plot_args, 2, pystring); + PyObject *plot_args = PyTuple_New(3); + PyTuple_SetItem(plot_args, 0, xarray); + PyTuple_SetItem(plot_args, 1, yarray); + PyTuple_SetItem(plot_args, 2, pystring); - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_semilogx, plot_args, kwargs); + PyObject *res = + PyObject_Call(detail::_interpreter::get().s_python_function_semilogx, + plot_args, kwargs); - Py_DECREF(kwargs); - Py_DECREF(plot_args); - if (res) Py_DECREF(res); + Py_DECREF(kwargs); + Py_DECREF(plot_args); + if (res) + Py_DECREF(res); - return res; + return res; } -template -bool named_semilogy(const std::string& name, const std::vector& x, const std::vector& y, const std::string& format = "") -{ - detail::_interpreter::get(); +template +bool named_semilogy(const std::string &name, const std::vector &x, + const std::vector &y, + const std::string &format = "") { + detail::_interpreter::get(); - PyObject* kwargs = PyDict_New(); - PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); + PyObject *kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); - PyObject* pystring = PyString_FromString(format.c_str()); + PyObject *pystring = PyString_FromString(format.c_str()); - PyObject* plot_args = PyTuple_New(3); - PyTuple_SetItem(plot_args, 0, xarray); - PyTuple_SetItem(plot_args, 1, yarray); - PyTuple_SetItem(plot_args, 2, pystring); + PyObject *plot_args = PyTuple_New(3); + PyTuple_SetItem(plot_args, 0, xarray); + PyTuple_SetItem(plot_args, 1, yarray); + PyTuple_SetItem(plot_args, 2, pystring); - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_semilogy, plot_args, kwargs); + PyObject *res = + PyObject_Call(detail::_interpreter::get().s_python_function_semilogy, + plot_args, kwargs); - Py_DECREF(kwargs); - Py_DECREF(plot_args); - if (res) Py_DECREF(res); + Py_DECREF(kwargs); + Py_DECREF(plot_args); + if (res) + Py_DECREF(res); - return res; + return res; } -template -bool named_loglog(const std::string& name, const std::vector& x, const std::vector& y, const std::string& format = "") -{ - detail::_interpreter::get(); +template +bool named_loglog(const std::string &name, const std::vector &x, + const std::vector &y, + const std::string &format = "") { + detail::_interpreter::get(); - PyObject* kwargs = PyDict_New(); - PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); + PyObject *kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); - PyObject* pystring = PyString_FromString(format.c_str()); + PyObject *pystring = PyString_FromString(format.c_str()); - PyObject* plot_args = PyTuple_New(3); - PyTuple_SetItem(plot_args, 0, xarray); - PyTuple_SetItem(plot_args, 1, yarray); - PyTuple_SetItem(plot_args, 2, pystring); - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_loglog, plot_args, kwargs); + PyObject *plot_args = PyTuple_New(3); + PyTuple_SetItem(plot_args, 0, xarray); + PyTuple_SetItem(plot_args, 1, yarray); + PyTuple_SetItem(plot_args, 2, pystring); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_loglog, plot_args, kwargs); - Py_DECREF(kwargs); - Py_DECREF(plot_args); - if (res) Py_DECREF(res); + Py_DECREF(kwargs); + Py_DECREF(plot_args); + if (res) + Py_DECREF(res); - return res; + return res; } -template -bool plot(const std::vector& y, const std::string& format = "") -{ - std::vector x(y.size()); - for(size_t i=0; i +bool plot(const std::vector &y, const std::string &format = "") { + std::vector x(y.size()); + for (size_t i = 0; i < x.size(); ++i) + x.at(i) = i; + return plot(x, y, format); } -template -bool plot(const std::vector& y, const std::map& keywords) -{ - std::vector x(y.size()); - for(size_t i=0; i +bool plot(const std::vector &y, + const std::map &keywords) { + std::vector x(y.size()); + for (size_t i = 0; i < x.size(); ++i) + x.at(i) = i; + return plot(x, y, keywords); } -template -bool stem(const std::vector& y, const std::string& format = "") -{ - std::vector x(y.size()); - for (size_t i = 0; i < x.size(); ++i) x.at(i) = i; - return stem(x, y, format); +template +bool stem(const std::vector &y, const std::string &format = "") { + std::vector x(y.size()); + for (size_t i = 0; i < x.size(); ++i) + x.at(i) = i; + return stem(x, y, format); } -template -void text(Numeric x, Numeric y, const std::string& s = "") -{ - detail::_interpreter::get(); +template +void text(Numeric x, Numeric y, const std::string &s = "") { + detail::_interpreter::get(); - PyObject* args = PyTuple_New(3); - PyTuple_SetItem(args, 0, PyFloat_FromDouble(x)); - PyTuple_SetItem(args, 1, PyFloat_FromDouble(y)); - PyTuple_SetItem(args, 2, PyString_FromString(s.c_str())); + PyObject *args = PyTuple_New(3); + PyTuple_SetItem(args, 0, PyFloat_FromDouble(x)); + PyTuple_SetItem(args, 1, PyFloat_FromDouble(y)); + PyTuple_SetItem(args, 2, PyString_FromString(s.c_str())); - PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_text, args); - if(!res) throw std::runtime_error("Call to text() failed."); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_text, args); + if (!res) + throw std::runtime_error("Call to text() failed."); - Py_DECREF(args); - Py_DECREF(res); + Py_DECREF(args); + Py_DECREF(res); } -inline void colorbar(PyObject* mappable = NULL, const std::map& keywords = {}) -{ - if (mappable == NULL) - throw std::runtime_error("Must call colorbar with PyObject* returned from an image, contour, surface, etc."); +inline void colorbar(PyObject *mappable = NULL, + const std::map &keywords = {}) { + if (mappable == NULL) + throw std::runtime_error("Must call colorbar with PyObject* returned from " + "an image, contour, surface, etc."); - detail::_interpreter::get(); + detail::_interpreter::get(); - PyObject* args = PyTuple_New(1); - PyTuple_SetItem(args, 0, mappable); + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, mappable); - PyObject* kwargs = PyDict_New(); - for(std::map::const_iterator it = keywords.begin(); it != keywords.end(); ++it) - { - PyDict_SetItemString(kwargs, it->first.c_str(), PyFloat_FromDouble(it->second)); - } + PyObject *kwargs = PyDict_New(); + for (std::map::const_iterator it = keywords.begin(); + it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyFloat_FromDouble(it->second)); + } - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_colorbar, args, kwargs); - if(!res) throw std::runtime_error("Call to colorbar() failed."); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_colorbar, args, kwargs); + if (!res) + throw std::runtime_error("Call to colorbar() failed."); - Py_DECREF(args); - Py_DECREF(kwargs); - Py_DECREF(res); + Py_DECREF(args); + Py_DECREF(kwargs); + Py_DECREF(res); } +inline long figure(long number = -1) { + detail::_interpreter::get(); -inline long figure(long number = -1) -{ - detail::_interpreter::get(); - - PyObject *res; - if (number == -1) - res = PyObject_CallObject(detail::_interpreter::get().s_python_function_figure, detail::_interpreter::get().s_python_empty_tuple); - else { - assert(number > 0); + PyObject *res; + if (number == -1) + res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_figure, + detail::_interpreter::get().s_python_empty_tuple); + else { + assert(number > 0); - // Make sure interpreter is initialised - detail::_interpreter::get(); + // Make sure interpreter is initialised + detail::_interpreter::get(); - PyObject *args = PyTuple_New(1); - PyTuple_SetItem(args, 0, PyLong_FromLong(number)); - res = PyObject_CallObject(detail::_interpreter::get().s_python_function_figure, args); - Py_DECREF(args); - } + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, PyLong_FromLong(number)); + res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_figure, args); + Py_DECREF(args); + } - if(!res) throw std::runtime_error("Call to figure() failed."); + if (!res) + throw std::runtime_error("Call to figure() failed."); - PyObject* num = PyObject_GetAttrString(res, "number"); - if (!num) throw std::runtime_error("Could not get number attribute of figure object"); - const long figureNumber = PyLong_AsLong(num); + PyObject *num = PyObject_GetAttrString(res, "number"); + if (!num) + throw std::runtime_error("Could not get number attribute of figure object"); + const long figureNumber = PyLong_AsLong(num); - Py_DECREF(num); - Py_DECREF(res); + Py_DECREF(num); + Py_DECREF(res); - return figureNumber; + return figureNumber; } -inline bool fignum_exists(long number) -{ - detail::_interpreter::get(); +inline bool fignum_exists(long number) { + detail::_interpreter::get(); - PyObject *args = PyTuple_New(1); - PyTuple_SetItem(args, 0, PyLong_FromLong(number)); - PyObject *res = PyObject_CallObject(detail::_interpreter::get().s_python_function_fignum_exists, args); - if(!res) throw std::runtime_error("Call to fignum_exists() failed."); + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, PyLong_FromLong(number)); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_fignum_exists, args); + if (!res) + throw std::runtime_error("Call to fignum_exists() failed."); - bool ret = PyObject_IsTrue(res); - Py_DECREF(res); - Py_DECREF(args); + bool ret = PyObject_IsTrue(res); + Py_DECREF(res); + Py_DECREF(args); - return ret; + return ret; } -inline void figure_size(size_t w, size_t h) -{ - detail::_interpreter::get(); +inline void figure_size(size_t w, size_t h) { + detail::_interpreter::get(); - const size_t dpi = 100; - PyObject* size = PyTuple_New(2); - PyTuple_SetItem(size, 0, PyFloat_FromDouble((double)w / dpi)); - PyTuple_SetItem(size, 1, PyFloat_FromDouble((double)h / dpi)); + const size_t dpi = 100; + PyObject *size = PyTuple_New(2); + PyTuple_SetItem(size, 0, PyFloat_FromDouble((double)w / dpi)); + PyTuple_SetItem(size, 1, PyFloat_FromDouble((double)h / dpi)); - PyObject* kwargs = PyDict_New(); - PyDict_SetItemString(kwargs, "figsize", size); - PyDict_SetItemString(kwargs, "dpi", PyLong_FromSize_t(dpi)); + PyObject *kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "figsize", size); + PyDict_SetItemString(kwargs, "dpi", PyLong_FromSize_t(dpi)); - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_figure, - detail::_interpreter::get().s_python_empty_tuple, kwargs); + PyObject *res = + PyObject_Call(detail::_interpreter::get().s_python_function_figure, + detail::_interpreter::get().s_python_empty_tuple, kwargs); - Py_DECREF(kwargs); + Py_DECREF(kwargs); - if(!res) throw std::runtime_error("Call to figure_size() failed."); - Py_DECREF(res); + if (!res) + throw std::runtime_error("Call to figure_size() failed."); + Py_DECREF(res); } -inline void legend() -{ - detail::_interpreter::get(); +inline void legend() { + detail::_interpreter::get(); - PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_legend, detail::_interpreter::get().s_python_empty_tuple); - if(!res) throw std::runtime_error("Call to legend() failed."); + PyObject *res = + PyObject_CallObject(detail::_interpreter::get().s_python_function_legend, + detail::_interpreter::get().s_python_empty_tuple); + if (!res) + throw std::runtime_error("Call to legend() failed."); - Py_DECREF(res); + Py_DECREF(res); } -inline void legend(const std::map& keywords) -{ +inline void legend(const std::map &keywords) { detail::_interpreter::get(); // construct keyword args - PyObject* kwargs = PyDict_New(); - for(std::map::const_iterator it = keywords.begin(); it != keywords.end(); ++it) - { - PyDict_SetItemString(kwargs, it->first.c_str(), PyString_FromString(it->second.c_str())); + PyObject *kwargs = PyDict_New(); + for (std::map::const_iterator it = keywords.begin(); + it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyString_FromString(it->second.c_str())); } - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_legend, detail::_interpreter::get().s_python_empty_tuple, kwargs); - if(!res) throw std::runtime_error("Call to legend() failed."); + PyObject *res = + PyObject_Call(detail::_interpreter::get().s_python_function_legend, + detail::_interpreter::get().s_python_empty_tuple, kwargs); + if (!res) + throw std::runtime_error("Call to legend() failed."); Py_DECREF(kwargs); Py_DECREF(res); } -template -inline void set_aspect(Numeric ratio) -{ - detail::_interpreter::get(); +template inline void set_aspect(Numeric ratio) { + detail::_interpreter::get(); - PyObject* args = PyTuple_New(1); - PyTuple_SetItem(args, 0, PyFloat_FromDouble(ratio)); - PyObject* kwargs = PyDict_New(); + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, PyFloat_FromDouble(ratio)); + PyObject *kwargs = PyDict_New(); - PyObject *ax = - PyObject_CallObject(detail::_interpreter::get().s_python_function_gca, - detail::_interpreter::get().s_python_empty_tuple); - if (!ax) throw std::runtime_error("Call to gca() failed."); - Py_INCREF(ax); + PyObject *ax = + PyObject_CallObject(detail::_interpreter::get().s_python_function_gca, + detail::_interpreter::get().s_python_empty_tuple); + if (!ax) + throw std::runtime_error("Call to gca() failed."); + Py_INCREF(ax); - PyObject *set_aspect = PyObject_GetAttrString(ax, "set_aspect"); - if (!set_aspect) throw std::runtime_error("Attribute set_aspect not found."); - Py_INCREF(set_aspect); + PyObject *set_aspect = PyObject_GetAttrString(ax, "set_aspect"); + if (!set_aspect) + throw std::runtime_error("Attribute set_aspect not found."); + Py_INCREF(set_aspect); - PyObject *res = PyObject_Call(set_aspect, args, kwargs); - if (!res) throw std::runtime_error("Call to set_aspect() failed."); - Py_DECREF(set_aspect); + PyObject *res = PyObject_Call(set_aspect, args, kwargs); + if (!res) + throw std::runtime_error("Call to set_aspect() failed."); + Py_DECREF(set_aspect); - Py_DECREF(ax); - Py_DECREF(args); - Py_DECREF(kwargs); + Py_DECREF(ax); + Py_DECREF(args); + Py_DECREF(kwargs); } -inline void set_aspect_equal() -{ - // expect ratio == "equal". Leaving error handling to matplotlib. - detail::_interpreter::get(); +inline void set_aspect_equal() { + // expect ratio == "equal". Leaving error handling to matplotlib. + detail::_interpreter::get(); - PyObject* args = PyTuple_New(1); - PyTuple_SetItem(args, 0, PyString_FromString("equal")); - PyObject* kwargs = PyDict_New(); + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, PyString_FromString("equal")); + PyObject *kwargs = PyDict_New(); - PyObject *ax = - PyObject_CallObject(detail::_interpreter::get().s_python_function_gca, - detail::_interpreter::get().s_python_empty_tuple); - if (!ax) throw std::runtime_error("Call to gca() failed."); - Py_INCREF(ax); + PyObject *ax = + PyObject_CallObject(detail::_interpreter::get().s_python_function_gca, + detail::_interpreter::get().s_python_empty_tuple); + if (!ax) + throw std::runtime_error("Call to gca() failed."); + Py_INCREF(ax); - PyObject *set_aspect = PyObject_GetAttrString(ax, "set_aspect"); - if (!set_aspect) throw std::runtime_error("Attribute set_aspect not found."); - Py_INCREF(set_aspect); + PyObject *set_aspect = PyObject_GetAttrString(ax, "set_aspect"); + if (!set_aspect) + throw std::runtime_error("Attribute set_aspect not found."); + Py_INCREF(set_aspect); - PyObject *res = PyObject_Call(set_aspect, args, kwargs); - if (!res) throw std::runtime_error("Call to set_aspect() failed."); - Py_DECREF(set_aspect); + PyObject *res = PyObject_Call(set_aspect, args, kwargs); + if (!res) + throw std::runtime_error("Call to set_aspect() failed."); + Py_DECREF(set_aspect); - Py_DECREF(ax); - Py_DECREF(args); - Py_DECREF(kwargs); + Py_DECREF(ax); + Py_DECREF(args); + Py_DECREF(kwargs); } -template -void ylim(Numeric left, Numeric right) -{ - detail::_interpreter::get(); +template void ylim(Numeric left, Numeric right) { + detail::_interpreter::get(); - PyObject* list = PyList_New(2); - PyList_SetItem(list, 0, PyFloat_FromDouble(left)); - PyList_SetItem(list, 1, PyFloat_FromDouble(right)); + PyObject *list = PyList_New(2); + PyList_SetItem(list, 0, PyFloat_FromDouble(left)); + PyList_SetItem(list, 1, PyFloat_FromDouble(right)); - PyObject* args = PyTuple_New(1); - PyTuple_SetItem(args, 0, list); + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, list); - PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_ylim, args); - if(!res) throw std::runtime_error("Call to ylim() failed."); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_ylim, args); + if (!res) + throw std::runtime_error("Call to ylim() failed."); - Py_DECREF(args); - Py_DECREF(res); + Py_DECREF(args); + Py_DECREF(res); } -template -void xlim(Numeric left, Numeric right) -{ - detail::_interpreter::get(); +template void xlim(Numeric left, Numeric right) { + detail::_interpreter::get(); - PyObject* list = PyList_New(2); - PyList_SetItem(list, 0, PyFloat_FromDouble(left)); - PyList_SetItem(list, 1, PyFloat_FromDouble(right)); + PyObject *list = PyList_New(2); + PyList_SetItem(list, 0, PyFloat_FromDouble(left)); + PyList_SetItem(list, 1, PyFloat_FromDouble(right)); - PyObject* args = PyTuple_New(1); - PyTuple_SetItem(args, 0, list); + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, list); - PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_xlim, args); - if(!res) throw std::runtime_error("Call to xlim() failed."); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_xlim, args); + if (!res) + throw std::runtime_error("Call to xlim() failed."); - Py_DECREF(args); - Py_DECREF(res); + Py_DECREF(args); + Py_DECREF(res); } +inline std::array xlim() { + PyObject *args = PyTuple_New(0); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_xlim, args); -inline std::array xlim() -{ - PyObject* args = PyTuple_New(0); - PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_xlim, args); - - if(!res) throw std::runtime_error("Call to xlim() failed."); + if (!res) + throw std::runtime_error("Call to xlim() failed."); - Py_DECREF(res); + Py_DECREF(res); - PyObject* left = PyTuple_GetItem(res,0); - PyObject* right = PyTuple_GetItem(res,1); - return { PyFloat_AsDouble(left), PyFloat_AsDouble(right) }; + PyObject *left = PyTuple_GetItem(res, 0); + PyObject *right = PyTuple_GetItem(res, 1); + return {PyFloat_AsDouble(left), PyFloat_AsDouble(right)}; } +inline std::array ylim() { + PyObject *args = PyTuple_New(0); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_ylim, args); -inline std::array ylim() -{ - PyObject* args = PyTuple_New(0); - PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_ylim, args); - - if(!res) throw std::runtime_error("Call to ylim() failed."); + if (!res) + throw std::runtime_error("Call to ylim() failed."); - Py_DECREF(res); + Py_DECREF(res); - PyObject* left = PyTuple_GetItem(res,0); - PyObject* right = PyTuple_GetItem(res,1); - return { PyFloat_AsDouble(left), PyFloat_AsDouble(right) }; + PyObject *left = PyTuple_GetItem(res, 0); + PyObject *right = PyTuple_GetItem(res, 1); + return {PyFloat_AsDouble(left), PyFloat_AsDouble(right)}; } -template -inline void xticks(const std::vector &ticks, const std::vector &labels = {}, const std::map& keywords = {}) -{ - assert(labels.size() == 0 || ticks.size() == labels.size()); +template +inline void xticks(const std::vector &ticks, + const std::vector &labels = {}, + const std::map &keywords = {}) { + assert(labels.size() == 0 || ticks.size() == labels.size()); - detail::_interpreter::get(); + detail::_interpreter::get(); - // using numpy array - PyObject* ticksarray = detail::get_array(ticks); + // using numpy array + PyObject *ticksarray = detail::get_array(ticks); - PyObject* args; - if(labels.size() == 0) { - // construct positional args - args = PyTuple_New(1); - PyTuple_SetItem(args, 0, ticksarray); - } else { - // make tuple of tick labels - PyObject* labelstuple = PyTuple_New(labels.size()); - for (size_t i = 0; i < labels.size(); i++) - PyTuple_SetItem(labelstuple, i, PyUnicode_FromString(labels[i].c_str())); - - // construct positional args - args = PyTuple_New(2); - PyTuple_SetItem(args, 0, ticksarray); - PyTuple_SetItem(args, 1, labelstuple); - } + PyObject *args; + if (labels.size() == 0) { + // construct positional args + args = PyTuple_New(1); + PyTuple_SetItem(args, 0, ticksarray); + } else { + // make tuple of tick labels + PyObject *labelstuple = PyTuple_New(labels.size()); + for (size_t i = 0; i < labels.size(); i++) + PyTuple_SetItem(labelstuple, i, PyUnicode_FromString(labels[i].c_str())); - // construct keyword args - PyObject* kwargs = PyDict_New(); - for(std::map::const_iterator it = keywords.begin(); it != keywords.end(); ++it) - { - PyDict_SetItemString(kwargs, it->first.c_str(), PyString_FromString(it->second.c_str())); - } + // construct positional args + args = PyTuple_New(2); + PyTuple_SetItem(args, 0, ticksarray); + PyTuple_SetItem(args, 1, labelstuple); + } + + // construct keyword args + PyObject *kwargs = PyDict_New(); + for (std::map::const_iterator it = keywords.begin(); + it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyString_FromString(it->second.c_str())); + } - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_xticks, args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_xticks, args, kwargs); - Py_DECREF(args); - Py_DECREF(kwargs); - if(!res) throw std::runtime_error("Call to xticks() failed"); + Py_DECREF(args); + Py_DECREF(kwargs); + if (!res) + throw std::runtime_error("Call to xticks() failed"); - Py_DECREF(res); + Py_DECREF(res); } -template -inline void xticks(const std::vector &ticks, const std::map& keywords) -{ - xticks(ticks, {}, keywords); +template +inline void xticks(const std::vector &ticks, + const std::map &keywords) { + xticks(ticks, {}, keywords); } -template -inline void yticks(const std::vector &ticks, const std::vector &labels = {}, const std::map& keywords = {}) -{ - assert(labels.size() == 0 || ticks.size() == labels.size()); +template +inline void yticks(const std::vector &ticks, + const std::vector &labels = {}, + const std::map &keywords = {}) { + assert(labels.size() == 0 || ticks.size() == labels.size()); - detail::_interpreter::get(); + detail::_interpreter::get(); - // using numpy array - PyObject* ticksarray = detail::get_array(ticks); + // using numpy array + PyObject *ticksarray = detail::get_array(ticks); - PyObject* args; - if(labels.size() == 0) { - // construct positional args - args = PyTuple_New(1); - PyTuple_SetItem(args, 0, ticksarray); - } else { - // make tuple of tick labels - PyObject* labelstuple = PyTuple_New(labels.size()); - for (size_t i = 0; i < labels.size(); i++) - PyTuple_SetItem(labelstuple, i, PyUnicode_FromString(labels[i].c_str())); - - // construct positional args - args = PyTuple_New(2); - PyTuple_SetItem(args, 0, ticksarray); - PyTuple_SetItem(args, 1, labelstuple); - } + PyObject *args; + if (labels.size() == 0) { + // construct positional args + args = PyTuple_New(1); + PyTuple_SetItem(args, 0, ticksarray); + } else { + // make tuple of tick labels + PyObject *labelstuple = PyTuple_New(labels.size()); + for (size_t i = 0; i < labels.size(); i++) + PyTuple_SetItem(labelstuple, i, PyUnicode_FromString(labels[i].c_str())); - // construct keyword args - PyObject* kwargs = PyDict_New(); - for(std::map::const_iterator it = keywords.begin(); it != keywords.end(); ++it) - { - PyDict_SetItemString(kwargs, it->first.c_str(), PyString_FromString(it->second.c_str())); - } + // construct positional args + args = PyTuple_New(2); + PyTuple_SetItem(args, 0, ticksarray); + PyTuple_SetItem(args, 1, labelstuple); + } - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_yticks, args, kwargs); + // construct keyword args + PyObject *kwargs = PyDict_New(); + for (std::map::const_iterator it = keywords.begin(); + it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyString_FromString(it->second.c_str())); + } - Py_DECREF(args); - Py_DECREF(kwargs); - if(!res) throw std::runtime_error("Call to yticks() failed"); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_yticks, args, kwargs); - Py_DECREF(res); + Py_DECREF(args); + Py_DECREF(kwargs); + if (!res) + throw std::runtime_error("Call to yticks() failed"); + + Py_DECREF(res); } -template -inline void yticks(const std::vector &ticks, const std::map& keywords) -{ - yticks(ticks, {}, keywords); +template +inline void yticks(const std::vector &ticks, + const std::map &keywords) { + yticks(ticks, {}, keywords); } -template inline void margins(Numeric margin) -{ - // construct positional args - PyObject* args = PyTuple_New(1); - PyTuple_SetItem(args, 0, PyFloat_FromDouble(margin)); +template inline void margins(Numeric margin) { + // construct positional args + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, PyFloat_FromDouble(margin)); - PyObject* res = - PyObject_CallObject(detail::_interpreter::get().s_python_function_margins, args); - if (!res) - throw std::runtime_error("Call to margins() failed."); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_margins, args); + if (!res) + throw std::runtime_error("Call to margins() failed."); - Py_DECREF(args); - Py_DECREF(res); + Py_DECREF(args); + Py_DECREF(res); } -template inline void margins(Numeric margin_x, Numeric margin_y) -{ - // construct positional args - PyObject* args = PyTuple_New(2); - PyTuple_SetItem(args, 0, PyFloat_FromDouble(margin_x)); - PyTuple_SetItem(args, 1, PyFloat_FromDouble(margin_y)); +template +inline void margins(Numeric margin_x, Numeric margin_y) { + // construct positional args + PyObject *args = PyTuple_New(2); + PyTuple_SetItem(args, 0, PyFloat_FromDouble(margin_x)); + PyTuple_SetItem(args, 1, PyFloat_FromDouble(margin_y)); - PyObject* res = - PyObject_CallObject(detail::_interpreter::get().s_python_function_margins, args); - if (!res) - throw std::runtime_error("Call to margins() failed."); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_margins, args); + if (!res) + throw std::runtime_error("Call to margins() failed."); - Py_DECREF(args); - Py_DECREF(res); + Py_DECREF(args); + Py_DECREF(res); } - -inline void tick_params(const std::map& keywords, const std::string axis = "both") -{ +inline void tick_params(const std::map &keywords, + const std::string axis = "both") { detail::_interpreter::get(); // construct positional args - PyObject* args; + PyObject *args; args = PyTuple_New(1); PyTuple_SetItem(args, 0, PyString_FromString(axis.c_str())); // construct keyword args - PyObject* kwargs = PyDict_New(); - for (std::map::const_iterator it = keywords.begin(); it != keywords.end(); ++it) - { - PyDict_SetItemString(kwargs, it->first.c_str(), PyString_FromString(it->second.c_str())); + PyObject *kwargs = PyDict_New(); + for (std::map::const_iterator it = keywords.begin(); + it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyString_FromString(it->second.c_str())); } - - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_tick_params, args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_tick_params, args, kwargs); Py_DECREF(args); Py_DECREF(kwargs); - if (!res) throw std::runtime_error("Call to tick_params() failed"); + if (!res) + throw std::runtime_error("Call to tick_params() failed"); Py_DECREF(res); } -inline void subplot(long nrows, long ncols, long plot_number) -{ - detail::_interpreter::get(); +inline void subplot(long nrows, long ncols, long plot_number) { + detail::_interpreter::get(); - // construct positional args - PyObject* args = PyTuple_New(3); - PyTuple_SetItem(args, 0, PyFloat_FromDouble(nrows)); - PyTuple_SetItem(args, 1, PyFloat_FromDouble(ncols)); - PyTuple_SetItem(args, 2, PyFloat_FromDouble(plot_number)); + // construct positional args + PyObject *args = PyTuple_New(3); + PyTuple_SetItem(args, 0, PyFloat_FromDouble(nrows)); + PyTuple_SetItem(args, 1, PyFloat_FromDouble(ncols)); + PyTuple_SetItem(args, 2, PyFloat_FromDouble(plot_number)); - PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_subplot, args); - if(!res) throw std::runtime_error("Call to subplot() failed."); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_subplot, args); + if (!res) + throw std::runtime_error("Call to subplot() failed."); - Py_DECREF(args); - Py_DECREF(res); + Py_DECREF(args); + Py_DECREF(res); } -inline void subplot2grid(long nrows, long ncols, long rowid=0, long colid=0, long rowspan=1, long colspan=1) -{ - detail::_interpreter::get(); +inline void subplot2grid(long nrows, long ncols, long rowid = 0, long colid = 0, + long rowspan = 1, long colspan = 1) { + detail::_interpreter::get(); - PyObject* shape = PyTuple_New(2); - PyTuple_SetItem(shape, 0, PyLong_FromLong(nrows)); - PyTuple_SetItem(shape, 1, PyLong_FromLong(ncols)); + PyObject *shape = PyTuple_New(2); + PyTuple_SetItem(shape, 0, PyLong_FromLong(nrows)); + PyTuple_SetItem(shape, 1, PyLong_FromLong(ncols)); - PyObject* loc = PyTuple_New(2); - PyTuple_SetItem(loc, 0, PyLong_FromLong(rowid)); - PyTuple_SetItem(loc, 1, PyLong_FromLong(colid)); + PyObject *loc = PyTuple_New(2); + PyTuple_SetItem(loc, 0, PyLong_FromLong(rowid)); + PyTuple_SetItem(loc, 1, PyLong_FromLong(colid)); - PyObject* args = PyTuple_New(4); - PyTuple_SetItem(args, 0, shape); - PyTuple_SetItem(args, 1, loc); - PyTuple_SetItem(args, 2, PyLong_FromLong(rowspan)); - PyTuple_SetItem(args, 3, PyLong_FromLong(colspan)); + PyObject *args = PyTuple_New(4); + PyTuple_SetItem(args, 0, shape); + PyTuple_SetItem(args, 1, loc); + PyTuple_SetItem(args, 2, PyLong_FromLong(rowspan)); + PyTuple_SetItem(args, 3, PyLong_FromLong(colspan)); - PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_subplot2grid, args); - if(!res) throw std::runtime_error("Call to subplot2grid() failed."); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_subplot2grid, args); + if (!res) + throw std::runtime_error("Call to subplot2grid() failed."); - Py_DECREF(shape); - Py_DECREF(loc); - Py_DECREF(args); - Py_DECREF(res); + Py_DECREF(shape); + Py_DECREF(loc); + Py_DECREF(args); + Py_DECREF(res); } -inline void title(const std::string &titlestr, const std::map &keywords = {}) -{ - detail::_interpreter::get(); +inline void title(const std::string &titlestr, + const std::map &keywords = {}) { + detail::_interpreter::get(); - PyObject* pytitlestr = PyString_FromString(titlestr.c_str()); - PyObject* args = PyTuple_New(1); - PyTuple_SetItem(args, 0, pytitlestr); + PyObject *pytitlestr = PyString_FromString(titlestr.c_str()); + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, pytitlestr); - PyObject* kwargs = PyDict_New(); - for (auto it = keywords.begin(); it != keywords.end(); ++it) { - PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str())); - } + PyObject *kwargs = PyDict_New(); + for (auto it = keywords.begin(); it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyUnicode_FromString(it->second.c_str())); + } - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_title, args, kwargs); - if(!res) throw std::runtime_error("Call to title() failed."); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_title, args, kwargs); + if (!res) + throw std::runtime_error("Call to title() failed."); - Py_DECREF(args); - Py_DECREF(kwargs); - Py_DECREF(res); + Py_DECREF(args); + Py_DECREF(kwargs); + Py_DECREF(res); } -inline void suptitle(const std::string &suptitlestr, const std::map &keywords = {}) -{ - detail::_interpreter::get(); +inline void suptitle(const std::string &suptitlestr, + const std::map &keywords = {}) { + detail::_interpreter::get(); - PyObject* pysuptitlestr = PyString_FromString(suptitlestr.c_str()); - PyObject* args = PyTuple_New(1); - PyTuple_SetItem(args, 0, pysuptitlestr); + PyObject *pysuptitlestr = PyString_FromString(suptitlestr.c_str()); + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, pysuptitlestr); - PyObject* kwargs = PyDict_New(); - for (auto it = keywords.begin(); it != keywords.end(); ++it) { - PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str())); - } + PyObject *kwargs = PyDict_New(); + for (auto it = keywords.begin(); it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyUnicode_FromString(it->second.c_str())); + } - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_suptitle, args, kwargs); - if(!res) throw std::runtime_error("Call to suptitle() failed."); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_suptitle, args, kwargs); + if (!res) + throw std::runtime_error("Call to suptitle() failed."); - Py_DECREF(args); - Py_DECREF(kwargs); - Py_DECREF(res); + Py_DECREF(args); + Py_DECREF(kwargs); + Py_DECREF(res); } -inline void axis(const std::string &axisstr) -{ - detail::_interpreter::get(); +inline void axis(const std::string &axisstr) { + detail::_interpreter::get(); - PyObject* str = PyString_FromString(axisstr.c_str()); - PyObject* args = PyTuple_New(1); - PyTuple_SetItem(args, 0, str); + PyObject *str = PyString_FromString(axisstr.c_str()); + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, str); - PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_axis, args); - if(!res) throw std::runtime_error("Call to title() failed."); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_axis, args); + if (!res) + throw std::runtime_error("Call to title() failed."); - Py_DECREF(args); - Py_DECREF(res); + Py_DECREF(args); + Py_DECREF(res); } -inline void axhline(double y, double xmin = 0., double xmax = 1., const std::map& keywords = std::map()) -{ - detail::_interpreter::get(); +inline void axhline(double y, double xmin = 0., double xmax = 1., + const std::map &keywords = + std::map()) { + detail::_interpreter::get(); - // construct positional args - PyObject* args = PyTuple_New(3); - PyTuple_SetItem(args, 0, PyFloat_FromDouble(y)); - PyTuple_SetItem(args, 1, PyFloat_FromDouble(xmin)); - PyTuple_SetItem(args, 2, PyFloat_FromDouble(xmax)); - - // construct keyword args - PyObject* kwargs = PyDict_New(); - for(std::map::const_iterator it = keywords.begin(); it != keywords.end(); ++it) - { - PyDict_SetItemString(kwargs, it->first.c_str(), PyString_FromString(it->second.c_str())); - } + // construct positional args + PyObject *args = PyTuple_New(3); + PyTuple_SetItem(args, 0, PyFloat_FromDouble(y)); + PyTuple_SetItem(args, 1, PyFloat_FromDouble(xmin)); + PyTuple_SetItem(args, 2, PyFloat_FromDouble(xmax)); + + // construct keyword args + PyObject *kwargs = PyDict_New(); + for (std::map::const_iterator it = keywords.begin(); + it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyString_FromString(it->second.c_str())); + } - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_axhline, args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_axhline, args, kwargs); - Py_DECREF(args); - Py_DECREF(kwargs); + Py_DECREF(args); + Py_DECREF(kwargs); - if(res) Py_DECREF(res); + if (res) + Py_DECREF(res); } -inline void axvline(double x, double ymin = 0., double ymax = 1., const std::map& keywords = std::map()) -{ - detail::_interpreter::get(); +inline void axvline(double x, double ymin = 0., double ymax = 1., + const std::map &keywords = + std::map()) { + detail::_interpreter::get(); + + // construct positional args + PyObject *args = PyTuple_New(3); + PyTuple_SetItem(args, 0, PyFloat_FromDouble(x)); + PyTuple_SetItem(args, 1, PyFloat_FromDouble(ymin)); + PyTuple_SetItem(args, 2, PyFloat_FromDouble(ymax)); - // construct positional args - PyObject* args = PyTuple_New(3); - PyTuple_SetItem(args, 0, PyFloat_FromDouble(x)); - PyTuple_SetItem(args, 1, PyFloat_FromDouble(ymin)); - PyTuple_SetItem(args, 2, PyFloat_FromDouble(ymax)); - - // construct keyword args - PyObject* kwargs = PyDict_New(); - for(std::map::const_iterator it = keywords.begin(); it != keywords.end(); ++it) - { - PyDict_SetItemString(kwargs, it->first.c_str(), PyString_FromString(it->second.c_str())); - } + // construct keyword args + PyObject *kwargs = PyDict_New(); + for (std::map::const_iterator it = keywords.begin(); + it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyString_FromString(it->second.c_str())); + } - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_axvline, args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_axvline, args, kwargs); - Py_DECREF(args); - Py_DECREF(kwargs); + Py_DECREF(args); + Py_DECREF(kwargs); - if(res) Py_DECREF(res); + if (res) + Py_DECREF(res); } -inline void axvspan(double xmin, double xmax, double ymin = 0., double ymax = 1., const std::map& keywords = std::map()) -{ - // construct positional args - PyObject* args = PyTuple_New(4); - PyTuple_SetItem(args, 0, PyFloat_FromDouble(xmin)); - PyTuple_SetItem(args, 1, PyFloat_FromDouble(xmax)); - PyTuple_SetItem(args, 2, PyFloat_FromDouble(ymin)); - PyTuple_SetItem(args, 3, PyFloat_FromDouble(ymax)); - - // construct keyword args - PyObject* kwargs = PyDict_New(); - for (auto it = keywords.begin(); it != keywords.end(); ++it) { - if (it->first == "linewidth" || it->first == "alpha") { - PyDict_SetItemString(kwargs, it->first.c_str(), - PyFloat_FromDouble(std::stod(it->second))); - } else { - PyDict_SetItemString(kwargs, it->first.c_str(), - PyString_FromString(it->second.c_str())); - } +inline void axvspan(double xmin, double xmax, double ymin = 0., + double ymax = 1., + const std::map &keywords = + std::map()) { + // construct positional args + PyObject *args = PyTuple_New(4); + PyTuple_SetItem(args, 0, PyFloat_FromDouble(xmin)); + PyTuple_SetItem(args, 1, PyFloat_FromDouble(xmax)); + PyTuple_SetItem(args, 2, PyFloat_FromDouble(ymin)); + PyTuple_SetItem(args, 3, PyFloat_FromDouble(ymax)); + + // construct keyword args + PyObject *kwargs = PyDict_New(); + for (auto it = keywords.begin(); it != keywords.end(); ++it) { + if (it->first == "linewidth" || it->first == "alpha") { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyFloat_FromDouble(std::stod(it->second))); + } else { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyString_FromString(it->second.c_str())); } + } - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_axvspan, args, kwargs); - Py_DECREF(args); - Py_DECREF(kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_axvspan, args, kwargs); + Py_DECREF(args); + Py_DECREF(kwargs); - if(res) Py_DECREF(res); + if (res) + Py_DECREF(res); } -inline void xlabel(const std::string &str, const std::map &keywords = {}) -{ - detail::_interpreter::get(); +inline void xlabel(const std::string &str, + const std::map &keywords = {}) { + detail::_interpreter::get(); - PyObject* pystr = PyString_FromString(str.c_str()); - PyObject* args = PyTuple_New(1); - PyTuple_SetItem(args, 0, pystr); + PyObject *pystr = PyString_FromString(str.c_str()); + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, pystr); - PyObject* kwargs = PyDict_New(); - for (auto it = keywords.begin(); it != keywords.end(); ++it) { - PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str())); - } + PyObject *kwargs = PyDict_New(); + for (auto it = keywords.begin(); it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyUnicode_FromString(it->second.c_str())); + } - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_xlabel, args, kwargs); - if(!res) throw std::runtime_error("Call to xlabel() failed."); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_xlabel, args, kwargs); + if (!res) + throw std::runtime_error("Call to xlabel() failed."); - Py_DECREF(args); - Py_DECREF(kwargs); - Py_DECREF(res); + Py_DECREF(args); + Py_DECREF(kwargs); + Py_DECREF(res); } -inline void ylabel(const std::string &str, const std::map& keywords = {}) -{ - detail::_interpreter::get(); +inline void ylabel(const std::string &str, + const std::map &keywords = {}) { + detail::_interpreter::get(); - PyObject* pystr = PyString_FromString(str.c_str()); - PyObject* args = PyTuple_New(1); - PyTuple_SetItem(args, 0, pystr); + PyObject *pystr = PyString_FromString(str.c_str()); + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, pystr); - PyObject* kwargs = PyDict_New(); - for (auto it = keywords.begin(); it != keywords.end(); ++it) { - PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str())); - } + PyObject *kwargs = PyDict_New(); + for (auto it = keywords.begin(); it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyUnicode_FromString(it->second.c_str())); + } - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_ylabel, args, kwargs); - if(!res) throw std::runtime_error("Call to ylabel() failed."); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_ylabel, args, kwargs); + if (!res) + throw std::runtime_error("Call to ylabel() failed."); - Py_DECREF(args); - Py_DECREF(kwargs); - Py_DECREF(res); + Py_DECREF(args); + Py_DECREF(kwargs); + Py_DECREF(res); } -inline void set_zlabel(const std::string &str, const std::map& keywords = {}) -{ - detail::_interpreter::get(); +inline void +set_zlabel(const std::string &str, + const std::map &keywords = {}) { + detail::_interpreter::get(); - // Same as with plot_surface: We lazily load the modules here the first time - // this function is called because I'm not sure that we can assume "matplotlib - // installed" implies "mpl_toolkits installed" on all platforms, and we don't - // want to require it for people who don't need 3d plots. - static PyObject *mpl_toolkitsmod = nullptr, *axis3dmod = nullptr; - if (!mpl_toolkitsmod) { - PyObject* mpl_toolkits = PyString_FromString("mpl_toolkits"); - PyObject* axis3d = PyString_FromString("mpl_toolkits.mplot3d"); - if (!mpl_toolkits || !axis3d) { throw std::runtime_error("couldnt create string"); } + // Same as with plot_surface: We lazily load the modules here the first time + // this function is called because I'm not sure that we can assume "matplotlib + // installed" implies "mpl_toolkits installed" on all platforms, and we don't + // want to require it for people who don't need 3d plots. + static PyObject *mpl_toolkitsmod = nullptr, *axis3dmod = nullptr; + if (!mpl_toolkitsmod) { + PyObject *mpl_toolkits = PyString_FromString("mpl_toolkits"); + PyObject *axis3d = PyString_FromString("mpl_toolkits.mplot3d"); + if (!mpl_toolkits || !axis3d) { + throw std::runtime_error("couldnt create string"); + } - mpl_toolkitsmod = PyImport_Import(mpl_toolkits); - Py_DECREF(mpl_toolkits); - if (!mpl_toolkitsmod) { throw std::runtime_error("Error loading module mpl_toolkits!"); } + mpl_toolkitsmod = PyImport_Import(mpl_toolkits); + Py_DECREF(mpl_toolkits); + if (!mpl_toolkitsmod) { + throw std::runtime_error("Error loading module mpl_toolkits!"); + } - axis3dmod = PyImport_Import(axis3d); - Py_DECREF(axis3d); - if (!axis3dmod) { throw std::runtime_error("Error loading module mpl_toolkits.mplot3d!"); } + axis3dmod = PyImport_Import(axis3d); + Py_DECREF(axis3d); + if (!axis3dmod) { + throw std::runtime_error("Error loading module mpl_toolkits.mplot3d!"); } + } - PyObject* pystr = PyString_FromString(str.c_str()); - PyObject* args = PyTuple_New(1); - PyTuple_SetItem(args, 0, pystr); + PyObject *pystr = PyString_FromString(str.c_str()); + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, pystr); - PyObject* kwargs = PyDict_New(); - for (auto it = keywords.begin(); it != keywords.end(); ++it) { - PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str())); - } + PyObject *kwargs = PyDict_New(); + for (auto it = keywords.begin(); it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyUnicode_FromString(it->second.c_str())); + } - PyObject *ax = - PyObject_CallObject(detail::_interpreter::get().s_python_function_gca, - detail::_interpreter::get().s_python_empty_tuple); - if (!ax) throw std::runtime_error("Call to gca() failed."); - Py_INCREF(ax); + PyObject *ax = + PyObject_CallObject(detail::_interpreter::get().s_python_function_gca, + detail::_interpreter::get().s_python_empty_tuple); + if (!ax) + throw std::runtime_error("Call to gca() failed."); + Py_INCREF(ax); - PyObject *zlabel = PyObject_GetAttrString(ax, "set_zlabel"); - if (!zlabel) throw std::runtime_error("Attribute set_zlabel not found."); - Py_INCREF(zlabel); + PyObject *zlabel = PyObject_GetAttrString(ax, "set_zlabel"); + if (!zlabel) + throw std::runtime_error("Attribute set_zlabel not found."); + Py_INCREF(zlabel); - PyObject *res = PyObject_Call(zlabel, args, kwargs); - if (!res) throw std::runtime_error("Call to set_zlabel() failed."); - Py_DECREF(zlabel); + PyObject *res = PyObject_Call(zlabel, args, kwargs); + if (!res) + throw std::runtime_error("Call to set_zlabel() failed."); + Py_DECREF(zlabel); - Py_DECREF(ax); - Py_DECREF(args); - Py_DECREF(kwargs); - if (res) Py_DECREF(res); + Py_DECREF(ax); + Py_DECREF(args); + Py_DECREF(kwargs); + if (res) + Py_DECREF(res); } -inline void grid(bool flag) -{ - detail::_interpreter::get(); +inline void grid(bool flag) { + detail::_interpreter::get(); - PyObject* pyflag = flag ? Py_True : Py_False; - Py_INCREF(pyflag); + PyObject *pyflag = flag ? Py_True : Py_False; + Py_INCREF(pyflag); - PyObject* args = PyTuple_New(1); - PyTuple_SetItem(args, 0, pyflag); + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, pyflag); - PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_grid, args); - if(!res) throw std::runtime_error("Call to grid() failed."); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_grid, args); + if (!res) + throw std::runtime_error("Call to grid() failed."); - Py_DECREF(args); - Py_DECREF(res); + Py_DECREF(args); + Py_DECREF(res); } -inline void show(const bool block = true) -{ - detail::_interpreter::get(); - - PyObject* res; - if(block) - { - res = PyObject_CallObject( - detail::_interpreter::get().s_python_function_show, - detail::_interpreter::get().s_python_empty_tuple); - } - else - { - PyObject *kwargs = PyDict_New(); - PyDict_SetItemString(kwargs, "block", Py_False); - res = PyObject_Call( detail::_interpreter::get().s_python_function_show, detail::_interpreter::get().s_python_empty_tuple, kwargs); - Py_DECREF(kwargs); - } +inline void show(const bool block = true) { + detail::_interpreter::get(); + PyObject *res; + if (block) { + res = + PyObject_CallObject(detail::_interpreter::get().s_python_function_show, + detail::_interpreter::get().s_python_empty_tuple); + } else { + PyObject *kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "block", Py_False); + res = + PyObject_Call(detail::_interpreter::get().s_python_function_show, + detail::_interpreter::get().s_python_empty_tuple, kwargs); + Py_DECREF(kwargs); + } - if (!res) throw std::runtime_error("Call to show() failed."); + if (!res) + throw std::runtime_error("Call to show() failed."); - Py_DECREF(res); + Py_DECREF(res); } -inline void close() -{ - detail::_interpreter::get(); +inline void close() { + detail::_interpreter::get(); - PyObject* res = PyObject_CallObject( - detail::_interpreter::get().s_python_function_close, - detail::_interpreter::get().s_python_empty_tuple); + PyObject *res = + PyObject_CallObject(detail::_interpreter::get().s_python_function_close, + detail::_interpreter::get().s_python_empty_tuple); - if (!res) throw std::runtime_error("Call to close() failed."); + if (!res) + throw std::runtime_error("Call to close() failed."); - Py_DECREF(res); + Py_DECREF(res); } inline void xkcd() { - detail::_interpreter::get(); + detail::_interpreter::get(); - PyObject* res; - PyObject *kwargs = PyDict_New(); + PyObject *res; + PyObject *kwargs = PyDict_New(); - res = PyObject_Call(detail::_interpreter::get().s_python_function_xkcd, - detail::_interpreter::get().s_python_empty_tuple, kwargs); + res = PyObject_Call(detail::_interpreter::get().s_python_function_xkcd, + detail::_interpreter::get().s_python_empty_tuple, kwargs); - Py_DECREF(kwargs); + Py_DECREF(kwargs); - if (!res) - throw std::runtime_error("Call to show() failed."); + if (!res) + throw std::runtime_error("Call to show() failed."); - Py_DECREF(res); + Py_DECREF(res); } -inline void draw() -{ - detail::_interpreter::get(); +inline void draw() { + detail::_interpreter::get(); - PyObject* res = PyObject_CallObject( - detail::_interpreter::get().s_python_function_draw, - detail::_interpreter::get().s_python_empty_tuple); + PyObject *res = + PyObject_CallObject(detail::_interpreter::get().s_python_function_draw, + detail::_interpreter::get().s_python_empty_tuple); - if (!res) throw std::runtime_error("Call to draw() failed."); + if (!res) + throw std::runtime_error("Call to draw() failed."); - Py_DECREF(res); + Py_DECREF(res); } -template -inline void pause(Numeric interval) -{ - detail::_interpreter::get(); +template inline void pause(Numeric interval) { + detail::_interpreter::get(); - PyObject* args = PyTuple_New(1); - PyTuple_SetItem(args, 0, PyFloat_FromDouble(interval)); + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, PyFloat_FromDouble(interval)); - PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_pause, args); - if(!res) throw std::runtime_error("Call to pause() failed."); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_pause, args); + if (!res) + throw std::runtime_error("Call to pause() failed."); - Py_DECREF(args); - Py_DECREF(res); + Py_DECREF(args); + Py_DECREF(res); } -inline void save(const std::string& filename, const int dpi=0) -{ - detail::_interpreter::get(); +inline void save(const std::string &filename, const int dpi = 0) { + detail::_interpreter::get(); - PyObject* pyfilename = PyString_FromString(filename.c_str()); + PyObject *pyfilename = PyString_FromString(filename.c_str()); - PyObject* args = PyTuple_New(1); - PyTuple_SetItem(args, 0, pyfilename); + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, pyfilename); - PyObject* kwargs = PyDict_New(); + PyObject *kwargs = PyDict_New(); - if(dpi > 0) - { - PyDict_SetItemString(kwargs, "dpi", PyLong_FromLong(dpi)); - } + if (dpi > 0) { + PyDict_SetItemString(kwargs, "dpi", PyLong_FromLong(dpi)); + } - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_save, args, kwargs); - if (!res) throw std::runtime_error("Call to save() failed."); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_save, args, kwargs); + if (!res) + throw std::runtime_error("Call to save() failed."); - Py_DECREF(args); - Py_DECREF(kwargs); - Py_DECREF(res); + Py_DECREF(args); + Py_DECREF(kwargs); + Py_DECREF(res); } -inline void rcparams(const std::map& keywords = {}) { - detail::_interpreter::get(); - PyObject* args = PyTuple_New(0); - PyObject* kwargs = PyDict_New(); - for (auto it = keywords.begin(); it != keywords.end(); ++it) { - if ("text.usetex" == it->first) - PyDict_SetItemString(kwargs, it->first.c_str(), PyLong_FromLong(std::stoi(it->second.c_str()))); - else PyDict_SetItemString(kwargs, it->first.c_str(), PyString_FromString(it->second.c_str())); - } - - PyObject * update = PyObject_GetAttrString(detail::_interpreter::get().s_python_function_rcparams, "update"); - PyObject * res = PyObject_Call(update, args, kwargs); - if(!res) throw std::runtime_error("Call to rcParams.update() failed."); - Py_DECREF(args); - Py_DECREF(kwargs); - Py_DECREF(update); - Py_DECREF(res); +inline void rcparams(const std::map &keywords = {}) { + detail::_interpreter::get(); + PyObject *args = PyTuple_New(0); + PyObject *kwargs = PyDict_New(); + for (auto it = keywords.begin(); it != keywords.end(); ++it) { + if ("text.usetex" == it->first) + PyDict_SetItemString(kwargs, it->first.c_str(), + PyLong_FromLong(std::stoi(it->second.c_str()))); + else + PyDict_SetItemString(kwargs, it->first.c_str(), + PyString_FromString(it->second.c_str())); + } + + PyObject *update = PyObject_GetAttrString( + detail::_interpreter::get().s_python_function_rcparams, "update"); + PyObject *res = PyObject_Call(update, args, kwargs); + if (!res) + throw std::runtime_error("Call to rcParams.update() failed."); + Py_DECREF(args); + Py_DECREF(kwargs); + Py_DECREF(update); + Py_DECREF(res); } inline void clf() { - detail::_interpreter::get(); + detail::_interpreter::get(); - PyObject *res = PyObject_CallObject( - detail::_interpreter::get().s_python_function_clf, - detail::_interpreter::get().s_python_empty_tuple); + PyObject *res = + PyObject_CallObject(detail::_interpreter::get().s_python_function_clf, + detail::_interpreter::get().s_python_empty_tuple); - if (!res) throw std::runtime_error("Call to clf() failed."); + if (!res) + throw std::runtime_error("Call to clf() failed."); - Py_DECREF(res); + Py_DECREF(res); } inline void cla() { - detail::_interpreter::get(); + detail::_interpreter::get(); - PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_cla, - detail::_interpreter::get().s_python_empty_tuple); + PyObject *res = + PyObject_CallObject(detail::_interpreter::get().s_python_function_cla, + detail::_interpreter::get().s_python_empty_tuple); - if (!res) - throw std::runtime_error("Call to cla() failed."); + if (!res) + throw std::runtime_error("Call to cla() failed."); - Py_DECREF(res); + Py_DECREF(res); } inline void ion() { - detail::_interpreter::get(); + detail::_interpreter::get(); - PyObject *res = PyObject_CallObject( - detail::_interpreter::get().s_python_function_ion, - detail::_interpreter::get().s_python_empty_tuple); + PyObject *res = + PyObject_CallObject(detail::_interpreter::get().s_python_function_ion, + detail::_interpreter::get().s_python_empty_tuple); - if (!res) throw std::runtime_error("Call to ion() failed."); + if (!res) + throw std::runtime_error("Call to ion() failed."); - Py_DECREF(res); + Py_DECREF(res); } -inline std::vector> ginput(const int numClicks = 1, const std::map& keywords = {}) -{ - detail::_interpreter::get(); +inline std::vector> +ginput(const int numClicks = 1, + const std::map &keywords = {}) { + detail::_interpreter::get(); - PyObject *args = PyTuple_New(1); - PyTuple_SetItem(args, 0, PyLong_FromLong(numClicks)); + PyObject *args = PyTuple_New(1); + PyTuple_SetItem(args, 0, PyLong_FromLong(numClicks)); - // construct keyword args - PyObject* kwargs = PyDict_New(); - for(std::map::const_iterator it = keywords.begin(); it != keywords.end(); ++it) - { - PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str())); - } + // construct keyword args + PyObject *kwargs = PyDict_New(); + for (std::map::const_iterator it = keywords.begin(); + it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), + PyUnicode_FromString(it->second.c_str())); + } - PyObject* res = PyObject_Call( - detail::_interpreter::get().s_python_function_ginput, args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_ginput, args, kwargs); - Py_DECREF(kwargs); - Py_DECREF(args); - if (!res) throw std::runtime_error("Call to ginput() failed."); - - const size_t len = PyList_Size(res); - std::vector> out; - out.reserve(len); - for (size_t i = 0; i < len; i++) { - PyObject *current = PyList_GetItem(res, i); - std::array position; - position[0] = PyFloat_AsDouble(PyTuple_GetItem(current, 0)); - position[1] = PyFloat_AsDouble(PyTuple_GetItem(current, 1)); - out.push_back(position); - } - Py_DECREF(res); + Py_DECREF(kwargs); + Py_DECREF(args); + if (!res) + throw std::runtime_error("Call to ginput() failed."); + + const size_t len = PyList_Size(res); + std::vector> out; + out.reserve(len); + for (size_t i = 0; i < len; i++) { + PyObject *current = PyList_GetItem(res, i); + std::array position; + position[0] = PyFloat_AsDouble(PyTuple_GetItem(current, 0)); + position[1] = PyFloat_AsDouble(PyTuple_GetItem(current, 1)); + out.push_back(position); + } + Py_DECREF(res); - return out; + return out; } // Actually, is there any reason not to call this automatically for every plot? inline void tight_layout() { - detail::_interpreter::get(); + detail::_interpreter::get(); - PyObject *res = PyObject_CallObject( - detail::_interpreter::get().s_python_function_tight_layout, - detail::_interpreter::get().s_python_empty_tuple); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_tight_layout, + detail::_interpreter::get().s_python_empty_tuple); - if (!res) throw std::runtime_error("Call to tight_layout() failed."); + if (!res) + throw std::runtime_error("Call to tight_layout() failed."); - Py_DECREF(res); + Py_DECREF(res); } // Support for variadic plot() and initializer lists: namespace detail { -template -using is_function = typename std::is_function>>::type; +template +using is_function = typename std::is_function< + std::remove_pointer>>::type; -template -struct is_callable_impl; +template struct is_callable_impl; -template -struct is_callable_impl -{ - typedef is_function type; +template struct is_callable_impl { + typedef is_function type; }; // a non-object is callable iff it is a function -template -struct is_callable_impl -{ - struct Fallback { void operator()(); }; - struct Derived : T, Fallback { }; +template struct is_callable_impl { + struct Fallback { + void operator()(); + }; + struct Derived : T, Fallback {}; - template struct Check; + template struct Check; - template - static std::true_type test( ... ); // use a variadic function to make sure (1) it accepts everything and (2) its always the worst match + template + static std::true_type + test(...); // use a variadic function to make sure (1) it accepts everything + // and (2) its always the worst match - template - static std::false_type test( Check* ); + template + static std::false_type test(Check *); public: - typedef decltype(test(nullptr)) type; - typedef decltype(&Fallback::operator()) dtype; - static constexpr bool value = type::value; + typedef decltype(test(nullptr)) type; + typedef decltype(&Fallback::operator()) dtype; + static constexpr bool value = type::value; }; // an object is callable iff it defines operator() -template -struct is_callable -{ - // dispatch to is_callable_impl or is_callable_impl depending on whether T is of class type or not - typedef typename is_callable_impl::value, T>::type type; +template struct is_callable { + // dispatch to is_callable_impl or is_callable_impl + // depending on whether T is of class type or not + typedef typename is_callable_impl::value, T>::type type; }; -template -struct plot_impl { }; +template struct plot_impl {}; -template<> -struct plot_impl -{ - template - bool operator()(const IterableX& x, const IterableY& y, const std::string& format) - { - detail::_interpreter::get(); +template <> struct plot_impl { + template + bool operator()(const IterableX &x, const IterableY &y, + const std::string &format) { + detail::_interpreter::get(); - // 2-phase lookup for distance, begin, end - using std::distance; - using std::begin; - using std::end; + // 2-phase lookup for distance, begin, end + using std::begin; + using std::distance; + using std::end; - auto xs = distance(begin(x), end(x)); - auto ys = distance(begin(y), end(y)); - assert(xs == ys && "x and y data must have the same number of elements!"); + auto xs = distance(begin(x), end(x)); + auto ys = distance(begin(y), end(y)); + assert(xs == ys && "x and y data must have the same number of elements!"); - PyObject* xlist = PyList_New(xs); - PyObject* ylist = PyList_New(ys); - PyObject* pystring = PyString_FromString(format.c_str()); + PyObject *xlist = PyList_New(xs); + PyObject *ylist = PyList_New(ys); + PyObject *pystring = PyString_FromString(format.c_str()); - auto itx = begin(x), ity = begin(y); - for(size_t i = 0; i < xs; ++i) { - PyList_SetItem(xlist, i, PyFloat_FromDouble(*itx++)); - PyList_SetItem(ylist, i, PyFloat_FromDouble(*ity++)); - } + auto itx = begin(x), ity = begin(y); + for (size_t i = 0; i < xs; ++i) { + PyList_SetItem(xlist, i, PyFloat_FromDouble(*itx++)); + PyList_SetItem(ylist, i, PyFloat_FromDouble(*ity++)); + } - PyObject* plot_args = PyTuple_New(3); - PyTuple_SetItem(plot_args, 0, xlist); - PyTuple_SetItem(plot_args, 1, ylist); - PyTuple_SetItem(plot_args, 2, pystring); + PyObject *plot_args = PyTuple_New(3); + PyTuple_SetItem(plot_args, 0, xlist); + PyTuple_SetItem(plot_args, 1, ylist); + PyTuple_SetItem(plot_args, 2, pystring); - PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_plot, plot_args); + PyObject *res = PyObject_CallObject( + detail::_interpreter::get().s_python_function_plot, plot_args); - Py_DECREF(plot_args); - if(res) Py_DECREF(res); + Py_DECREF(plot_args); + if (res) + Py_DECREF(res); - return res; - } + return res; + } }; -template<> -struct plot_impl -{ - template - bool operator()(const Iterable& ticks, const Callable& f, const std::string& format) - { - if(begin(ticks) == end(ticks)) return true; - - // We could use additional meta-programming to deduce the correct element type of y, - // but all values have to be convertible to double anyways - std::vector y; - for(auto x : ticks) y.push_back(f(x)); - return plot_impl()(ticks,y,format); - } +template <> struct plot_impl { + template + bool operator()(const Iterable &ticks, const Callable &f, + const std::string &format) { + if (begin(ticks) == end(ticks)) + return true; + + // We could use additional meta-programming to deduce the correct element + // type of y, but all values have to be convertible to double anyways + std::vector y; + for (auto x : ticks) + y.push_back(f(x)); + return plot_impl()(ticks, y, format); + } }; } // end namespace detail // recursion stop for the above -template -bool plot() { return true; } +template bool plot() { return true; } -template -bool plot(const A& a, const B& b, const std::string& format, Args... args) -{ - return detail::plot_impl::type>()(a,b,format) && plot(args...); +template +bool plot(const A &a, const B &b, const std::string &format, Args... args) { + return detail::plot_impl::type>()(a, b, + format) && + plot(args...); } /* - * This group of plot() functions is needed to support initializer lists, i.e. calling - * plot( {1,2,3,4} ) + * This group of plot() functions is needed to support initializer lists, i.e. + * calling plot( {1,2,3,4} ) */ -inline bool plot(const std::vector& x, const std::vector& y, const std::string& format = "") { - return plot(x,y,format); +inline bool plot(const std::vector &x, const std::vector &y, + const std::string &format = "") { + return plot(x, y, format); } -inline bool plot(const std::vector& y, const std::string& format = "") { - return plot(y,format); +inline bool plot(const std::vector &y, const std::string &format = "") { + return plot(y, format); } -inline bool plot(const std::vector& x, const std::vector& y, const std::map& keywords) { - return plot(x,y,keywords); +inline bool plot(const std::vector &x, const std::vector &y, + const std::map &keywords) { + return plot(x, y, keywords); } /* - * This class allows dynamic plots, ie changing the plotted data without clearing and re-plotting + * This class allows dynamic plots, ie changing the plotted data without + * clearing and re-plotting */ -class Plot -{ +class Plot { public: - // default initialization with plot label, some data and format - template - Plot(const std::string& name, const std::vector& x, const std::vector& y, const std::string& format = "") { - detail::_interpreter::get(); + // default initialization with plot label, some data and format + template + Plot(const std::string &name, const std::vector &x, + const std::vector &y, const std::string &format = "") { + detail::_interpreter::get(); - assert(x.size() == y.size()); + assert(x.size() == y.size()); - PyObject* kwargs = PyDict_New(); - if(name != "") - PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); + PyObject *kwargs = PyDict_New(); + if (name != "") + PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); - PyObject* pystring = PyString_FromString(format.c_str()); + PyObject *pystring = PyString_FromString(format.c_str()); - PyObject* plot_args = PyTuple_New(3); - PyTuple_SetItem(plot_args, 0, xarray); - PyTuple_SetItem(plot_args, 1, yarray); - PyTuple_SetItem(plot_args, 2, pystring); + PyObject *plot_args = PyTuple_New(3); + PyTuple_SetItem(plot_args, 0, xarray); + PyTuple_SetItem(plot_args, 1, yarray); + PyTuple_SetItem(plot_args, 2, pystring); - PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_plot, plot_args, kwargs); + PyObject *res = PyObject_Call( + detail::_interpreter::get().s_python_function_plot, plot_args, kwargs); - Py_DECREF(kwargs); - Py_DECREF(plot_args); + Py_DECREF(kwargs); + Py_DECREF(plot_args); - if(res) - { - line= PyList_GetItem(res, 0); + if (res) { + line = PyList_GetItem(res, 0); - if(line) - set_data_fct = PyObject_GetAttrString(line,"set_data"); - else - Py_DECREF(line); - Py_DECREF(res); - } + if (line) + set_data_fct = PyObject_GetAttrString(line, "set_data"); + else + Py_DECREF(line); + Py_DECREF(res); } + } - // shorter initialization with name or format only - // basically calls line, = plot([], []) - Plot(const std::string& name = "", const std::string& format = "") - : Plot(name, std::vector(), std::vector(), format) {} - - template - bool update(const std::vector& x, const std::vector& y) { - assert(x.size() == y.size()); - if(set_data_fct) - { - PyObject* xarray = detail::get_array(x); - PyObject* yarray = detail::get_array(y); - - PyObject* plot_args = PyTuple_New(2); - PyTuple_SetItem(plot_args, 0, xarray); - PyTuple_SetItem(plot_args, 1, yarray); - - PyObject* res = PyObject_CallObject(set_data_fct, plot_args); - if (res) Py_DECREF(res); - return res; - } - return false; - } + // shorter initialization with name or format only + // basically calls line, = plot([], []) + Plot(const std::string &name = "", const std::string &format = "") + : Plot(name, std::vector(), std::vector(), format) {} - // clears the plot but keep it available - bool clear() { - return update(std::vector(), std::vector()); - } + template + bool update(const std::vector &x, const std::vector &y) { + assert(x.size() == y.size()); + if (set_data_fct) { + PyObject *xarray = detail::get_array(x); + PyObject *yarray = detail::get_array(y); - // definitely remove this line - void remove() { - if(line) - { - auto remove_fct = PyObject_GetAttrString(line,"remove"); - PyObject* args = PyTuple_New(0); - PyObject* res = PyObject_CallObject(remove_fct, args); - if (res) Py_DECREF(res); - } - decref(); - } + PyObject *plot_args = PyTuple_New(2); + PyTuple_SetItem(plot_args, 0, xarray); + PyTuple_SetItem(plot_args, 1, yarray); - ~Plot() { - decref(); + PyObject *res = PyObject_CallObject(set_data_fct, plot_args); + if (res) + Py_DECREF(res); + return res; } -private: + return false; + } - void decref() { - if(line) - Py_DECREF(line); - if(set_data_fct) - Py_DECREF(set_data_fct); + // clears the plot but keep it available + bool clear() { return update(std::vector(), std::vector()); } + + // definitely remove this line + void remove() { + if (line) { + auto remove_fct = PyObject_GetAttrString(line, "remove"); + PyObject *args = PyTuple_New(0); + PyObject *res = PyObject_CallObject(remove_fct, args); + if (res) + Py_DECREF(res); } + decref(); + } + + ~Plot() { decref(); } +private: + void decref() { + if (line) + Py_DECREF(line); + if (set_data_fct) + Py_DECREF(set_data_fct); + } - PyObject* line = nullptr; - PyObject* set_data_fct = nullptr; + PyObject *line = nullptr; + PyObject *set_data_fct = nullptr; }; } // end namespace matplotlibcpp From fb2ee35f83133371ecd40ce53d97a61084f51cda Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Wed, 28 Sep 2022 22:11:08 +0800 Subject: [PATCH 19/31] =?UTF-8?q?[09/28/2022]=20=E5=A2=9E=E5=8A=A0matplotl?= =?UTF-8?q?ib=20wrapper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加matplotlib wrapper --- matplotlib.h | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 matplotlib.h diff --git a/matplotlib.h b/matplotlib.h new file mode 100644 index 0000000..f8e4b8f --- /dev/null +++ b/matplotlib.h @@ -0,0 +1,79 @@ +#ifndef _MATPLOTLIB_H +#define _MATPLOTLIB_H + +#include +#include +#include + +#ifdef _WIN32 +#define __XXX_YYY_ZZZ_POPEN___ _popen +#define __XXX_YYY_ZZZ_PCLOSE___ _pclose +#else +#include +#define __XXX_YYY_ZZZ_POPEN___ popen +#define __XXX_YYY_ZZZ_PCLOSE___ pclose +#endif + +#define PY_MAJOR_VERSION 3 +#include "matplotlibcpp.h" + +std::string +__XXX_YYY_ZZZ_STRIP__(const std::string &str, + const std::string &whitespace = " \n\r\t\f\v") { + size_t from = str.find_first_not_of(whitespace); + + if (from == std::string::npos) { + return ""; + } + size_t to = str.find_last_not_of(whitespace); + assert(to != std::string::npos); + + return str.substr(from, (to - from) + 1); +} + +std::string __XXX_YYY_ZZZ_COMMAND__(const std::string &cmd) { + using pipe_ptr = std::unique_ptr; + pipe_ptr pipe(__XXX_YYY_ZZZ_POPEN___(cmd.c_str(), "r"), + __XXX_YYY_ZZZ_PCLOSE___); + if (pipe == nullptr) { + std::cout << "error: failed to execute: " << cmd << std::endl; + return ""; + } + + const int BUF_SIZE = 1023; + char buf[BUF_SIZE + 1]; + buf[BUF_SIZE] = '\0'; + + std::stringstream ss; + while (fgets(buf, BUF_SIZE, pipe.get()) != NULL) { + ss << buf; + } + + if (__XXX_YYY_ZZZ_PCLOSE___(pipe.release()) != 0) { + return ""; + } + + return __XXX_YYY_ZZZ_STRIP__(ss.str()); +} + +static bool __XXX_YYY_ZZZ_INIT__() { + const std::string PYTHON_VERSION = __XXX_YYY_ZZZ_COMMAND__( + "python3 --version | cut -d ' ' -f2 | cut -d '.' -f-2"); + const std::string PYTHONHOME = + std::string(getenv("CONDA_PREFIX")) + "/lib/python" + PYTHON_VERSION; + const std::string PYTHONPATH = PYTHONHOME + ":" + PYTHONHOME + + "/site-packages:" + PYTHONHOME + + "/lib-dynload"; + setenv("PYTHONHOME", PYTHONHOME.c_str(), 1); + setenv("PYTHONPATH", PYTHONPATH.c_str(), 1); + + std::cout << "PYTHON_VERSION: " << PYTHON_VERSION << std::endl; + std::cout << "PYTHONHOME : " << getenv("PYTHONHOME") << std::endl; + std::cout << "PYTHONPATH : " << getenv("PYTHONPATH") << std::endl; + + return true; +} + +static bool __UNUSED_XXX_YYY_ZZZ_INIT__ = __XXX_YYY_ZZZ_INIT__(); + +#endif From f3c309411289da3f1372afe66af252cf7c72fc9d Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Wed, 28 Sep 2022 22:22:24 +0800 Subject: [PATCH 20/31] =?UTF-8?q?[09/28/2022]=20=E4=BD=BF=E7=94=A8matplobl?= =?UTF-8?q?ib=E4=BD=BF=E8=83=BDexamples?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 使用matploblib使能examples --- examples/animation.cpp | 51 ++++++++++++------------ examples/bar.cpp | 16 ++++---- examples/basic.cpp | 76 +++++++++++++++++------------------ examples/colorbar.cpp | 39 +++++++++--------- examples/contour.cpp | 31 +++++++-------- examples/fill.cpp | 40 +++++++++---------- examples/fill_inbetween.cpp | 2 +- examples/imshow.cpp | 33 ++++++++-------- examples/lines3d.cpp | 46 ++++++++++----------- examples/minimal.cpp | 6 +-- examples/modern.cpp | 43 ++++++++++---------- examples/nonblock.cpp | 72 ++++++++++++++++----------------- examples/quiver.cpp | 28 ++++++------- examples/spy.cpp | 37 +++++++++-------- examples/subplot.cpp | 42 ++++++++++---------- examples/subplot2grid.cpp | 72 ++++++++++++++++----------------- examples/surface.cpp | 31 +++++++-------- examples/update.cpp | 79 ++++++++++++++++++------------------- examples/xkcd.cpp | 23 ++++++----- 19 files changed, 376 insertions(+), 391 deletions(-) diff --git a/examples/animation.cpp b/examples/animation.cpp index d979430..f73b671 100644 --- a/examples/animation.cpp +++ b/examples/animation.cpp @@ -1,36 +1,35 @@ #define _USE_MATH_DEFINES +#include "../matplotlib.h" #include -#include "../matplotlibcpp.h" namespace plt = matplotlibcpp; -int main() -{ - int n = 1000; - std::vector x, y, z; +int main() { + int n = 1000; + std::vector x, y, z; - for(int i=0; i #include -#include "../matplotlibcpp.h" namespace plt = matplotlibcpp; int main(int argc, char **argv) { - std::vector test_data; - for (int i = 0; i < 20; i++) { - test_data.push_back(i); - } + std::vector test_data; + for (int i = 0; i < 20; i++) { + test_data.push_back(i); + } - plt::bar(test_data); - plt::show(); + plt::bar(test_data); + plt::show(); - return (0); + return (0); } diff --git a/examples/basic.cpp b/examples/basic.cpp index 2dc34c7..aaab1e2 100644 --- a/examples/basic.cpp +++ b/examples/basic.cpp @@ -1,44 +1,44 @@ #define _USE_MATH_DEFINES -#include +#include "../matplotlib.h" #include -#include "../matplotlibcpp.h" +#include namespace plt = matplotlibcpp; -int main() -{ - // Prepare data. - int n = 5000; - std::vector x(n), y(n), z(n), w(n,2); - for(int i=0; i 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 = 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 figure + const char *filename = "./basic.png"; + std::cout << "Saving result to " << filename << std::endl; + ; + plt::save(filename); } diff --git a/examples/colorbar.cpp b/examples/colorbar.cpp index f53e01d..d3c1e0b 100644 --- a/examples/colorbar.cpp +++ b/examples/colorbar.cpp @@ -1,32 +1,31 @@ #define _USE_MATH_DEFINES +#include "../matplotlib.h" #include #include -#include "../matplotlibcpp.h" using namespace std; namespace plt = matplotlibcpp; -int main() -{ - // Prepare data - int ncols = 500, nrows = 300; - std::vector z(ncols * nrows); - for (int j=0; j z(ncols * nrows); + for (int j = 0; j < nrows; ++j) { + for (int i = 0; i < ncols; ++i) { + z.at(ncols * j + i) = std::sin(std::hypot(i - ncols / 2, j - nrows / 2)); } + } - const float* zptr = &(z[0]); - const int colors = 1; + const float *zptr = &(z[0]); + const int colors = 1; - plt::title("My matrix"); - PyObject* mat; - plt::imshow(zptr, nrows, ncols, colors, {}, &mat); - plt::colorbar(mat); + plt::title("My matrix"); + PyObject *mat; + plt::imshow(zptr, nrows, ncols, colors, {}, &mat); + plt::colorbar(mat); - // Show plots - plt::show(); - plt::close(); - Py_DECREF(mat); + // Show plots + plt::show(); + plt::close(); + Py_DECREF(mat); } diff --git a/examples/contour.cpp b/examples/contour.cpp index 9289d0a..072dc29 100644 --- a/examples/contour.cpp +++ b/examples/contour.cpp @@ -1,24 +1,23 @@ -#include "../matplotlibcpp.h" +#include "../matplotlib.h" #include namespace plt = matplotlibcpp; -int main() -{ - std::vector> x, y, z; - for (double i = -5; i <= 5; i += 0.25) { - std::vector 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); +int main() { + std::vector> x, y, z; + for (double i = -5; i <= 5; i += 0.25) { + std::vector 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::contour(x, y, z); - plt::show(); + plt::contour(x, y, z); + plt::show(); } diff --git a/examples/fill.cpp b/examples/fill.cpp index 6059b47..aa3b9aa 100644 --- a/examples/fill.cpp +++ b/examples/fill.cpp @@ -1,5 +1,5 @@ #define _USE_MATH_DEFINES -#include "../matplotlibcpp.h" +#include "../matplotlib.h" #include using namespace std; @@ -8,28 +8,28 @@ namespace plt = matplotlibcpp; // Example fill plot taken from: // https://matplotlib.org/gallery/misc/fill_spiral.html int main() { - // Prepare data. - vector theta; - for (double d = 0; d < 8 * M_PI; d += 0.1) - theta.push_back(d); + // Prepare data. + vector theta; + for (double d = 0; d < 8 * M_PI; d += 0.1) + theta.push_back(d); - const int a = 1; - const double b = 0.2; + const int a = 1; + const double b = 0.2; - for (double dt = 0; dt < 2 * M_PI; dt += M_PI/2.0) { - vector x1, y1, x2, y2; - for (double th : theta) { - x1.push_back( a*cos(th + dt) * exp(b*th) ); - y1.push_back( a*sin(th + dt) * exp(b*th) ); + for (double dt = 0; dt < 2 * M_PI; dt += M_PI / 2.0) { + vector x1, y1, x2, y2; + for (double th : theta) { + x1.push_back(a * cos(th + dt) * exp(b * th)); + y1.push_back(a * sin(th + dt) * exp(b * th)); - x2.push_back( a*cos(th + dt + M_PI/4.0) * exp(b*th) ); - y2.push_back( a*sin(th + dt + M_PI/4.0) * exp(b*th) ); - } + x2.push_back(a * cos(th + dt + M_PI / 4.0) * exp(b * th)); + y2.push_back(a * sin(th + dt + M_PI / 4.0) * exp(b * th)); + } - x1.insert(x1.end(), x2.rbegin(), x2.rend()); - y1.insert(y1.end(), y2.rbegin(), y2.rend()); + x1.insert(x1.end(), x2.rbegin(), x2.rend()); + y1.insert(y1.end(), y2.rbegin(), y2.rend()); - plt::fill(x1, y1, {}); - } - plt::show(); + plt::fill(x1, y1, {}); + } + plt::show(); } diff --git a/examples/fill_inbetween.cpp b/examples/fill_inbetween.cpp index 788d008..26981b7 100644 --- a/examples/fill_inbetween.cpp +++ b/examples/fill_inbetween.cpp @@ -1,5 +1,5 @@ #define _USE_MATH_DEFINES -#include "../matplotlibcpp.h" +#include "../matplotlib.h" #include #include diff --git a/examples/imshow.cpp b/examples/imshow.cpp index b11661e..56bf821 100644 --- a/examples/imshow.cpp +++ b/examples/imshow.cpp @@ -1,29 +1,28 @@ #define _USE_MATH_DEFINES +#include "../matplotlib.h" #include #include -#include "../matplotlibcpp.h" using namespace std; namespace plt = matplotlibcpp; -int main() -{ - // Prepare data - int ncols = 500, nrows = 300; - std::vector z(ncols * nrows); - for (int j=0; j z(ncols * nrows); + for (int j = 0; j < nrows; ++j) { + for (int i = 0; i < ncols; ++i) { + z.at(ncols * j + i) = std::sin(std::hypot(i - ncols / 2, j - nrows / 2)); } + } - const float* zptr = &(z[0]); - const int colors = 1; + const float *zptr = &(z[0]); + const int colors = 1; - plt::title("My matrix"); - plt::imshow(zptr, nrows, ncols, colors); + plt::title("My matrix"); + plt::imshow(zptr, nrows, ncols, colors); - // Show plots - plt::save("imshow.png"); - std::cout << "Result saved to 'imshow.png'.\n"; + // Show plots + plt::save("imshow.png"); + std::cout << "Result saved to 'imshow.png'.\n"; } diff --git a/examples/lines3d.cpp b/examples/lines3d.cpp index fd4610d..6859b0d 100644 --- a/examples/lines3d.cpp +++ b/examples/lines3d.cpp @@ -1,30 +1,32 @@ #define _USE_MATH_DEFINES -#include "../matplotlibcpp.h" +#include "../matplotlib.h" #include namespace plt = matplotlibcpp; -int main() -{ - std::vector x, y, z; - double theta, r; - double z_inc = 4.0/99.0; double theta_inc = (8.0 * M_PI)/99.0; - - for (double i = 0; i < 100; i += 1) { - theta = -4.0 * M_PI + theta_inc*i; - z.push_back(-2.0 + z_inc*i); - r = z[i]*z[i] + 1; - x.push_back(r * sin(theta)); - y.push_back(r * cos(theta)); - } +int main() { + std::vector x, y, z; + double theta, r; + double z_inc = 4.0 / 99.0; + double theta_inc = (8.0 * M_PI) / 99.0; - std::map keywords; - keywords.insert(std::pair("label", "parametric curve") ); + for (double i = 0; i < 100; i += 1) { + theta = -4.0 * M_PI + theta_inc * i; + z.push_back(-2.0 + z_inc * i); + r = z[i] * z[i] + 1; + x.push_back(r * sin(theta)); + y.push_back(r * cos(theta)); + } - plt::plot3(x, y, z, keywords); - plt::xlabel("x label"); - plt::ylabel("y label"); - plt::set_zlabel("z label"); // set_zlabel rather than just zlabel, in accordance with the Axes3D method - plt::legend(); - plt::show(); + std::map keywords; + keywords.insert( + std::pair("label", "parametric curve")); + + plt::plot3(x, y, z, keywords); + plt::xlabel("x label"); + plt::ylabel("y label"); + plt::set_zlabel("z label"); // set_zlabel rather than just zlabel, in + // accordance with the Axes3D method + plt::legend(); + plt::show(); } diff --git a/examples/minimal.cpp b/examples/minimal.cpp index fbe1e1c..1320d4d 100644 --- a/examples/minimal.cpp +++ b/examples/minimal.cpp @@ -1,8 +1,8 @@ -#include "../matplotlibcpp.h" +#include "../matplotlib.h" namespace plt = matplotlibcpp; int main() { - plt::plot({1,3,2,4}); - plt::show(); + plt::plot({1, 3, 2, 4}); + plt::show(); } diff --git a/examples/modern.cpp b/examples/modern.cpp index 871ef2b..3561ad9 100644 --- a/examples/modern.cpp +++ b/examples/modern.cpp @@ -1,33 +1,32 @@ #define _USE_MATH_DEFINES +#include "../matplotlib.h" #include -#include "../matplotlibcpp.h" using namespace std; namespace plt = matplotlibcpp; -int main() -{ - // plot(y) - the x-coordinates are implicitly set to [0,1,...,n) - //plt::plot({1,2,3,4}); - - // Prepare data for parametric plot. - int n = 5000; // number of data points - vector x(n),y(n); - for(int i=0; i 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); + } - //plt::set_aspect(0.5); - plt::set_aspect_equal(); + // 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-"); + // plt::set_aspect(0.5); + plt::set_aspect_equal(); - // show plots - plt::show(); + // show plots + plt::show(); } diff --git a/examples/nonblock.cpp b/examples/nonblock.cpp index 327d96c..e3ac1a1 100644 --- a/examples/nonblock.cpp +++ b/examples/nonblock.cpp @@ -1,46 +1,44 @@ #define _USE_MATH_DEFINES +#include "../matplotlib.h" #include -#include "../matplotlibcpp.h" namespace plt = matplotlibcpp; - using namespace matplotlibcpp; using namespace std; -int main() -{ - // Prepare data. - int n = 5000; - std::vector x(n), y(n), z(n), w(n,2); - for(int i=0; i 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); + } + + // Plot line from given x and y data. Color is selected automatically. + plt::subplot(2, 2, 1); + plt::plot(x, y); + + // Plot a red dashed line from given x and y data. + plt::subplot(2, 2, 2); + plt::plot(x, w, "r--"); + + // Plot a line whose name will show up as "log(x)" in the legend. + plt::subplot(2, 2, 3); + 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(); + + plt::show(false); + + cout << "matplotlibcpp::show() is working in an non-blocking mode" << endl; + getchar(); } diff --git a/examples/quiver.cpp b/examples/quiver.cpp index ea3c3ec..2efcb83 100644 --- a/examples/quiver.cpp +++ b/examples/quiver.cpp @@ -1,20 +1,20 @@ -#include "../matplotlibcpp.h" +#include "../matplotlib.h" namespace plt = matplotlibcpp; -int main() -{ - // u and v are respectively the x and y components of the arrows we're plotting - std::vector 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); - } +int main() { + // u and v are respectively the x and y components of the arrows we're + // plotting + std::vector 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(); + plt::quiver(x, y, u, v); + plt::show(); } \ No newline at end of file diff --git a/examples/spy.cpp b/examples/spy.cpp index 6027a48..c2d3c7f 100644 --- a/examples/spy.cpp +++ b/examples/spy.cpp @@ -1,30 +1,29 @@ -#include "../matplotlibcpp.h" +#include "../matplotlib.h" #include #include namespace plt = matplotlibcpp; -int main() -{ - const int n = 20; - std::vector> matrix; +int main() { + const int n = 20; + std::vector> matrix; - for (int i = 0; i < n; ++i) { - std::vector row; - for (int j = 0; j < n; ++j) { - if (i == j) - row.push_back(-2); - else if (j == i - 1 || j == i + 1) - row.push_back(1); - else - row.push_back(0); - } - matrix.push_back(row); + for (int i = 0; i < n; ++i) { + std::vector row; + for (int j = 0; j < n; ++j) { + if (i == j) + row.push_back(-2); + else if (j == i - 1 || j == i + 1) + row.push_back(1); + else + row.push_back(0); } + matrix.push_back(row); + } - plt::spy(matrix, 5, {{"marker", "o"}}); - plt::show(); + plt::spy(matrix, 5, {{"marker", "o"}}); + plt::show(); - return 0; + return 0; } diff --git a/examples/subplot.cpp b/examples/subplot.cpp index bee322e..e88a980 100644 --- a/examples/subplot.cpp +++ b/examples/subplot.cpp @@ -1,31 +1,29 @@ #define _USE_MATH_DEFINES +#include "../matplotlib.h" #include -#include "../matplotlibcpp.h" using namespace std; namespace plt = matplotlibcpp; -int main() -{ - // Prepare data - int n = 500; - std::vector x(n), y(n), z(n), w(n,2); - for(int i=0; i x(n), y(n), z(n), w(n, 2); + for (int i = 0; i < n; ++i) { + x.at(i) = i; + y.at(i) = sin(2 * M_PI * i / 360.0); + z.at(i) = 100.0 / i; + } - // Set the "super title" - plt::suptitle("My plot"); - plt::subplot(1, 2, 1); - plt::plot(x, y, "r-"); - plt::subplot(1, 2, 2); - plt::plot(x, z, "k-"); - // Add some text to the plot - plt::text(100, 90, "Hello!"); + // Set the "super title" + plt::suptitle("My plot"); + plt::subplot(1, 2, 1); + plt::plot(x, y, "r-"); + plt::subplot(1, 2, 2); + plt::plot(x, z, "k-"); + // Add some text to the plot + plt::text(100, 90, "Hello!"); - - // Show plots - plt::show(); + // Show plots + plt::show(); } diff --git a/examples/subplot2grid.cpp b/examples/subplot2grid.cpp index f590e51..28b0655 100644 --- a/examples/subplot2grid.cpp +++ b/examples/subplot2grid.cpp @@ -1,44 +1,42 @@ #define _USE_MATH_DEFINES +#include "../matplotlib.h" #include -#include "../matplotlibcpp.h" using namespace std; namespace plt = matplotlibcpp; -int main() -{ - // Prepare data - int n = 500; - std::vector x(n), u(n), v(n), w(n); - for(int i=0; i x(n), u(n), v(n), w(n); + for (int i = 0; i < n; ++i) { + x.at(i) = i; + u.at(i) = sin(2 * M_PI * i / 500.0); + v.at(i) = 100.0 / i; + w.at(i) = sin(2 * M_PI * i / 1000.0); + } + + // Set the "super title" + plt::suptitle("My plot"); + + const long nrows = 3, ncols = 3; + long row = 2, col = 2; + + plt::subplot2grid(nrows, ncols, row, col); + plt::plot(x, w, "g-"); + + long spanr = 1, spanc = 2; + col = 0; + plt::subplot2grid(nrows, ncols, row, col, spanr, spanc); + plt::plot(x, v, "r-"); + + spanr = 2, spanc = 3; + row = 0, col = 0; + plt::subplot2grid(nrows, ncols, row, col, spanr, spanc); + plt::plot(x, u, "b-"); + // Add some text to the plot + plt::text(100., -0.5, "Hello!"); + + // Show plots + plt::show(); } diff --git a/examples/surface.cpp b/examples/surface.cpp index 4865f06..9f5e244 100644 --- a/examples/surface.cpp +++ b/examples/surface.cpp @@ -1,24 +1,23 @@ -#include "../matplotlibcpp.h" +#include "../matplotlib.h" #include namespace plt = matplotlibcpp; -int main() -{ - std::vector> x, y, z; - for (double i = -5; i <= 5; i += 0.25) { - std::vector 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); +int main() { + std::vector> x, y, z; + for (double i = -5; i <= 5; i += 0.25) { + std::vector 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(); + plt::plot_surface(x, y, z); + plt::show(); } diff --git a/examples/update.cpp b/examples/update.cpp index 64f4906..8828649 100644 --- a/examples/update.cpp +++ b/examples/update.cpp @@ -1,60 +1,57 @@ #define _USE_MATH_DEFINES -#include -#include "../matplotlibcpp.h" +#include "../matplotlib.h" #include +#include namespace plt = matplotlibcpp; void update_window(const double x, const double y, const double t, - std::vector &xt, std::vector &yt) -{ - const double target_length = 300; - const double half_win = (target_length/(2.*sqrt(1.+t*t))); - - xt[0] = x - half_win; - xt[1] = x + half_win; - yt[0] = y - half_win*t; - yt[1] = y + half_win*t; + std::vector &xt, std::vector &yt) { + const double target_length = 300; + const double half_win = (target_length / (2. * sqrt(1. + t * t))); + + xt[0] = x - half_win; + xt[1] = x + half_win; + yt[0] = y - half_win * t; + yt[1] = y + half_win * t; } +int main() { + size_t n = 1000; + std::vector x, y; -int main() -{ - size_t n = 1000; - std::vector x, y; + const double w = 0.05; + const double a = n / 2; - const double w = 0.05; - const double a = n/2; + for (size_t i = 0; i < n; i++) { + x.push_back(i); + y.push_back(a * sin(w * i)); + } - for (size_t i=0; i xt(2), yt(2); - std::vector xt(2), yt(2); + plt::title("Tangent of a sine curve"); + plt::xlim(x.front(), x.back()); + plt::ylim(-a, a); + plt::axis("equal"); - plt::title("Tangent of a sine curve"); - plt::xlim(x.front(), x.back()); - plt::ylim(-a, a); - plt::axis("equal"); + // Plot sin once and for all. + plt::named_plot("sin", x, y); - // Plot sin once and for all. - plt::named_plot("sin", x, y); + // Prepare plotting the tangent. + plt::Plot plot("tangent"); - // Prepare plotting the tangent. - plt::Plot plot("tangent"); + plt::legend(); - plt::legend(); + for (size_t i = 0; i < n; i++) { + if (i % 10 == 0) { + update_window(x[i], y[i], a * w * cos(w * x[i]), xt, yt); - for (size_t i=0; i -#include "../matplotlibcpp.h" #include namespace plt = matplotlibcpp; int main() { - std::vector t(1000); - std::vector x(t.size()); + std::vector t(1000); + std::vector 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]); - } + 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::show(); + plt::xkcd(); + plt::plot(t, x); + plt::title("AN ORDINARY SIN WAVE"); + plt::show(); } - From 0f201b8fe5d2db7731005ec08ad43e37819472e3 Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Wed, 28 Sep 2022 22:51:16 +0800 Subject: [PATCH 21/31] =?UTF-8?q?[09/28/2022]=20=E5=A2=9E=E5=8A=A0conda?= =?UTF-8?q?=E4=B8=8E=E7=B3=BB=E7=BB=9F=E5=85=BC=E5=AE=B9=E6=80=A7=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加conda与系统兼容性配置 --- matplotlib.h | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/matplotlib.h b/matplotlib.h index f8e4b8f..a7da328 100644 --- a/matplotlib.h +++ b/matplotlib.h @@ -57,19 +57,23 @@ std::string __XXX_YYY_ZZZ_COMMAND__(const std::string &cmd) { } static bool __XXX_YYY_ZZZ_INIT__() { - const std::string PYTHON_VERSION = __XXX_YYY_ZZZ_COMMAND__( - "python3 --version | cut -d ' ' -f2 | cut -d '.' -f-2"); - const std::string PYTHONHOME = - std::string(getenv("CONDA_PREFIX")) + "/lib/python" + PYTHON_VERSION; - const std::string PYTHONPATH = PYTHONHOME + ":" + PYTHONHOME + - "/site-packages:" + PYTHONHOME + - "/lib-dynload"; - setenv("PYTHONHOME", PYTHONHOME.c_str(), 1); - setenv("PYTHONPATH", PYTHONPATH.c_str(), 1); - - std::cout << "PYTHON_VERSION: " << PYTHON_VERSION << std::endl; - std::cout << "PYTHONHOME : " << getenv("PYTHONHOME") << std::endl; - std::cout << "PYTHONPATH : " << getenv("PYTHONPATH") << std::endl; + const std::string CONDA_PREFIX = getenv("CONDA_PREFIX"); + if (CONDA_PREFIX.empty()) { + // do default python config + } else { + const std::string PYTHON_VERSION = __XXX_YYY_ZZZ_COMMAND__( + "python3 --version | cut -d ' ' -f2 | cut -d '.' -f-2"); + const std::string PYTHONHOME = + std::string(getenv("CONDA_PREFIX")) + "/lib/python" + PYTHON_VERSION; + const std::string PYTHONPATH = PYTHONHOME + ":" + PYTHONHOME + + "/site-packages:" + PYTHONHOME + + "/lib-dynload"; + setenv("PYTHONHOME", PYTHONHOME.c_str(), 1); + setenv("PYTHONPATH", PYTHONPATH.c_str(), 1); + std::cout << "PYTHON_VERSION: " << PYTHON_VERSION << std::endl; + std::cout << "PYTHONHOME : " << getenv("PYTHONHOME") << std::endl; + std::cout << "PYTHONPATH : " << getenv("PYTHONPATH") << std::endl; + } return true; } From 3a5243a0f84f55430f450b2818bf50f75775b031 Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Wed, 28 Sep 2022 23:25:27 +0800 Subject: [PATCH 22/31] [09/28/2022] Bugfixed: NULL pointer for std::string Bugfixed: NULL pointer for std::string --- matplotlib.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/matplotlib.h b/matplotlib.h index a7da328..acc8d3b 100644 --- a/matplotlib.h +++ b/matplotlib.h @@ -57,7 +57,8 @@ std::string __XXX_YYY_ZZZ_COMMAND__(const std::string &cmd) { } static bool __XXX_YYY_ZZZ_INIT__() { - const std::string CONDA_PREFIX = getenv("CONDA_PREFIX"); + const char *conda_prefix = getenv("CONDA_PREFIX"); + const std::string CONDA_PREFIX = conda_prefix == NULL ? "" : conda_prefix; if (CONDA_PREFIX.empty()) { // do default python config } else { From db085c7cd7dfe17afb7c2cc523044b1150ead416 Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Wed, 28 Sep 2022 23:28:45 +0800 Subject: [PATCH 23/31] =?UTF-8?q?[09/28/2022]=20=E7=AE=80=E5=8C=96?= =?UTF-8?q?=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8F=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 简化环境变量获取 --- matplotlib.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/matplotlib.h b/matplotlib.h index acc8d3b..ffb8270 100644 --- a/matplotlib.h +++ b/matplotlib.h @@ -57,9 +57,7 @@ std::string __XXX_YYY_ZZZ_COMMAND__(const std::string &cmd) { } static bool __XXX_YYY_ZZZ_INIT__() { - const char *conda_prefix = getenv("CONDA_PREFIX"); - const std::string CONDA_PREFIX = conda_prefix == NULL ? "" : conda_prefix; - if (CONDA_PREFIX.empty()) { + if (getenv("CONDA_PREFIX") == NULL) { // do default python config } else { const std::string PYTHON_VERSION = __XXX_YYY_ZZZ_COMMAND__( From ecafe5e2ef457ff16665fb738057f5cf27639beb Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Thu, 29 Sep 2022 08:37:17 +0800 Subject: [PATCH 24/31] =?UTF-8?q?[09/29/2022]=20=E5=A2=9E=E5=8A=A0matplotl?= =?UTF-8?q?ib.h=E5=88=B0=E5=AE=89=E8=A3=85=E6=96=87=E4=BB=B6=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加matplotlib.h到安装文件中 --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d4b3f3..895d010 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,7 +105,8 @@ endif() # Install headers install(FILES - "${PROJECT_SOURCE_DIR}/matplotlibcpp.h" + ${PROJECT_SOURCE_DIR}/matplotlibcpp.h + ${PROJECT_SOURCE_DIR}/matplotlib.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) From b15e16af58f5aafb2a44ffa5169c0e6168f028af Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Thu, 29 Sep 2022 10:14:09 +0800 Subject: [PATCH 25/31] =?UTF-8?q?[09/29/2022]=20=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E5=86=85=E8=81=94=E5=87=BD=E6=95=B0=E6=9B=B4=E5=A5=BD=E7=9A=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=8F=AF=E8=AF=BB=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 使用内联函数更好的代码可读性 --- matplotlib.h | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/matplotlib.h b/matplotlib.h index ffb8270..6a4ca7f 100644 --- a/matplotlib.h +++ b/matplotlib.h @@ -1,7 +1,8 @@ -#ifndef _MATPLOTLIB_H -#define _MATPLOTLIB_H +#ifndef _XXX_YYY_ZZZ_MATPLOTLIB_H +#define _XXX_YYY_ZZZ_MATPLOTLIB_H #include +#include #include #include @@ -9,14 +10,10 @@ #define __XXX_YYY_ZZZ_POPEN___ _popen #define __XXX_YYY_ZZZ_PCLOSE___ _pclose #else -#include #define __XXX_YYY_ZZZ_POPEN___ popen #define __XXX_YYY_ZZZ_PCLOSE___ pclose #endif -#define PY_MAJOR_VERSION 3 -#include "matplotlibcpp.h" - std::string __XXX_YYY_ZZZ_STRIP__(const std::string &str, const std::string &whitespace = " \n\r\t\f\v") { @@ -26,7 +23,6 @@ __XXX_YYY_ZZZ_STRIP__(const std::string &str, return ""; } size_t to = str.find_last_not_of(whitespace); - assert(to != std::string::npos); return str.substr(from, (to - from) + 1); } @@ -57,21 +53,34 @@ std::string __XXX_YYY_ZZZ_COMMAND__(const std::string &cmd) { } static bool __XXX_YYY_ZZZ_INIT__() { - if (getenv("CONDA_PREFIX") == NULL) { + auto myenv = [](const std::string &name) { + const char *value = getenv(name.c_str()); + return std::string(value == NULL ? "" : value); + }; + const std::string CONDA_PREFIX = myenv("CONDA_PREFIX"); + if (CONDA_PREFIX.empty()) { // do default python config } else { const std::string PYTHON_VERSION = __XXX_YYY_ZZZ_COMMAND__( "python3 --version | cut -d ' ' -f2 | cut -d '.' -f-2"); +#ifdef _WIN32 + const std::string PYTHONHOME = CONDA_PREFIX + R"(\lib)"; + const std::string PYTHONPATH = PYTHONHOME + ";" + PYTHONHOME + + R"(\site-packages)"; + _putenv_s("PYTHONHOME", PYTHONHOME.c_str()); + _putenv_s("PYTHONPATH", PYTHONPATH.c_str()); +#else const std::string PYTHONHOME = - std::string(getenv("CONDA_PREFIX")) + "/lib/python" + PYTHON_VERSION; + CONDA_PREFIX + "/lib/python" + PYTHON_VERSION; const std::string PYTHONPATH = PYTHONHOME + ":" + PYTHONHOME + "/site-packages:" + PYTHONHOME + "/lib-dynload"; setenv("PYTHONHOME", PYTHONHOME.c_str(), 1); setenv("PYTHONPATH", PYTHONPATH.c_str(), 1); +#endif std::cout << "PYTHON_VERSION: " << PYTHON_VERSION << std::endl; - std::cout << "PYTHONHOME : " << getenv("PYTHONHOME") << std::endl; - std::cout << "PYTHONPATH : " << getenv("PYTHONPATH") << std::endl; + std::cout << "PYTHONHOME : " << myenv("PYTHONHOME") << std::endl; + std::cout << "PYTHONPATH : " << myenv("PYTHONPATH") << std::endl; } return true; @@ -79,4 +88,7 @@ static bool __XXX_YYY_ZZZ_INIT__() { static bool __UNUSED_XXX_YYY_ZZZ_INIT__ = __XXX_YYY_ZZZ_INIT__(); +#define PY_MAJOR_VERSION 3 +#include "matplotlibcpp.h" + #endif From 0dbf276aacd032d0918ede17de2dfeca5481718b Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Thu, 29 Sep 2022 21:33:03 +0800 Subject: [PATCH 26/31] [09/29/2022] ModuleNotFoundError: No module named '_ctypes' ModuleNotFoundError: No module named '_ctypes' --- matplotlib.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/matplotlib.h b/matplotlib.h index 6a4ca7f..a6a6473 100644 --- a/matplotlib.h +++ b/matplotlib.h @@ -66,7 +66,8 @@ static bool __XXX_YYY_ZZZ_INIT__() { #ifdef _WIN32 const std::string PYTHONHOME = CONDA_PREFIX + R"(\lib)"; const std::string PYTHONPATH = PYTHONHOME + ";" + PYTHONHOME + - R"(\site-packages)"; + R"(\site-packages;)" + CONDA_PREFIX + + R"(\DLLs)"; _putenv_s("PYTHONHOME", PYTHONHOME.c_str()); _putenv_s("PYTHONPATH", PYTHONPATH.c_str()); #else From 9ce4facf6b6f9a412bce4f0090358db42256d617 Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Fri, 30 Sep 2022 00:34:56 +0800 Subject: [PATCH 27/31] =?UTF-8?q?[09/30/2022]=20=E5=9C=A8Windows=E4=B8=8B?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0qt=E5=92=8Cqt=E7=8E=AF=E5=A2=83=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E4=BD=BF=E8=83=BDmatplotlib-cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在Windows下增加qt和qt环境变量使能matplotlib-cpp --- README.md | 1 + matplotlib.h | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/README.md b/README.md index b51e097..7bf0f1d 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ It is built to resemble the plotting API used by Matlab and matplotlib. ### Windows ```bash +conda install qt mkdir build cd build cmake .. -G "Visual Studio 15 2017 Win64" -DCMAKE_INSTALL_PREFIX=..\dist diff --git a/matplotlib.h b/matplotlib.h index a6a6473..a4e4c52 100644 --- a/matplotlib.h +++ b/matplotlib.h @@ -68,8 +68,12 @@ static bool __XXX_YYY_ZZZ_INIT__() { const std::string PYTHONPATH = PYTHONHOME + ";" + PYTHONHOME + R"(\site-packages;)" + CONDA_PREFIX + R"(\DLLs)"; + const std::string QT_QPA_PLATFORM_PLUGIN_PATH = + CONDA_PREFIX + R"(\Library\plugins\platforms)"; _putenv_s("PYTHONHOME", PYTHONHOME.c_str()); _putenv_s("PYTHONPATH", PYTHONPATH.c_str()); + _putenv_s("QT_QPA_PLATFORM_PLUGIN_PATH", + QT_QPA_PLATFORM_PLUGIN_PATH.c_str()); #else const std::string PYTHONHOME = CONDA_PREFIX + "/lib/python" + PYTHON_VERSION; From 7386656e70f01307c59d3570bb726231c2c55df8 Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Fri, 30 Sep 2022 00:41:48 +0800 Subject: [PATCH 28/31] =?UTF-8?q?[09/30/2022]=20=E5=9C=A8Windows=E5=92=8CU?= =?UTF-8?q?buntu=E4=B8=8B=E4=BD=BF=E7=94=A8=E4=B8=8D=E5=90=8C=E7=9A=84?= =?UTF-8?q?=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在Windows和Ubuntu下使用不同的输出 --- matplotlib.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/matplotlib.h b/matplotlib.h index a4e4c52..546f20c 100644 --- a/matplotlib.h +++ b/matplotlib.h @@ -61,8 +61,6 @@ static bool __XXX_YYY_ZZZ_INIT__() { if (CONDA_PREFIX.empty()) { // do default python config } else { - const std::string PYTHON_VERSION = __XXX_YYY_ZZZ_COMMAND__( - "python3 --version | cut -d ' ' -f2 | cut -d '.' -f-2"); #ifdef _WIN32 const std::string PYTHONHOME = CONDA_PREFIX + R"(\lib)"; const std::string PYTHONPATH = PYTHONHOME + ";" + PYTHONHOME + @@ -74,7 +72,15 @@ static bool __XXX_YYY_ZZZ_INIT__() { _putenv_s("PYTHONPATH", PYTHONPATH.c_str()); _putenv_s("QT_QPA_PLATFORM_PLUGIN_PATH", QT_QPA_PLATFORM_PLUGIN_PATH.c_str()); + std::cout << "PYTHONHOME : " << myenv("PYTHONHOME") + << std::endl; + std::cout << "PYTHONPATH : " << myenv("PYTHONPATH") + << std::endl; + std::cout << "QT_QPA_PLATFORM_PLUGIN_PATH: " + << myenv("QT_QPA_PLATFORM_PLUGIN_PATH") << std::endl; #else + const std::string PYTHON_VERSION = __XXX_YYY_ZZZ_COMMAND__( + "python3 --version | cut -d ' ' -f2 | cut -d '.' -f-2"); const std::string PYTHONHOME = CONDA_PREFIX + "/lib/python" + PYTHON_VERSION; const std::string PYTHONPATH = PYTHONHOME + ":" + PYTHONHOME + @@ -82,10 +88,10 @@ static bool __XXX_YYY_ZZZ_INIT__() { "/lib-dynload"; setenv("PYTHONHOME", PYTHONHOME.c_str(), 1); setenv("PYTHONPATH", PYTHONPATH.c_str(), 1); -#endif std::cout << "PYTHON_VERSION: " << PYTHON_VERSION << std::endl; std::cout << "PYTHONHOME : " << myenv("PYTHONHOME") << std::endl; std::cout << "PYTHONPATH : " << myenv("PYTHONPATH") << std::endl; +#endif } return true; From caeab2dfeb0bc19441b1250f0cd766f80ca1fa93 Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Fri, 30 Sep 2022 10:12:19 +0800 Subject: [PATCH 29/31] =?UTF-8?q?[09/30/2022]=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E6=AC=A1=E5=BA=8F=E6=BB=A1=E8=B6=B3Windows=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E7=8E=AF=E5=A2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 调整次序满足Windows开发环境 --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7bf0f1d..e39efa4 100644 --- a/README.md +++ b/README.md @@ -38,10 +38,6 @@ Complete minimal example: #include #include -#define PY_MAJOR_VERSION 3 -#include "matplotlibcpp.h" -#define plt matplotlibcpp - std::string to_strip(const std::string &str, const std::string &whitespace = " \n\r\t\f\v") { size_t from = str.find_first_not_of(whitespace); @@ -92,6 +88,11 @@ int main() { return 0; } + +#define PY_MAJOR_VERSION 3 +#include "matplotlibcpp.h" +#define plt matplotlibcpp + ``` **source**: [minimal.cpp](https://github.com/SNSerHello/matplotlib-cpp/blob/master/examples/minimal.cpp) From b4e551ec250e9c0b42b0fd04914a74834c6a4c2a Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Mon, 3 Oct 2022 22:33:54 +0800 Subject: [PATCH 30/31] =?UTF-8?q?[10/03/2022]=20=E4=BD=BF=E7=94=A8matplotl?= =?UTF-8?q?ib.h=E6=9D=A5=E7=AE=80=E5=8C=96=E7=A8=8B=E5=BA=8F=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 使用matplotlib.h来简化程序代码 --- README.md | 75 +++++-------------------------------------------------- 1 file changed, 6 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index e39efa4..dfb7165 100644 --- a/README.md +++ b/README.md @@ -33,66 +33,14 @@ Usage Complete minimal example: ```cpp -#include -#include -#include -#include - -std::string to_strip(const std::string &str, - const std::string &whitespace = " \n\r\t\f\v") { - size_t from = str.find_first_not_of(whitespace); - - if (from == std::string::npos) { - return ""; - } - size_t to = str.find_last_not_of(whitespace); - assert(to != std::string::npos); - - return str.substr(from, (to - from) + 1); -} - -std::string COMMAND(const std::string &cmd) { - using pipe_ptr = std::unique_ptr; - pipe_ptr pipe(popen(cmd.c_str(), "r"), pclose); - if (pipe == nullptr) { - std::cout << "error: failed to execute: " << cmd << std::endl; - return ""; - } - - const int BUF_SIZE = 1023; - char buf[BUF_SIZE + 1]; - buf[BUF_SIZE] = '\0'; - std::stringstream out; - while (fgets(buf, BUF_SIZE, pipe.get()) != NULL) { - out << buf; - } - pclose(pipe.release()); - - return out.str(); -} +#include int main() { - // 增加环境变量设置可以免除在运行的时候手动的增加 - const std::string PYTHON_VERSION = - to_strip(COMMAND("python3 --version | cut -d ' ' -f2 | cut -d '.' -f-2")); - const std::string PYTHONHOME = - std::string(getenv("CONDA_PREFIX")) + "/lib/python" + PYTHON_VERSION; - const std::string PYTHONPATH = PYTHONHOME + ":" + PYTHONHOME + - "/site-packages:" + PYTHONHOME + - "/lib-dynload"; - setenv("PYTHONHOME", PYTHONHOME.c_str(), 1); - setenv("PYTHONPATH", PYTHONPATH.c_str(), 1); - plt::plot({1,3,2,4}); plt::show(); return 0; } - -#define PY_MAJOR_VERSION 3 -#include "matplotlibcpp.h" -#define plt matplotlibcpp - ``` **source**: [minimal.cpp](https://github.com/SNSerHello/matplotlib-cpp/blob/master/examples/minimal.cpp) @@ -117,8 +65,6 @@ g++ minimal.cpp \ **Anaconda环境下运行** ```bash -export PYTHONHOME=$CONDA_PREFIX/lib/python3.7 -export PYTHONPATH=$PYTHONHOME:$PYTHONHOME/site-packages:$PYTHONHOME/lib-dynload ./minimal ``` @@ -128,11 +74,9 @@ export PYTHONPATH=$PYTHONHOME:$PYTHONHOME/site-packages:$PYTHONHOME/lib-dynload A more comprehensive example: ```cpp -#include "matplotlibcpp.h" +#include "matplotlib.h" #include -namespace plt = matplotlibcpp; - int main() { // Prepare data. @@ -173,10 +117,9 @@ g++ basic.cpp -I/usr/include/python3.7 -lpython3.7 Alternatively, matplotlib-cpp also supports some C++11-powered syntactic sugar: ```cpp #include -#include "matplotlibcpp.h" +#include "matplotlib.h" using namespace std; -namespace plt = matplotlibcpp; int main() { @@ -209,12 +152,10 @@ g++ modern.cpp -std=c++11 -I/usr/include/python3.7 -lpython3.7 Or some *funny-looking xkcd-styled* example: ```cpp -#include "matplotlibcpp.h" +#include "matplotlib.h" #include #include -namespace plt = matplotlibcpp; - int main() { std::vector t(1000); std::vector x(t.size()); @@ -241,9 +182,7 @@ g++ xkcd.cpp -std=c++11 -I/usr/include/python3.7 -lpython3.7 When working with vector fields, you might be interested in quiver plots: ```cpp -#include "../matplotlibcpp.h" - -namespace plt = matplotlibcpp; +#include "../matplotlib.h" int main() { @@ -270,9 +209,7 @@ int main() When working with 3d functions, you might be interested in 3d plots: ```cpp -#include "../matplotlibcpp.h" - -namespace plt = matplotlibcpp; +#include "../matplotlib.h" int main() { From bf699db5a01cd8c59878168aca3ff020cceef8f3 Mon Sep 17 00:00:00 2001 From: SNSerHello Date: Sat, 8 Oct 2022 21:38:46 +0800 Subject: [PATCH 31/31] =?UTF-8?q?[10/08/2022]=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=97=A0=E7=94=A8=E7=9A=84=E5=88=86=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 删除无用的分号 --- examples/basic.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/basic.cpp b/examples/basic.cpp index aaab1e2..1d920bd 100644 --- a/examples/basic.cpp +++ b/examples/basic.cpp @@ -39,6 +39,5 @@ int main() { // save figure const char *filename = "./basic.png"; std::cout << "Saving result to " << filename << std::endl; - ; plt::save(filename); }