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); } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy