├── .clang-format ├── .dir-locals.el ├── .github └── workflows │ └── main.yml ├── .gitignore ├── .gitmodules ├── .pre-commit-config.yaml ├── CMakeLists.txt ├── LICENSE ├── README.md ├── cmake ├── matplotlibcpp17Config.cmake.in ├── package.cmake └── uninstall.cmake.in ├── doc ├── Doxyfile ├── custom.css ├── footer.html └── header.html ├── gallery ├── artist_animation │ ├── CMakeLists.txt │ ├── animate_decay.cpp │ ├── cla_pause.cpp │ └── random_walk.cpp ├── contrib │ ├── sombrero.cpp │ └── sombrero.png ├── images │ ├── README.md │ ├── align_labels_demo.png │ ├── animate_decay.gif │ ├── bar_label_demo1.png │ ├── bar_label_demo2.png │ ├── bar_label_demo3.png │ ├── fill.png │ ├── fill_between_demo_1.png │ ├── fill_between_demo_2.png │ ├── fill_between_demo_3.png │ ├── fill_betweenx_demo.png │ ├── gridspec_multicolumn.png │ ├── hello_world.png │ ├── hist1.png │ ├── hist3.png │ ├── image_demo.png │ ├── lines3d.png │ ├── lorenz_attractor.png │ ├── multiple_figs_demo1.png │ ├── multiple_figs_demo2.png │ ├── multiple_figs_demo3.png │ ├── patch_collection.png │ ├── patches_circle_rectangle.png │ ├── quiver_demo_1.png │ ├── quiver_demo_2.png │ ├── quiver_demo_3.png │ ├── random_walk.gif │ ├── scatter_hist1.png │ ├── scatter_hist2.png │ ├── scatter_symbol.png │ ├── scatter_with_legend1.png │ ├── scatter_with_legend2.png │ └── simple_plot.png ├── images_contours_and_fields │ ├── .gitignore │ ├── CMakeLists.txt │ ├── contourf_log.cpp │ ├── image_demo.cpp │ └── quiver_demo.cpp ├── lines_bars_and_markers │ ├── .gitignore │ ├── CMakeLists.txt │ ├── bar_label_demo.cpp │ ├── errorbar_limits_simple.cpp │ ├── errorbar_subsample.cpp │ ├── fill.cpp │ ├── fill_between_demo.cpp │ ├── fill_betweenx_demo.cpp │ ├── scatter_hist.cpp │ ├── scatter_symbol.cpp │ ├── scatter_with_legend.cpp │ ├── simple_plot.cpp │ └── step_demo.cpp ├── mplot3d │ ├── CMakeLists.txt │ ├── contour3d.cpp │ ├── errorbar3d.cpp │ ├── lines3d.cpp │ ├── lorenz_attractor.cpp │ ├── subplot3d.cpp │ └── surface3d.cpp ├── scales │ ├── CMakeLists.txt │ └── aspect_loglog.cpp ├── shapes_and_collections │ ├── CMakeLists.txt │ ├── patch_collection.cpp │ └── patches_circle_rectangle.cpp ├── statistics │ ├── .gitignore │ ├── CMakeLists.txt │ ├── errorbar.cpp │ └── hist.cpp ├── subplots_axes_and_figures │ ├── .gitignore │ ├── CMakeLists.txt │ ├── align_labels_demo.cpp │ ├── colorbar_placement.cpp │ ├── gridspec_multicolumn.cpp │ ├── multiple_figs_demo.cpp │ ├── subplots.cpp │ └── two_scales.cpp └── tests │ ├── CMakeLists.txt │ ├── test_shared_lib │ ├── CMakeLists.txt │ ├── test_lib.cpp │ ├── test_lib.h │ └── test_lib_main.cpp │ └── test_static_lib │ ├── CMakeLists.txt │ ├── test_lib.cpp │ ├── test_lib.h │ └── test_lib_main.cpp ├── hello_world ├── CMakeLists.txt └── hello_world.cpp └── include └── matplotlibcpp17 ├── animation.h ├── axes.h ├── cm.h ├── collections.h ├── common.h ├── container.h ├── figure.h ├── gridspec.h ├── legend.h ├── mplot3d.h ├── patches.h ├── pyplot.h ├── quiver.h ├── text.h └── ticker.h /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | IndentWidth: 2 3 | NamespaceIndentation: None 4 | Language: Cpp 5 | Standard: Auto 6 | ColumnLimit: 80 7 | SortIncludes: false 8 | -------------------------------------------------------------------------------- /.dir-locals.el: -------------------------------------------------------------------------------- 1 | ((c++-mode . ((mode . clang-format+)))) 2 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: doc 2 | 3 | on: 4 | # Triggers the workflow on push or pull request events but only for the master branch 5 | push: 6 | branches: [ master ] 7 | 8 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 9 | jobs: 10 | # This workflow contains a single job called "build" 11 | build: 12 | # The type of runner that the job will run on 13 | runs-on: ubuntu-latest 14 | 15 | # Steps represent a sequence of tasks that will be executed as part of the job 16 | steps: 17 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 18 | - name: checkout 19 | uses: actions/checkout@v2 20 | with: 21 | submodules: true 22 | 23 | - name: doxygen 24 | uses: mattnotmitt/doxygen-action@v1.9.2 25 | with: 26 | working-directory: 'doc/' 27 | doxyfile-path: './Doxyfile' 28 | 29 | - name: deploy 30 | uses: JamesIves/github-pages-deploy-action@v4.2.3 31 | with: 32 | branch: gh-pages 33 | folder: doc/html 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.png 2 | doc/html -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "doc/doxygen-awesome-css"] 2 | path = doc/doxygen-awesome-css 3 | url = https://github.com/jothepro/doxygen-awesome-css.git 4 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/pre-commit-hooks 3 | rev: v3.2.0 4 | hooks: 5 | - id: trailing-whitespace 6 | id: end-of-file-fixer 7 | id: check-yaml 8 | id: check-added-large-files 9 | 10 | # CMake formatting 11 | - repo: https://github.com/cheshirekow/cmake-format-precommit 12 | rev: "v0.6.13" 13 | hooks: 14 | - id: cmake-format 15 | additional_dependencies: [pyyaml] 16 | types: [file] 17 | files: (\.cmake|CMakeLists.txt)(.in)?$ 18 | 19 | # Clang format the codebase automatically 20 | - repo: https://github.com/pre-commit/mirrors-clang-format 21 | rev: "v13.0.1" 22 | hooks: 23 | - id: clang-format 24 | types_or: [c++, c] 25 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | project( 4 | "matplotlibcpp17" 5 | VERSION 1.0.4 6 | DESCRIPTION 7 | "A C++ header-only plotting library based on pybind11 and matplotlib, featuring more flexibility than matplotlibcpp" 8 | HOMEPAGE_URL "https://soblin.github.io/matplotlibcpp17/") 9 | 10 | find_package( 11 | Python3 12 | COMPONENTS Interpreter Development 13 | REQUIRED) 14 | find_package(pybind11 2.4.3 REQUIRED) 15 | 16 | # ############################################################################## 17 | # (1) check matplotlib minor version 18 | # ############################################################################## 19 | execute_process( 20 | COMMAND ${Python3_EXECUTABLE} "-c" "import matplotlib; 21 | print(str(matplotlib.__version__), end='')" 22 | RESULT_VARIABLE MATPLOTLIB_VERSION_CHECKING 23 | OUTPUT_VARIABLE MATPLOTLIB_VERSION) 24 | if(NOT MATPLOTLIB_VERSION_CHECKING MATCHES 0) 25 | message(FATAL_ERROR "Could not check matplotlib.__version__") 26 | endif() 27 | message(STATUS "Detected matplotlib version is ${MATPLOTLIB_VERSION}") 28 | if(${MATPLOTLIB_VERSION} VERSION_LESS 3.4) 29 | message(WARNING "Detected matplotlib version is < 3.4.0") 30 | set(MATPLOTLIB_MINOR_VER_GTE_4 0) 31 | else() 32 | message(STATUS "Detected matplotlib version is >= 3.4.0") 33 | set(MATPLOTLIB_MINOR_VER_GTE_4 1) 34 | endif() 35 | 36 | # ############################################################################## 37 | # (2) for add_subdirectory 38 | # ############################################################################## 39 | add_library(matplotlibcpp17::matplotlibcpp17 INTERFACE IMPORTED GLOBAL) 40 | set_property( 41 | TARGET matplotlibcpp17::matplotlibcpp17 42 | PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/include 43 | ${Python3_INCLUDE_DIRS}) 44 | set_property( 45 | TARGET matplotlibcpp17::matplotlibcpp17 46 | PROPERTY INTERFACE_LINK_LIBRARIES ${Python3_LIBRARIES} pybind11::embed) 47 | 48 | # ############################################################################## 49 | # (3) install 50 | # ############################################################################## 51 | # https://dominikberner.ch/cmake-interface-lib/ 52 | include(GNUInstallDirs) 53 | # header-only library(INTERFACE) 54 | add_library(${PROJECT_NAME} INTERFACE) 55 | install( 56 | TARGETS ${PROJECT_NAME} 57 | EXPORT ${PROJECT_NAME}_Targets 58 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 59 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) 60 | include(CMakePackageConfigHelpers) 61 | write_basic_package_version_file( 62 | "${PROJECT_NAME}ConfigVersion.cmake" 63 | VERSION ${PROJECT_VERSION} 64 | COMPATIBILITY SameMajorVersion) 65 | configure_package_config_file( 66 | "${PROJECT_SOURCE_DIR}/cmake/${PROJECT_NAME}Config.cmake.in" 67 | "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" 68 | INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}) 69 | # to /share/cmake/matplotlibcpp17 70 | install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" 71 | "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" 72 | DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}) 73 | # to /share/cmake/matplotlibcpp17 74 | install( 75 | EXPORT ${PROJECT_NAME}_Targets 76 | FILE ${PROJECT_NAME}Targets.cmake 77 | NAMESPACE ${PROJECT_NAME}:: 78 | DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}) 79 | # to /include/matplotlibcpp17 80 | install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME} 81 | DESTINATION include) 82 | set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE") 83 | # create .deb 84 | include("${PROJECT_SOURCE_DIR}/cmake/package.cmake") 85 | 86 | target_include_directories( 87 | ${PROJECT_NAME} 88 | INTERFACE $ 89 | $) 90 | target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_17) 91 | 92 | # ############################################################################## 93 | # (4) uninstall 94 | # ############################################################################## 95 | # https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake 96 | if(NOT TARGET uninstall) 97 | configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/uninstall.cmake.in" 98 | "${CMAKE_CURRENT_BINARY_DIR}/uninstall.cmake" IMMEDIATE @ONLY) 99 | add_custom_target( 100 | uninstall COMMAND ${CMAKE_COMMAND} -P 101 | ${CMAKE_CURRENT_BINARY_DIR}/uninstall.cmake) 102 | endif() 103 | 104 | # ############################################################################## 105 | # (5) gallery 106 | # ############################################################################## 107 | if(NOT DEFINED USE_GUI) 108 | set(USE_GUI 0) 109 | message(STATUS "set USE_GUI = OFF") 110 | endif() 111 | if(NOT DEFINED ADD_DEMO) 112 | set(ADD_DEMO 0) 113 | message(STATUS "set ADD_DEMO = OFF") 114 | endif() 115 | if(USE_GUI) 116 | message(STATUS "USE_GUI = ON") 117 | else() 118 | message(STATUS "USE_GUI = OFF") 119 | endif() 120 | if(ADD_DEMO) 121 | message(STATUS "ADD_DEMO = ON") 122 | else() 123 | message(STATUS "ADD_DEMO = OFF") 124 | endif() 125 | 126 | function(add_demo name path) 127 | add_executable(${name} ${path}) 128 | target_link_libraries(${name} xtensor matplotlibcpp17::matplotlibcpp17) 129 | endfunction() 130 | 131 | if(${ADD_DEMO}) 132 | find_package( 133 | Python3 134 | COMPONENTS NumPy 135 | REQUIRED) 136 | find_package(xtensor 0.24.0 REQUIRED) 137 | set(CMAKE_CXX_STANDARD 17) 138 | set(CMAKE_CXX_FLAGS 139 | "-Wall -g -DUSE_GUI=${USE_GUI} -DMATPLOTLIB_MINOR_VER_GTE_4=${MATPLOTLIB_MINOR_VER_GTE_4}" 140 | ) 141 | add_subdirectory(gallery/tests) 142 | add_subdirectory(gallery/lines_bars_and_markers) 143 | add_subdirectory(gallery/subplots_axes_and_figures) 144 | add_subdirectory(gallery/statistics) 145 | add_subdirectory(gallery/images_contours_and_fields) 146 | add_subdirectory(gallery/shapes_and_collections) 147 | add_subdirectory(gallery/artist_animation) 148 | add_subdirectory(gallery/mplot3d) 149 | add_subdirectory(gallery/scales) 150 | endif() 151 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Mamoru Sobue 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # matplotlibcpp17 2 | 3 | A C++ header-only library for matplotlib based on pybind 4 | 5 | ----- 6 | 7 | [matplotlibcpp17](https://github.com/soblin/matplotlibcpp17) is an yet another C++ library for matplotlib featuring more functionalities than matplotlibcpp. 8 | 9 | It is supposed to provide the user with almost full access to matplotlib features in C++, by implementing as many *wrapper classes* of matplotlib module as possible (like `axes::Axes`, `figure::Figure`). And its primary advantage over conventional matplotlibcpp is that the user can pass a variety of arguments as in the form of *args* and *kwargs* thanks to pybind11, without the need for coversion to `map`, thus leading to more flexibility. 10 | 11 | ## Dependencies 12 | 13 | - [pybind11](https://github.com/pybind/pybind11) >= 2.4.3 14 | - `sudo apt install pybind11-dev` (on Ubuntu20.04) 15 | - or manual install 16 | - [matplotlib](https://matplotlib.org/stable/index.html) >= 3.4.0 17 | - numpy for `mplot3d` 18 | - ([xtensor](https://github.com/xtensor-stack/xtensor) == 0.24.0 + [xtl](https://github.com/xtensor-stack/xtl), only for `gallery` demos) 19 | 20 | ## Usage 21 | 22 | ### Installation 23 | 24 | ```bash 25 | $ mdkir build; cd build; 26 | $ cmake .. -DADD_DEMO=0 (-DCMAKE_INSTALL_PREFIX=) 27 | $ make -j 28 | $ make install 29 | $ (make uninstall) 30 | ``` 31 | 32 | For using matplotlibcpp17 from CMakeLists.txt, see [hello_world](https://github.com/soblin/matplotlibcpp17/tree/master/hello_world) example. 33 | 34 | ```bash 35 | find_package(matplotlibcpp17) 36 | ... 37 | target_link_libraries(a.out matplotlibcpp17::matplotlibcpp17) 38 | ``` 39 | 40 | ### Use by add_subdirectory 41 | 42 | ```bash 43 | add_subdirectory(path to matplotlibcpp17) 44 | ... 45 | target_link_libraries(a.out matplotlibcpp17::matplotlibcpp17) 46 | ``` 47 | 48 | ### Include matplotlibcpp17 directly 49 | 50 | descibed in [minimal example](#minimal-example). 51 | 52 | ## Syntax 53 | 54 | The user will need to capsulate *arguments* in `Args(arg1, arg2, ...) == pybind11:tuple` and *keyword arguments* in `Kwargs("k1"_a = v1, "k2"_a = v2, ...) == pybind11::dict`. The returned value is a wrapper class for pybind. Please refer to the reference and examples below. 55 | - exception: `subplots`, `TBD`s 56 | - conversion: Wrapper class of matplotlibcpp17 like [::container::BarContainer](https://github.com/soblin/matplotlibcpp17/blob/master/include/matplotlibcpp17/container.h) needs to be passed to python interpreter using `unwrap()` method in *args* and *kwargs*. 57 | 58 | ## Examples 59 | 60 | ### minimal example 61 | 62 | ```cpp 63 | g++ ./hello_world/hello_world.cpp -std=c++17 -I./include -I/usr/include/python3.x -I -lpython3.x 64 | ./a.out 65 | ``` 66 | 67 | gives 68 | 69 | ![minimal example](./gallery/images/hello_world.png) 70 | 71 | ### subplots 72 | 73 | From [gallery/subplots_axes_and_figures/align_labels_demo.cpp](https://github.com/soblin/matplotlibcpp17/blob/master/gallery/subplots_axes_and_figures/align_labels_demo.cpp). 74 | 75 | - [original python code](https://matplotlib.org/stable/gallery/subplots_axes_and_figures/align_labels_demo.html) 76 | 77 | ```cpp 78 | auto plt = matplotlibcpp17::pyplot::import(); 79 | 80 | // corresponding wrapper class for returned value is implemented in this library 81 | /// gs is of type gridspec::GridSpec 82 | auto gs = GridSpec(2, 2); 83 | 84 | /// pass wrapper class object like gs[0, :] of ::gridspec::SubplotSpec to the interpreter using .unwrap() method as python object 85 | auto ax = fig.add_subplot(Args(gs(0, py::slice(0, 2, 1)).unwrap())); 86 | 87 | ax.plot(Args(arange(0, 1000000, 10000))); 88 | ax.set_ylabel(Args("YLabel0")); 89 | ax.set_xlabel(Args("XLabel0")); 90 | ``` 91 | 92 | ![subplots_axes_and_figures](./gallery/images/align_labels_demo.png) 93 | 94 | ### bar plot 95 | 96 | From [gallery/lines_bars_and_markers/bar_label_demo.cpp](https://github.com/soblin/matplotlibcpp17/blob/master/gallery/lines_bars_and_markers/bar_label_demo.cpp). Here `subplots()` returns `tuple`. 97 | 98 | - [original python code](https://matplotlib.org/stable/gallery/lines_bars_and_markers/bar_label_demo.html) 99 | 100 | ```cpp 101 | auto [fig, ax] = plt.subplots(); 102 | auto p1 = ax.bar(Args(ind, menMeans, width), 103 | Kwargs("yerr"_a = menStd, "label"_a = "Men")); 104 | auto p2 = ax.bar( 105 | Args(ind, womenMeans, width), 106 | Kwargs("bottom"_a = menMeans, "yerr"_a = womenStd, "label"_a = "Women")); 107 | ax.axhline(Args(0), Kwargs("color"_a = "grey", "linewidth"_a = 0.8)); 108 | ax.set_ylabel(Args("Scores")); 109 | ax.set_title(Args("Scores by group and gender")); 110 | 111 | ax.set_xticks(Args(ind, py::make_tuple("G1", "G2", "G3", "G4", "G5"))); 112 | ax.legend(); 113 | 114 | // pass wrapper class object like p1 of ::container::BarContainer to the interpreter using .unwrap() method as python object 115 | ax.bar_label(Args(p1.unwrap()), Kwargs("label_type"_a = "center")); 116 | ax.bar_label(Args(p2.unwrap()), Kwargs("label_type"_a = "center")); 117 | ax.bar_label(Args(p2.unwrap())); 118 | plt.show(); 119 | ``` 120 | 121 | ![bar_label_demo1](./gallery/images/bar_label_demo1.png) 122 | 123 | ### image 124 | 125 | 2D-style pybind11 array can be plotted as an image using `imshow()` function. 126 | 127 | From [images_contours_and_fields/image_demo](https://github.com/soblin/matplotlibcpp17/blob/master/gallery/images_contours_and_fields/image_demo.cpp) 128 | 129 | - [original python code](https://matplotlib.org/stable/gallery/images_contours_and_fields/image_demo.html) 130 | 131 | ```cpp 132 | vector> Z2D{...}; 133 | auto Zpy = py::array(py::cast(std::move(Z2D))); 134 | ax.imshow(Args(Zpy), Kwargs("interpolation"_a = "bilinear", 135 | "cmap"_a = "RdYlGn", "origin"_a = "lower", 136 | "extent"_a = py::make_tuple(-3, 3, -3, 3), 137 | "vmax"_a = vmax, "vmin"_a = vmin)); 138 | ``` 139 | 140 | ![image_demo](./gallery/images/image_demo.png) 141 | 142 | ### fill 143 | 144 | Fucntions like `subplots`, `TBD`s are overloaded because they return different types depending on the arguments. Here `subplots()` returns `tuple>`. 145 | 146 | From [gallery/lines_bars_and_markers](https://github.com/soblin/matplotlibcpp17/blob/master/gallery/lines_bars_and_markers/fill.cpp) 147 | 148 | - [original python code](https://matplotlib.org/stable/gallery/lines_bars_and_markers/fill.html) 149 | 150 | ```cpp 151 | auto [fig, axes] = 152 | plt.subplots(1, 3, 153 | Kwargs("figsize"_a = py::make_tuple(9, 3), 154 | "subplot_kw"_a = py::dict("aspect"_a = "equal"))); 155 | auto ax1 = axes[0], ax2 = axes[1], ax3 = axes[2]; 156 | ``` 157 | 158 | ![fill](./gallery/images/fill.png) 159 | 160 | ### quiver 161 | 162 | Use `.unwrap()` method to pass wrapper class of matplotlibcpp17 to plotting functions. 163 | 164 | From [gallery/images_contours_and_fields/quiver_demo.cpp](https://github.com/soblin/matplotlibcpp17/blob/master/gallery/images_contours_and_fields/quiver_demo.cpp) 165 | 166 | - [original python code](https://matplotlib.org/stable/gallery/images_contours_and_fields/quiver_demo.html) 167 | 168 | ```cpp 169 | auto plt = matplotlibcpp17::pyplot::import(); 170 | auto [fig1, ax1] = plt.subplots(); 171 | ax1.set_title(Args("Arrows scale with plot width, not view")); 172 | auto Q = ax1.quiver(Args(X, Y, U, V, M), 173 | Kwargs("units"_a = "x", "pivot"_a = "tip", 174 | "width"_a = 0.022, "scale"_a = 1.0 / 0.15)); 175 | auto qk = 176 | ax1.quiverkey(Args(Q.unwrap(), 0.9, 0.9, 1, R"($1 \frac{m}{s}$)"), 177 | Kwargs("labelpos"_a = "E", "coordinates"_a = "figure")); 178 | ax1.scatter(Args(X, Y), Kwargs("color"_a = "0.5", "s"_a = 1)); 179 | ``` 180 | 181 | ![quiver_demo3](./gallery/images/quiver_demo_3.png) 182 | 183 | ### 3D 184 | 185 | To plot 3D graph with `projection = "3d"`, following code is required. 186 | 187 | ```cpp 188 | #include 189 | 190 | matplotlibcpp17::mplot3d::import(); 191 | ``` 192 | 193 | ### gif 194 | 195 | Currently only `ArtistAnimation` is supported. `FuncAnimation` interface maybe implemented in the future. 196 | 197 | From [gallery/artist_animation/random_walk.cpp](https://github.com/soblin/matplotlibcpp17/blob/master/gallery/artist_animation/random_walk.cpp) 198 | 199 | - [original python code](https://matplotlib.org/stable/gallery/animation/random_walk.html) 200 | 201 | ![random_walk](./gallery/images/random_walk.gif) 202 | 203 | ## Demos 204 | 205 | `gallery` folder contains corresponding examples from [the official website of matplotlib](https://matplotlib.org/stable/gallery) with the same structure. 206 | 207 | ### build 208 | 209 | If you want to build the demos, use `-DADD_DEMO=1` (by default it is `0`). 210 | 211 | ```bash 212 | $ mkdir build; cd build 213 | $ cmake .. -DADD_DEMO={0, 1} -DUSE_GUI={0, 1} 214 | $ make -j 215 | ``` 216 | 217 | If you do not need to see the demo with `plt.show()`, use `-DUSE_GUI=1` (by default it is `0`). Otherwise the executables will `plt.savefig()` to `gallery/images` directory. 218 | 219 | `make ` runs all the executables under that directory. 220 | 221 | ```bash 222 | make lines_bars_and_markers 223 | ``` 224 | 225 | ## Contributing 226 | 227 | Contributions to this project are welcome if you could add or want/need more modules :) 228 | -------------------------------------------------------------------------------- /cmake/matplotlibcpp17Config.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") 4 | check_required_components("@PROJECT_NAME@") 5 | -------------------------------------------------------------------------------- /cmake/package.cmake: -------------------------------------------------------------------------------- 1 | # https://decovar.dev/blog/2021/09/23/cmake-cpack-package-deb-apt/ 2 | set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) 3 | set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${CMAKE_PROJECT_DESCRIPTION}) 4 | set(CPACK_VERBATIM_VARIABLES YES) 5 | set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME}) 6 | SET(CPACK_OUTPUT_FILE_PREFIX "${PROJECT_BINARY_DIR}/") 7 | set(CPACK_PACKAGING_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}) 8 | set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) 9 | set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) 10 | set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) 11 | set(CPACK_PACKAGE_CONTACT "example@example.com") 12 | set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Deb Example") 13 | set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") 14 | set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md") 15 | # package name for deb 16 | set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) 17 | set(CPACK_COMPONENTS_GROUPING ALL_COMPONENTS_IN_ONE) 18 | # without this you won't be able to pack only specified component 19 | set(CPACK_DEB_COMPONENT_INSTALL YES) 20 | 21 | include(CPack) 22 | 23 | # run cpack -G DEB to create .deb 24 | -------------------------------------------------------------------------------- /cmake/uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") 2 | message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") 3 | endif() 4 | 5 | file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) 6 | string(REGEX REPLACE "\n" ";" files "${files}") 7 | foreach(file ${files}) 8 | message(STATUS "Uninstalling $ENV{DESTDIR}${file}") 9 | if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 10 | exec_program( 11 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 12 | OUTPUT_VARIABLE rm_out 13 | RETURN_VALUE rm_retval 14 | ) 15 | if(NOT "${rm_retval}" STREQUAL 0) 16 | message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") 17 | endif() 18 | else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 19 | message(STATUS "File $ENV{DESTDIR}${file} does not exist.") 20 | endif() 21 | endforeach() 22 | -------------------------------------------------------------------------------- /doc/custom.css: -------------------------------------------------------------------------------- 1 | @media screen and (max-width: 767px) { 2 | .github-corner svg { 3 | width: 55px; 4 | height: 55px; 5 | } 6 | #projectnumber { 7 | margin-right: 22px; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /doc/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 14 | 19 | 20 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /doc/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | $projectname: $title 11 | $title 12 | 13 | 14 | 15 | 16 | 17 | $treeview 18 | $search 19 | $mathjax 20 | 21 | $extrastylesheet 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 44 | 45 | 46 | 47 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
39 |
$projectname 40 |  $projectnumber 41 |
42 |
$projectbrief
43 |
48 |
$projectbrief
49 |
$searchbox
60 |
61 | 62 | 63 | -------------------------------------------------------------------------------- /gallery/artist_animation/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_demo(cla_pause cla_pause.cpp) 2 | add_demo(animate_decay animate_decay.cpp) 3 | add_demo(random_walk random_walk.cpp) 4 | 5 | add_custom_target( 6 | artist_animation 7 | DEPENDS cla_pause animate_decay 8 | COMMAND cla_pause 9 | COMMAND animate_decay 10 | COMMAND random_walk 11 | COMMENT "running artist_animation" 12 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../images") 13 | -------------------------------------------------------------------------------- /gallery/artist_animation/animate_decay.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/animation/animate_decay.html 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | using namespace std; 10 | using namespace matplotlibcpp17; 11 | using matplotlibcpp17::animation::ArtistAnimation; 12 | 13 | int main() { 14 | py::scoped_interpreter guard{}; 15 | auto plt = matplotlibcpp17::pyplot::import(); 16 | const int N = 200; 17 | vector ts, ys; 18 | auto [fig, ax] = plt.subplots(); 19 | ax.set_xlim(Args(0, 10)); 20 | ax.set_ylim(Args(-1.1, 1.1)); 21 | py::list artist_list; 22 | for (int i = 0; i < N; ++i) { 23 | double t = i * 1.0 / 10; 24 | double y = sin(2 * M_PI * t) * exp(-t * 1.0 / 10); 25 | ts.push_back(t); 26 | ys.push_back(y); 27 | auto [xmin, xmax] = ax.get_xlim(); 28 | if (t >= xmax) 29 | ax.set_xlim(Args(xmin, 2 * xmax)); 30 | auto line = ax.plot(Args(ts, ys), Kwargs("color"_a = "blue", "lw"_a = 1)); 31 | artist_list.append(line.unwrap()); 32 | } 33 | auto ani = ArtistAnimation(Args(fig.unwrap(), artist_list), 34 | Kwargs("interval"_a = 10)); 35 | #if USE_GUI 36 | plt.show(); 37 | #else 38 | ani.save(Args("animate_decay.gif"), Kwargs("writer"_a = "pillow")); 39 | #endif 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /gallery/artist_animation/cla_pause.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | using namespace std; 6 | using namespace matplotlibcpp17; 7 | 8 | int main() { 9 | py::scoped_interpreter guard{}; 10 | auto plt = matplotlibcpp17::pyplot::import(); 11 | vector data; 12 | const int N = 10; 13 | for (int i = 0; i <= N; ++i) { 14 | plt.xlim(Args(0, 10)); 15 | plt.ylim(Args(0, 10)); 16 | data.push_back(i); 17 | plt.plot(Args(data)); 18 | plt.pause(Args(1)); 19 | plt.cla(); 20 | } 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /gallery/artist_animation/random_walk.cpp: -------------------------------------------------------------------------------- 1 | // example from https://matplotlib.org/stable/gallery/animation/random_walk.html 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | using namespace std; 15 | using namespace matplotlibcpp17; 16 | using matplotlibcpp17::animation::ArtistAnimation; 17 | 18 | xt::xtensor random_walk(int num_steps, double max_step = 0.05) { 19 | auto start_pos = xt::random::rand({3, 1}); 20 | auto steps_ = xt::random::rand({3, num_steps}, -max_step, max_step); 21 | auto steps = xt::hstack(xt::xtuple(start_pos, steps_)); // {3, num_steps+1} 22 | auto walk = xt::cumsum(steps, 1); // {3, num_steps+1} 23 | return walk; 24 | } 25 | 26 | int main() { 27 | static const int M = 4; 28 | const int num_steps = 30; 29 | const vector colors = {"r", "g", "b", "orange"}; // #M 30 | auto walks = xt::xtensor::from_shape({M, 3, num_steps + 1}); 31 | for (int i = 0; i < M; ++i) { 32 | auto walk = xt::view(walks, i, xt::all(), xt::all()); 33 | walk = random_walk(num_steps); 34 | } 35 | py::scoped_interpreter guard{}; 36 | auto plt = matplotlibcpp17::pyplot::import(); 37 | // this is required for "projection = 3d" 38 | matplotlibcpp17::mplot3d::import(); 39 | auto fig = plt.figure(); 40 | auto ax = fig.add_subplot(py::make_tuple(), Kwargs("projection"_a = "3d")); 41 | py::list artist_list; 42 | for (int j = 1; j <= num_steps; ++j) { 43 | for (int i = 0; i < M; ++i) { 44 | const auto xs0 = xt::view(walks, i, 0, xt::range(1, j + 1)); 45 | const auto ys0 = xt::view(walks, i, 1, xt::range(1, j + 1)); 46 | const auto zs0 = xt::view(walks, i, 2, xt::range(1, j + 1)); 47 | // to vector 48 | vector xs(xs0.begin(), xs0.end()); 49 | vector ys(ys0.begin(), ys0.end()); 50 | vector zs(zs0.begin(), zs0.end()); 51 | ax.plot(Args(xs, ys, zs), Kwargs("color"_a = colors[i])); 52 | } 53 | artist_list.append(ax.get_lines().unwrap()); 54 | } 55 | auto ani = ArtistAnimation(Args(fig.unwrap(), artist_list), 56 | Kwargs("interval"_a = 100)); 57 | #if USE_GUI 58 | plt.show(); 59 | #else 60 | ani.save(Args("random_walk.gif"), Kwargs("writer"_a = "pillow")); 61 | #endif 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /gallery/contrib/sombrero.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | pybind11::scoped_interpreter guard{}; 6 | 7 | const int size = 1000; 8 | const double sigma = 100; 9 | 10 | const auto i = nc::arange(size) - (0.5 * size); 11 | const auto [x, y] = nc::meshgrid(i, i); 12 | 13 | const auto xy = 14 | (nc::power(x, 2) + nc::power(y, 2)) / (-2.0 * nc::power(sigma, 2)); 15 | 16 | const auto sombrero = 17 | nc::exp(xy) * (xy + 1.0) / (std::acos(-1.0) * nc::power(sigma, 4)); 18 | const auto pysombrero = nc::pybindInterface::nc2pybind(sombrero); 19 | 20 | const auto min = nc::min(sombrero)[0]; 21 | const auto max = nc::max(sombrero)[0]; 22 | 23 | auto plt = matplotlibcpp17::pyplot::import(); 24 | 25 | plt.imshow(Args(pysombrero), 26 | Kwargs("extent"_a = pybind11::make_tuple(-1, +1, -1, +1), 27 | "cmap"_a = "inferno")); 28 | 29 | plt.colorbar(); 30 | 31 | plt.clim(pybind11::make_tuple(min * 0.8, max * 0.8)); 32 | 33 | plt.show(); 34 | 35 | return 0; 36 | } -------------------------------------------------------------------------------- /gallery/contrib/sombrero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/contrib/sombrero.png -------------------------------------------------------------------------------- /gallery/images/README.md: -------------------------------------------------------------------------------- 1 | generated figures 2 | -------------------------------------------------------------------------------- /gallery/images/align_labels_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/align_labels_demo.png -------------------------------------------------------------------------------- /gallery/images/animate_decay.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/animate_decay.gif -------------------------------------------------------------------------------- /gallery/images/bar_label_demo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/bar_label_demo1.png -------------------------------------------------------------------------------- /gallery/images/bar_label_demo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/bar_label_demo2.png -------------------------------------------------------------------------------- /gallery/images/bar_label_demo3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/bar_label_demo3.png -------------------------------------------------------------------------------- /gallery/images/fill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/fill.png -------------------------------------------------------------------------------- /gallery/images/fill_between_demo_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/fill_between_demo_1.png -------------------------------------------------------------------------------- /gallery/images/fill_between_demo_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/fill_between_demo_2.png -------------------------------------------------------------------------------- /gallery/images/fill_between_demo_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/fill_between_demo_3.png -------------------------------------------------------------------------------- /gallery/images/fill_betweenx_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/fill_betweenx_demo.png -------------------------------------------------------------------------------- /gallery/images/gridspec_multicolumn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/gridspec_multicolumn.png -------------------------------------------------------------------------------- /gallery/images/hello_world.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/hello_world.png -------------------------------------------------------------------------------- /gallery/images/hist1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/hist1.png -------------------------------------------------------------------------------- /gallery/images/hist3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/hist3.png -------------------------------------------------------------------------------- /gallery/images/image_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/image_demo.png -------------------------------------------------------------------------------- /gallery/images/lines3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/lines3d.png -------------------------------------------------------------------------------- /gallery/images/lorenz_attractor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/lorenz_attractor.png -------------------------------------------------------------------------------- /gallery/images/multiple_figs_demo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/multiple_figs_demo1.png -------------------------------------------------------------------------------- /gallery/images/multiple_figs_demo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/multiple_figs_demo2.png -------------------------------------------------------------------------------- /gallery/images/multiple_figs_demo3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/multiple_figs_demo3.png -------------------------------------------------------------------------------- /gallery/images/patch_collection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/patch_collection.png -------------------------------------------------------------------------------- /gallery/images/patches_circle_rectangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/patches_circle_rectangle.png -------------------------------------------------------------------------------- /gallery/images/quiver_demo_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/quiver_demo_1.png -------------------------------------------------------------------------------- /gallery/images/quiver_demo_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/quiver_demo_2.png -------------------------------------------------------------------------------- /gallery/images/quiver_demo_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/quiver_demo_3.png -------------------------------------------------------------------------------- /gallery/images/random_walk.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/random_walk.gif -------------------------------------------------------------------------------- /gallery/images/scatter_hist1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/scatter_hist1.png -------------------------------------------------------------------------------- /gallery/images/scatter_hist2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/scatter_hist2.png -------------------------------------------------------------------------------- /gallery/images/scatter_symbol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/scatter_symbol.png -------------------------------------------------------------------------------- /gallery/images/scatter_with_legend1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/scatter_with_legend1.png -------------------------------------------------------------------------------- /gallery/images/scatter_with_legend2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/scatter_with_legend2.png -------------------------------------------------------------------------------- /gallery/images/simple_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soblin/matplotlibcpp17/4d025b5975b701598fce8487cd8feaf82eb5923f/gallery/images/simple_plot.png -------------------------------------------------------------------------------- /gallery/images_contours_and_fields/.gitignore: -------------------------------------------------------------------------------- 1 | *.png 2 | -------------------------------------------------------------------------------- /gallery/images_contours_and_fields/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_demo(quiver_demo quiver_demo.cpp) 2 | add_demo(contourf_log contourf_log) 3 | add_demo(image_demo image_demo) 4 | 5 | add_custom_target( 6 | images_contours_and_fields 7 | DEPENDS quiver_demo contourf_log image_demo 8 | COMMAND quiver_demo 9 | COMMAND contourf_log 10 | COMMAND image_demo 11 | COMMENT "running images_contours_and_fields" 12 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../images") 13 | -------------------------------------------------------------------------------- /gallery/images_contours_and_fields/contourf_log.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/images_contours_and_fields/contourf_log.html 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | using namespace std; 15 | using namespace matplotlibcpp17; 16 | using namespace xt::placeholders; 17 | 18 | using mesh2D = vector>; 19 | 20 | int main() { 21 | const int N = 100; 22 | const auto x_ = xt::linspace(-3.0, 3.0, N); 23 | const auto y_ = xt::linspace(-2.0, 2.0, N); 24 | 25 | const auto [X_, Y_] = xt::meshgrid(x_, y_); 26 | const auto Z1_ = xt::exp(-xt::pow(X_, 2) - xt::pow(Y_, 2)); 27 | const auto Z2_ = xt::exp(-xt::pow(X_ * 10, 2) - xt::pow(Y_ * 10, 2)); 28 | xt::xarray z_ = Z1_ + 50 * Z2_; 29 | // instead of x[:5, :5] = -1.0 30 | auto v = xt::view(z_, xt::range(_, 5), xt::range(_, 5)); 31 | v = 0.0; 32 | // to vector> 33 | const int xsz = x_.shape()[0], ysz = y_.shape()[0]; 34 | mesh2D X(xsz), Y(xsz), z(xsz); 35 | for (int i = 0; i < xsz; ++i) { 36 | X[i].resize(ysz); 37 | Y[i].resize(ysz); 38 | z[i].resize(ysz); 39 | for (int j = 0; j < ysz; ++j) { 40 | X[i][j] = X_(i, j); 41 | Y[i][j] = Y_(i, j); 42 | z[i][j] = z_(i, j); 43 | } 44 | } 45 | 46 | py::scoped_interpreter guard{}; 47 | // to numpy array 48 | const auto Xpy = py::array(py::cast(std::move(X))); 49 | const auto Ypy = py::array(py::cast(std::move(Y))); 50 | const auto zpy = py::array(py::cast(std::move(z))); 51 | auto plt = pyplot::import(); 52 | auto [fig, ax] = plt.subplots(); 53 | auto cs = ax.contourf(Args(Xpy, Ypy, zpy), 54 | Kwargs("locator"_a = ticker::LogLocator().unwrap(), 55 | "cmap"_a = cm::PuBu_r)); 56 | fig.colorbar(Args(cs.unwrap())); 57 | plt.show(); 58 | } 59 | -------------------------------------------------------------------------------- /gallery/images_contours_and_fields/image_demo.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/images_contours_and_fields/image_demo.html 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | using namespace matplotlibcpp17; 16 | 17 | using mesh2D = vector>; 18 | 19 | int main() { 20 | const double delta = 0.025; 21 | const auto x = xt::arange(-3.0, 3.0, delta); 22 | const auto [X_, Y_] = xt::meshgrid(x, x); 23 | const auto Z1_ = xt::exp(-xt::pow(X_, 2) - xt::pow(Y_, 2)); 24 | const auto Z2_ = xt::exp(-xt::pow(X_ - 1, 2) - xt::pow(Y_ - 1, 2)); 25 | const auto Z_ = (Z1_ - Z2_) * 2.0; 26 | 27 | // to vector 28 | vector X(X_.begin(), X_.end()), Y(Y_.begin(), Y_.end()), 29 | Z1(Z1_.begin(), Z1_.end()), Z2(Z2_.begin(), Z2_.end()); 30 | // to vector 31 | const int xsz = x.shape()[0], ysz = x.shape()[0]; 32 | mesh2D Z2D(xsz); 33 | for (int i = 0; i < xsz; ++i) { 34 | Z2D[i].resize(ysz); 35 | for (int j = 0; j < ysz; ++j) { 36 | Z2D[i][j] = Z_(i, j); 37 | } 38 | } 39 | 40 | py::scoped_interpreter guard{}; 41 | auto plt = matplotlibcpp17::pyplot::import(); 42 | auto [fig, ax] = plt.subplots(); 43 | const double vmax = *max_element(Z_.begin(), Z_.end()), 44 | vmin = *min_element(Z_.begin(), Z_.end()); 45 | const auto Zpy = py::array(py::cast(std::move(Z2D))); 46 | ax.imshow(Args(Zpy), Kwargs("interpolation"_a = "bilinear", 47 | "cmap"_a = cm::RdYlGn, "origin"_a = "lower", 48 | "extent"_a = py::make_tuple(-3, 3, -3, 3), 49 | "vmax"_a = vmax, "vmin"_a = vmin)); 50 | #if USE_GUI 51 | plt.show(); 52 | #else 53 | plt.savefig(Args("image_demo.png")); 54 | #endif 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /gallery/images_contours_and_fields/quiver_demo.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/images_contours_and_fields/quiver_demo.html 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | using namespace matplotlibcpp17; 15 | 16 | int main1() { 17 | const auto [X0, Y0] = xt::meshgrid(xt::arange(0.0, 2 * M_PI, 0.2), 18 | xt::arange(0.0, 2 * M_PI, 0.2)); 19 | const auto U0 = xt::cos(X0); 20 | const auto V0 = xt::sin(Y0); 21 | // to vector 22 | vector X(X0.begin(), X0.end()), Y(Y0.begin(), Y0.end()), 23 | U(U0.begin(), U0.end()), V(V0.begin(), V0.end()); 24 | 25 | auto plt = matplotlibcpp17::pyplot::import(); 26 | auto [fig1, ax1] = plt.subplots(); 27 | ax1.set_title(Args("Arrows scale with plot width, not view")); 28 | auto Q = ax1.quiver(Args(X, Y, U, V), Kwargs("units"_a = "width")); 29 | auto qk = 30 | ax1.quiverkey(Args(Q.unwrap(), 0.9, 0.9, 2, R"($2 \frac{m}{s}$)"), 31 | Kwargs("labelpos"_a = "E", "coordinates"_a = "figure")); 32 | #if USE_GUI 33 | plt.show(); 34 | #else 35 | plt.savefig(Args("quiver_demo_1.png")); 36 | #endif 37 | return 0; 38 | } 39 | 40 | int main2() { 41 | const auto [X0, Y0] = xt::meshgrid(xt::arange(0.0, 2 * M_PI, 0.6), 42 | xt::arange(0.0, 2 * M_PI, 0.6)); 43 | const auto U0 = xt::cos(X0); 44 | const auto V0 = xt::sin(Y0); 45 | // to vector 46 | vector X(X0.begin(), X0.end()), Y(Y0.begin(), Y0.end()), 47 | U(U0.begin(), U0.end()), V(V0.begin(), V0.end()); 48 | 49 | auto plt = matplotlibcpp17::pyplot::import(); 50 | auto [fig1, ax1] = plt.subplots(); 51 | ax1.set_title(Args("pivot='mid'; every third arrow; units='inches'")); 52 | auto Q = ax1.quiver(Args(X, Y, U, V), 53 | Kwargs("pivot"_a = "mid", "units"_a = "inches")); 54 | auto qk = 55 | ax1.quiverkey(Args(Q.unwrap(), 0.9, 0.9, 1, R"($1 \frac{m}{s}$)"), 56 | Kwargs("labelpos"_a = "E", "coordinates"_a = "figure")); 57 | ax1.scatter(Args(X, Y), Kwargs("color"_a = "r", "s"_a = 5)); 58 | 59 | #if USE_GUI 60 | plt.show(); 61 | #else 62 | plt.savefig(Args("quiver_demo_2.png")); 63 | #endif 64 | return 0; 65 | } 66 | 67 | int main3() { 68 | const auto [X0, Y0] = xt::meshgrid(xt::arange(0.0, 2 * M_PI, 0.2), 69 | xt::arange(0.0, 2 * M_PI, 0.2)); 70 | const auto U0 = xt::cos(X0); 71 | const auto V0 = xt::sin(Y0); 72 | const auto M0 = xt::hypot(U0, V0); 73 | vector X(X0.begin(), X0.end()), Y(Y0.begin(), Y0.end()), 74 | U(U0.begin(), U0.end()), V(V0.begin(), V0.end()), M(M0.begin(), M0.end()); 75 | 76 | auto plt = matplotlibcpp17::pyplot::import(); 77 | auto [fig1, ax1] = plt.subplots(); 78 | ax1.set_title(Args("pivot='tip'; scales with x view")); 79 | auto Q = ax1.quiver(Args(X, Y, U, V, M), 80 | Kwargs("units"_a = "x", "pivot"_a = "tip", 81 | "width"_a = 0.022, "scale"_a = 1.0 / 0.15)); 82 | auto qk = 83 | ax1.quiverkey(Args(Q.unwrap(), 0.9, 0.9, 1, R"($1 \frac{m}{s}$)"), 84 | Kwargs("labelpos"_a = "E", "coordinates"_a = "figure")); 85 | ax1.scatter(Args(X, Y), Kwargs("color"_a = "0.5", "s"_a = 1)); 86 | 87 | #if USE_GUI 88 | plt.show(); 89 | #else 90 | plt.savefig(Args("quiver_demo_3.png")); 91 | #endif 92 | 93 | return 0; 94 | } 95 | 96 | int main() { 97 | py::scoped_interpreter guard{}; 98 | main1(); 99 | main2(); 100 | main3(); 101 | } 102 | -------------------------------------------------------------------------------- /gallery/lines_bars_and_markers/.gitignore: -------------------------------------------------------------------------------- 1 | *.png 2 | -------------------------------------------------------------------------------- /gallery/lines_bars_and_markers/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_demo(bar_label_demo bar_label_demo.cpp) 2 | add_demo(fill fill.cpp) 3 | add_demo(simple_plot simple_plot.cpp) 4 | add_demo(scatter_symbol scatter_symbol.cpp) 5 | add_demo(fill_between_demo fill_between_demo.cpp) 6 | add_demo(fill_betweenx_demo fill_betweenx_demo.cpp) 7 | add_demo(scatter_with_legend scatter_with_legend.cpp) 8 | add_demo(scatter_hist scatter_hist.cpp) 9 | add_demo(errorbar_limits_simple errorbar_limits_simple.cpp) 10 | add_demo(errorbar_subsample errorbar_subsample.cpp) 11 | add_demo(step_demo step_demo.cpp) 12 | 13 | add_custom_target( 14 | lines_bars_and_markers 15 | DEPENDS bar_label_demo 16 | fill 17 | simple_plot 18 | scatter_symbol 19 | fill_between_demo 20 | fill_betweenx_demo 21 | scatter_with_legend 22 | scatter_hist 23 | errorbar_limits_simple 24 | errorbar_subsample 25 | step_demo 26 | COMMAND bar_label_demo 27 | COMMAND fill 28 | COMMAND simple_plot 29 | COMMAND scatter_symbol 30 | COMMAND fill_between_demo 31 | COMMAND fill_betweenx_demo 32 | COMMAND scatter_with_legend 33 | COMMAND scatter_hist 34 | COMMAND errorbar_limits_simple 35 | COMMAND errorbar_subsample 36 | COMMAND step_demo 37 | COMMENT "running lines_bars_and_markers" 38 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../images") 39 | -------------------------------------------------------------------------------- /gallery/lines_bars_and_markers/bar_label_demo.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/lines_bars_and_markers/bar_label_demo.html 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | using namespace matplotlibcpp17; 12 | 13 | int main1() { 14 | const vector menMeans = {20, 35, 30, 35, -27}; 15 | const vector womenMeans = {25, 32, 34, 20, -25}; 16 | const vector menStd = {2, 3, 4, 1, 2}; 17 | const vector womenStd = {3, 5, 2, 3, 3}; 18 | const vector ind = {0, 1, 2, 3, 4}; // the x locations for the groups 19 | const double width = 20 | 0.35; // the width of the bars: can also be len(x) sequence 21 | auto plt = matplotlibcpp17::pyplot::import(); 22 | auto [fig, ax] = plt.subplots(); 23 | auto p1 = ax.bar(Args(ind, menMeans, width), 24 | Kwargs("yerr"_a = menStd, "label"_a = "Men")); 25 | auto p2 = ax.bar( 26 | Args(ind, womenMeans, width), 27 | Kwargs("bottom"_a = menMeans, "yerr"_a = womenStd, "label"_a = "Women")); 28 | ax.axhline(Args(0), Kwargs("color"_a = "grey", "linewidth"_a = 0.8)); 29 | ax.set_ylabel(Args("Scores")); 30 | ax.set_title(Args("Scores by group and gender")); 31 | ax.set_xticks(Args(ind, py::make_tuple("G1", "G2", "G3", "G4", "G5"))); 32 | ax.legend(); 33 | 34 | // Label with label_type 'center' instead of the default 'edge' 35 | ax.bar_label(Args(p1.unwrap()), Kwargs("label_type"_a = "center")); 36 | ax.bar_label(Args(p2.unwrap()), Kwargs("label_type"_a = "center")); 37 | ax.bar_label(Args(p2.unwrap())); 38 | #if USE_GUI 39 | plt.show(); 40 | #else 41 | plt.savefig(Args("bar_label_demo1.png")); 42 | #endif 43 | return 0; 44 | } 45 | 46 | int main2() { 47 | const vector people = {"Tom", "Dick", "Harry", "Slim", "Jim"}; 48 | const vector y_pos = {0, 1, 2, 3, 4}; 49 | const vector performance = {10.00367304, 10.42750809, 10.09280011, 50 | 8.66745522, 12.77785333}; 51 | const vector error = {0.70633485, 0.24791576, 0.15788335, 0.69769852, 52 | 0.71995667}; 53 | auto plt = matplotlibcpp17::pyplot::import(); 54 | auto [fig, ax] = plt.subplots(); 55 | auto hbars = ax.barh(Args(y_pos, performance), 56 | Kwargs("xerr"_a = error, "align"_a = "center")); 57 | ax.set_yticks(Args(y_pos), Kwargs("labels"_a = people)); 58 | ax.invert_yaxis(); // labels read top-to-bottom 59 | ax.set_xlabel(Args("Performance")); 60 | ax.set_title(Args("How fast do you want to go today?")); 61 | 62 | // Label with specially formatted floats 63 | ax.bar_label(Args(hbars.unwrap()), Kwargs("fmt"_a = "%.2f")); 64 | ax.set_xlim(Args(), Kwargs("right"_a = 15)); // adjust xlim to fit labels 65 | #if USE_GUI 66 | plt.show(); 67 | #else 68 | plt.savefig(Args("bar_label_demo2.png")); 69 | #endif 70 | return 0; 71 | } 72 | 73 | int main3() { 74 | const vector people = {"Tom", "Dick", "Harry", "Slim", "Jim"}; 75 | const vector y_pos = {0, 1, 2, 3, 4}; 76 | const vector performance = {10.00367304, 10.42750809, 10.09280011, 77 | 8.66745522, 12.77785333}; 78 | const vector error = {0.70633485, 0.24791576, 0.15788335, 0.69769852, 79 | 0.71995667}; 80 | auto plt = matplotlibcpp17::pyplot::import(); 81 | auto [fig, ax] = plt.subplots(); 82 | auto hbars = ax.barh(Args(y_pos, performance), 83 | Kwargs("xerr"_a = error, "align"_a = "center")); 84 | ax.set_yticks(Args(y_pos), Kwargs("labels"_a = people)); 85 | ax.invert_yaxis(); // labels read top-to-bottom 86 | ax.set_xlabel(Args("Performance")); 87 | ax.set_title(Args("How fast do you want to go today?")); 88 | 89 | // Label with specially formatted floats 90 | vector labels; 91 | transform(error.begin(), error.end(), back_inserter(labels), [](double e) { 92 | stringstream stm; 93 | stm << std::fixed << std::setprecision(2) << e; 94 | return "±" + stm.str(); 95 | }); 96 | ax.bar_label(Args(hbars.unwrap()), 97 | Kwargs("labels"_a = labels, "padding"_a = 8, "color"_a = "b", 98 | "fontsize"_a = 14)); 99 | ax.set_xlim(Args(), Kwargs("right"_a = 15)); // adjust xlim to fit labels 100 | #if USE_GUI 101 | plt.show(); 102 | #else 103 | plt.savefig(Args("bar_label_demo3.png")); 104 | #endif 105 | return 0; 106 | } 107 | 108 | int main() { 109 | py::scoped_interpreter guard{}; 110 | main1(); 111 | main2(); 112 | main3(); 113 | return 0; 114 | } 115 | -------------------------------------------------------------------------------- /gallery/lines_bars_and_markers/errorbar_limits_simple.cpp: -------------------------------------------------------------------------------- 1 | // example 2 | // https://matplotlib.org/stable/gallery/lines_bars_and_markers/errorbar_limits_simple.html 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace matplotlibcpp17; 13 | 14 | int main() { 15 | py::scoped_interpreter guard{}; 16 | auto plt = pyplot::import(); 17 | auto fig = plt.figure(); 18 | const auto x_ = xt::arange(0.0, 10.0, 1.0); 19 | const auto y_ = 2.5 * xt::sin(x_ / 20 * M_PI); 20 | const auto y1_ = y_ + 1.0, y2_ = y_ + 2.0, y3_ = y_ + 3.0; 21 | const auto yerr_ = xt::linspace(0.05, 0.2, 10); 22 | const vector x(x_.begin(), x_.end()), y(y_.begin(), y_.end()), 23 | yerr(yerr_.begin(), yerr_.end()), y3(y3_.begin(), y3_.end()), 24 | y2(y2_.begin(), y2_.end()), y1(y1_.begin(), y1_.end()); 25 | plt.errorbar(Args(x, y3), 26 | Kwargs("yerr"_a = yerr, "label"_a = "both limits (default)")); 27 | plt.errorbar(Args(x, y2), Kwargs("yerr"_a = yerr, "uplims"_a = true, 28 | "label"_a = "uplims=True")); 29 | plt.errorbar(Args(x, y1), 30 | Kwargs("yerr"_a = yerr, "uplims"_a = true, "lolims"_a = true, 31 | "label"_a = "uplims=True, lolims=True")); 32 | 33 | vector upperlimits, lowerlimits; 34 | for (auto i : {0, 1, 2, 3, 4}) { 35 | upperlimits.push_back(true); 36 | upperlimits.push_back(false); 37 | lowerlimits.push_back(false); 38 | lowerlimits.push_back(true); 39 | } 40 | plt.errorbar(Args(x, y), Kwargs("yerr"_a = yerr, "uplims"_a = upperlimits, 41 | "lolims"_a = lowerlimits, 42 | "label"_a = "subsets of uplims and lolims")); 43 | plt.legend(Args(), Kwargs("loc"_a = "lower right")); 44 | #if USE_GUI 45 | plt.show(); 46 | #else 47 | plt.savefig(Args("errorbar_limits_simple.png")); 48 | #endif 49 | } 50 | -------------------------------------------------------------------------------- /gallery/lines_bars_and_markers/errorbar_subsample.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/lines_bars_and_markers/errorbar_subsample.html 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace matplotlibcpp17; 13 | 14 | int main() { 15 | const auto x_ = xt::arange(0.1, 4.0, 0.1); 16 | const auto y1_ = xt::exp(-1.0 * x_); 17 | const auto y2_ = xt::exp(-0.5 * x_); 18 | const auto y1err_ = 0.1 + 0.1 * xt::sqrt(x_); 19 | const auto y2err_ = 0.1 + 0.1 * xt::sqrt(x_ / 2.0); 20 | const vector x(x_.begin(), x_.end()), y1(y1_.begin(), y1_.end()), 21 | y2(y2_.begin(), y2_.end()), y1err(y1err_.begin(), y1err_.end()), 22 | y2err(y2err_.begin(), y2err_.end()); 23 | 24 | py::scoped_interpreter guard{}; 25 | auto plt = pyplot::import(); 26 | auto [fig, axs] = plt.subplots( 27 | 1, 3, Kwargs("sharex"_a = true, "figsize"_a = py::make_tuple(12, 6))); 28 | auto ax0 = axs[0], ax1 = axs[1], ax2 = axs[2]; 29 | ax0.set_title(Args("all errorbars")); 30 | ax0.errorbar(Args(x, y1), Kwargs("yerr"_a = y1err)); 31 | ax0.errorbar(Args(x, y1), Kwargs("yerr"_a = y2err)); 32 | 33 | ax1.set_title(Args("only every 6th errorbar")); 34 | ax1.errorbar(Args(x, y1), Kwargs("yerr"_a = y1err, "errorevery"_a = 6)); 35 | ax1.errorbar(Args(x, y2), Kwargs("yerr"_a = y2err, "errorevery"_a = 6)); 36 | 37 | // TODO: TypeError: '<' not supported between instances of 'tuple' and 'int' 38 | /* 39 | ax2.set_title(Args("second seris shifted by 3")); 40 | ax2.errorbar(Args(x, y1), 41 | Kwargs("yerr"_a = y1err, "errorevery"_a = py::make_tuple(0, 6))); 42 | ax2.errorbar(Args(x, y2), 43 | Kwargs("yerr"_a = y2err, "errorevery"_a = py::make_tuple(3, 6))); 44 | */ 45 | 46 | fig.suptitle(Args("Errorbar subsampling")); 47 | #if USE_GUI 48 | plt.show(); 49 | #else 50 | plt.savefig(Args("erorbar_subsample.png")); 51 | #endif 52 | } 53 | -------------------------------------------------------------------------------- /gallery/lines_bars_and_markers/fill.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/lines_bars_and_markers/fill.html 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | 10 | using namespace std; 11 | using namespace matplotlibcpp17; 12 | 13 | int main() { 14 | const double scale = 10; 15 | const xt::xarray angles = {90.0, 210.0, 330.0}; 16 | const auto x0 = scale / sqrt(3.0) * xt::cos(angles / 360.0 * 2 * M_PI); 17 | const auto y0 = scale / sqrt(3.0) * xt::sin(angles / 360.0 * 2 * M_PI); 18 | const vector x(x0.begin(), x0.end()); 19 | const vector y(y0.begin(), y0.end()); 20 | 21 | py::scoped_interpreter guard{}; 22 | auto plt = matplotlibcpp17::pyplot::import(); 23 | auto [fig, axes] = 24 | plt.subplots(1, 3, 25 | Kwargs("figsize"_a = py::make_tuple(9, 3), 26 | "subplot_kw"_a = py::dict("aspect"_a = "equal"))); 27 | auto ax1 = axes[0], ax2 = axes[1], ax3 = axes[2]; 28 | ax1.fill(Args(x, y)); 29 | ax2.fill(Args(x, y), Kwargs("facecolor"_a = "lightsalmon", 30 | "edgecolor"_a = "orangered", "linewidth"_a = 3)); 31 | ax3.fill(Args(x, y), Kwargs("facecolor"_a = "none", "edgecolor"_a = "purple", 32 | "linewidth"_a = 3)); 33 | #if USE_GUI 34 | plt.show(); 35 | #else 36 | plt.savefig(Args("fill.png")); 37 | #endif 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /gallery/lines_bars_and_markers/fill_between_demo.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/lines_bars_and_markers/fill_between_demo.html 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | using namespace matplotlibcpp17; 15 | 16 | int main1() { 17 | const auto x_ = xt::arange(0.0, 2.0, 0.01); 18 | const auto y1_ = xt::sin(2 * M_PI * x_); 19 | const auto y2_ = 0.8 * xt::sin(4 * M_PI * x_); 20 | const vector x(x_.begin(), x_.end()), y1(y1_.begin(), y1_.end()), 21 | y2(y2_.begin(), y2_.end()); 22 | 23 | auto plt = matplotlibcpp17::pyplot::import(); 24 | auto [fig, axes] = plt.subplots( 25 | 3, 1, Kwargs("sharex"_a = true, "figsize"_a = py::make_tuple(6, 6))); 26 | auto ax1 = axes[0], ax2 = axes[1], ax3 = axes[2]; 27 | ax1.fill_between(Args(x, y1)); 28 | ax1.set_title(Args("fill between y1 and 0")); 29 | 30 | ax2.fill_between(Args(x, y1, 1)); 31 | ax2.set_title(Args("fill between y1 and 1")); 32 | 33 | ax3.fill_between(Args(x, y1, y2)); 34 | ax3.set_title(Args("fill between y1 and y2")); 35 | ax3.set_xlabel(Args("x")); 36 | fig.tight_layout(); 37 | #if USE_GUI 38 | plt.show(); 39 | #else 40 | plt.savefig(Args("fill_between_demo_1.png")); 41 | #endif 42 | return 0; 43 | } 44 | 45 | int main2() { 46 | auto plt = matplotlibcpp17::pyplot::import(); 47 | 48 | const vector x = {0, 1, 2, 3}; 49 | const vector y1 = {0.8, 0.8, 0.2, 0.2}; 50 | const vector y2 = {0, 0, 1, 1}; 51 | auto [fig, axs] = plt.subplots(2, 1, Kwargs("sharex"_a = true)); 52 | auto ax1 = axs[0], ax2 = axs[1]; 53 | 54 | ax1.set_title(Args("interpolation=False")); 55 | ax1.plot(Args(x, y1, "o--")); 56 | ax1.plot(Args(x, y2, "o--")); 57 | vector where = {true, true, false, false}; 58 | ax1.fill_between(Args(x, y1, y2), Kwargs("where"_a = where, "color"_a = "C0", 59 | "alpha"_a = 0.3)); 60 | where = {false, false, true, true}; 61 | ax1.fill_between(Args(x, y1, y2), Kwargs("where"_a = where, "color"_a = "C1", 62 | "alpha"_a = 0.3)); 63 | 64 | ax2.set_title(Args("interpolation=True")); 65 | ax2.plot(Args(x, y1, "o--")); 66 | ax2.plot(Args(x, y2, "o--")); 67 | where = {true, true, false, false}; 68 | ax2.fill_between(Args(x, y1, y2), 69 | Kwargs("where"_a = where, "color"_a = "C0", "alpha"_a = 0.3, 70 | "interpolate"_a = true)); 71 | where = {false, false, true, true}; 72 | ax2.fill_between(Args(x, y1, y2), 73 | Kwargs("where"_a = where, "color"_a = "C1", "alpha"_a = 0.3, 74 | "interpolate"_a = true)); 75 | fig.tight_layout(); 76 | #if USE_GUI 77 | plt.show(); 78 | #else 79 | plt.savefig(Args("fill_between_demo_2.png")); 80 | #endif 81 | return 0; 82 | } 83 | 84 | int main3() { 85 | auto plt = matplotlibcpp17::pyplot::import(); 86 | auto [fig, ax] = plt.subplots(); 87 | 88 | const auto x0 = xt::arange(0.0, 4 * M_PI, 0.01); 89 | const auto y0 = xt::sin(x0); 90 | vector x(x0.begin(), x0.end()), y(y0.begin(), y0.end()); 91 | ax.plot(Args(x, y), Kwargs("color"_a = "black")); 92 | const double threshold = 0.75; 93 | vector where; 94 | transform(y.begin(), y.end(), back_inserter(where), 95 | [&threshold](double y) { return y > threshold; }); 96 | ax.fill_between(Args(x, 0, 1), 97 | Kwargs("where"_a = where, "color"_a = "green", 98 | "alpha"_a = 0.5, 99 | "transform"_a = ax.get_xaxis_transform().unwrap())); 100 | #if USE_GUI 101 | plt.show(); 102 | #else 103 | plt.savefig(Args("fill_between_demo_3.png")); 104 | #endif 105 | return 0; 106 | } 107 | 108 | int main() { 109 | py::scoped_interpreter guard{}; 110 | main1(); 111 | main2(); 112 | main3(); 113 | } 114 | -------------------------------------------------------------------------------- /gallery/lines_bars_and_markers/fill_betweenx_demo.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/lines_bars_and_markers/fill_betweenx_demo.html 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace matplotlibcpp17; 13 | 14 | int main1() { 15 | auto plt = matplotlibcpp17::pyplot::import(); 16 | const auto y_ = xt::arange(0.0, 2.0, 0.01); 17 | const auto x1_ = xt::sin(2 * M_PI * y_); 18 | const auto x2_ = 1.2 * xt::sin(4 * M_PI * y_); 19 | const vector y(y_.begin(), y_.end()), x1(x1_.begin(), x1_.end()), 20 | x2(x2_.begin(), x2_.end()); 21 | 22 | auto [fig, axes] = plt.subplots( 23 | 1, 3, Kwargs("sharey"_a = true, "figsize"_a = py::make_tuple(6, 6))); 24 | auto ax1 = axes[0], ax2 = axes[1], ax3 = axes[2]; 25 | 26 | ax1.fill_betweenx(Args(y, 0, x1)); 27 | ax1.set_title(Args("between (x1, 0)")); 28 | 29 | ax2.fill_betweenx(Args(y, x1, 1)); 30 | ax2.set_title(Args("between (x1, 1)")); 31 | ax2.set_xlabel(Args("x")); 32 | 33 | ax3.fill_betweenx(Args(y, x1, x2)); 34 | ax3.set_title(Args("between (x1, x2)")); 35 | 36 | #if USE_GUI 37 | plt.show(); 38 | #else 39 | plt.savefig(Args("fill_betweenx_demo.png")); 40 | #endif 41 | return 0; 42 | } 43 | 44 | int main() { 45 | py::scoped_interpreter guard{}; 46 | main1(); 47 | } 48 | -------------------------------------------------------------------------------- /gallery/lines_bars_and_markers/scatter_hist.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/lines_bars_and_markers/scatter_hist.html 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | using namespace matplotlibcpp17; 14 | 15 | int main() { 16 | int N = 1000; 17 | const auto x_ = xt::random::randn({N}); 18 | const auto y_ = xt::random::randn({N}); 19 | const vector x(x_.begin(), x_.end()), y(y_.begin(), y_.end()); 20 | py::scoped_interpreter guard{}; 21 | auto plt = matplotlibcpp17::pyplot::import(); 22 | // cell1 23 | { 24 | const double left = 0.1, width = 0.65; 25 | const double bottom = 0.1, height = 0.65; 26 | const double spacing = 0.005; 27 | const vector rect_scatter = {left, bottom, width, height}; 28 | const vector rect_histx = {left, bottom + height + spacing, width, 29 | 0.2}; 30 | const vector rect_histy = {left + width + spacing, bottom, 0.2, 31 | height}; 32 | auto fig = plt.figure(Args(), Kwargs("figsize"_a = py::make_tuple(8, 8))); 33 | auto ax = fig.add_axes(Args(rect_scatter)); 34 | auto ax_histx = 35 | fig.add_axes(Args(rect_histx), Kwargs("sharex"_a = ax.unwrap())); 36 | auto ax_histy = 37 | fig.add_axes(Args(rect_histy), Kwargs("sharey"_a = ax.unwrap())); 38 | ax_histx.tick_params(Args(), 39 | Kwargs("axis"_a = "x", "labelbottom"_a = false)); 40 | ax_histy.tick_params(Args(), Kwargs("axis"_a = "y", "labelleft"_a = false)); 41 | ax.scatter(Args(x, y)); 42 | const double binwidth = 0.25; 43 | const auto xi = xt::amax(xt::fabs(x_), {0}), 44 | yi = xt::amax(xt::fabs(y_), {0}); 45 | const double xymax = max(fabs(x_[xi]), fabs(y_[yi])); 46 | const double lim = (static_cast(xymax / binwidth) + 1) * binwidth; 47 | auto bins_ = xt::arange(-lim, lim + binwidth, binwidth); 48 | vector bins(bins_.begin(), bins_.end()); 49 | ax_histx.hist(Args(x), Kwargs("bins"_a = bins)); 50 | ax_histy.hist(Args(y), 51 | Kwargs("bins"_a = bins, "orientation"_a = "horizontal")); 52 | #if USE_GUI 53 | plt.show(); 54 | #else 55 | plt.savefig(Args("scatter_hist1.png")); 56 | #endif 57 | } 58 | // cell2 59 | { 60 | auto fig = plt.figure(Args(), Kwargs("figsize"_a = py::make_tuple(8, 8))); 61 | auto gs = fig.add_gridspec(2, 2, 62 | Kwargs("width_ratios"_a = py::make_tuple(7, 2), 63 | "height_ratios"_a = py::make_tuple(2, 7), 64 | "left"_a = 0.1, "right"_a = 0.9, 65 | "bottom"_a = 0.1, "top"_a = 0.9, 66 | "wspace"_a = 0.05, "hspace"_a = 0.05)); 67 | auto ax = fig.add_subplot(Args(gs(1, 0).unwrap())); 68 | auto ax_histx = fig.add_subplot(Args(gs(0, 0).unwrap()), 69 | Kwargs("sharex"_a = ax.unwrap())); 70 | auto ax_histy = fig.add_subplot(Args(gs(1, 1).unwrap()), 71 | Kwargs("sharey"_a = ax.unwrap())); 72 | ax_histx.tick_params(Args(), 73 | Kwargs("axis"_a = "x", "labelbottom"_a = false)); 74 | ax_histy.tick_params(Args(), Kwargs("axis"_a = "y", "labelleft"_a = false)); 75 | ax.scatter(Args(x, y)); 76 | const double binwidth = 0.25; 77 | const auto xi = xt::amax(xt::fabs(x_), {0}), 78 | yi = xt::amax(xt::fabs(y_), {0}); 79 | const double xymax = max(fabs(x_[xi]), fabs(y_[yi])); 80 | const double lim = (static_cast(xymax / binwidth) + 1) * binwidth; 81 | auto bins_ = xt::arange(-lim, lim + binwidth, binwidth); 82 | vector bins(bins_.begin(), bins_.end()); 83 | ax_histx.hist(Args(x), Kwargs("bins"_a = bins)); 84 | ax_histy.hist(Args(y), 85 | Kwargs("bins"_a = bins, "orientation"_a = "horizontal")); 86 | #if USE_GUI 87 | plt.show(); 88 | #else 89 | plt.savefig(Args("scatter_hist2.png")); 90 | #endif 91 | } 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /gallery/lines_bars_and_markers/scatter_symbol.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/lines_bars_and_markers/scatter_symbol.html 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | template std::vector arange(T start, T end, T h) { 10 | int N = static_cast((end - start) / h); 11 | std::vector xs(N); 12 | T val = start; 13 | for (int i = 0; i < N; ++i) { 14 | xs[i] = val; 15 | val += h; 16 | } 17 | return xs; 18 | } 19 | 20 | using namespace std; 21 | using namespace matplotlibcpp17; 22 | 23 | int main() { 24 | py::scoped_interpreter guard{}; 25 | auto plt = pyplot::import(); 26 | const vector x = {0., 2., 4., 6., 8., 10., 12., 14., 16., 27 | 18., 20., 22., 24., 26., 28., 30., 32., 34., 28 | 36., 38., 40., 42., 44., 46., 48.}; 29 | const vector y = { 30 | 21.01101912, 24.74481311, 27.34126659, 27.27298483, 44.26208785, 31 | 41.14266853, 32.72670355, 35.63706738, 57.689303, 64.43917295, 32 | 56.86145395, 65.85596686, 91.33222544, 89.93319308, 90.07761828, 33 | 104.3101143, 105.86324421, 125.79378295, 127.67869682, 131.83987721, 34 | 140.51644988, 140.79566887, 153.22398837, 169.06951457, 174.97156606}; 35 | const vector s = { 36 | 736.2911849, 628.75670445, 664.90041181, 607.46030945, 884.4840139, 37 | 774.0174507, 790.37543212, 1278.33411095, 588.75488929, 810.61127126, 38 | 1126.45270023, 1278.31780809, 886.56768427, 769.13688434, 953.93522899, 39 | 538.35320778, 811.14962318, 1225.04291605, 628.81456741, 1094.89690779, 40 | 1006.37932941, 759.34401418, 1237.90122592, 689.78115093, 1159.15645671}; 41 | plt.scatter(Args(x, y, s), 42 | Kwargs("c"_a = "g", "alpha"_a = 0.5, 43 | "marker"_a = R"($\clubsuit$)", "label"_a = "Luck")); 44 | plt.xlabel(Args("Leprechauns")); 45 | plt.ylabel(Args("Gold")); 46 | plt.legend(Kwargs("loc"_a = "upper left")); 47 | #if USE_GUI 48 | plt.show(); 49 | #else 50 | plt.savefig(Args("scatter_symbol.png")); 51 | #endif 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /gallery/lines_bars_and_markers/scatter_with_legend.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/lines_bars_and_markers/scatter_with_legend.html 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace matplotlibcpp17; 13 | 14 | int main1() { 15 | auto plt = matplotlibcpp17::pyplot::import(); 16 | auto [fig, ax] = plt.subplots(); 17 | for (auto &&color : {"tab:blue", "tab:orange", "tab:green"}) { 18 | int n = 750; 19 | auto xy = xt::random::rand({2, n}); 20 | auto x_ = xt::view(xy, 0, xt::all()), y_ = xt::view(xy, 1, xt::all()); 21 | auto scale_ = xt::random::rand({n}) * 200; 22 | vector x(x_.begin(), x_.end()), y(y_.begin(), y_.end()), 23 | scale(scale_.begin(), scale_.end()); 24 | ax.scatter(Args(x, y), 25 | Kwargs("s"_a = scale, "c"_a = color, "label"_a = color, 26 | "alpha"_a = 0.3, "edgecolors"_a = "none")); 27 | } 28 | ax.legend(); 29 | ax.grid(Args(true)); 30 | #if USE_GUI 31 | plt.show(); 32 | #else 33 | plt.savefig(Args("scatter_with_legend1.png")); 34 | #endif 35 | return 0; 36 | } 37 | 38 | int main2() { 39 | int N = 45; 40 | const auto x_ = xt::random::rand({N}, 0.0, 1.0); 41 | const auto y_ = xt::random::rand({N}, 0.0, 1.0); 42 | const auto c_ = xt::random::randint({N}, 1, 5); 43 | const auto s_ = xt::random::randint({N}, 10, 220); 44 | const vector x(x_.begin(), x_.end()), y(y_.begin(), y_.end()); 45 | const vector c(c_.begin(), c_.end()), s(s_.begin(), s_.end()); 46 | auto plt = matplotlibcpp17::pyplot::import(); 47 | auto [fig, ax] = plt.subplots(); 48 | auto scatter = ax.scatter(Args(x, y), Kwargs("c"_a = c, "s"_a = s)); 49 | { 50 | auto [handles, labels] = scatter.legend_elements(); 51 | auto legend1 = 52 | ax.legend(Args(handles.unwrap(), labels.unwrap()), 53 | Kwargs("loc"_a = "lower left", "title"_a = "Classes")); 54 | ax.add_artist(Args(legend1.unwrap())); 55 | } 56 | { 57 | auto [handles, labels] = scatter.legend_elements( 58 | Args(), Kwargs("prop"_a = "sizes", "alpha"_a = 0.6)); 59 | auto legend2 = 60 | ax.legend(Args(handles.unwrap(), labels.unwrap()), 61 | Kwargs("loc"_a = "upper right", "title"_a = "Sizes")); 62 | } 63 | #if USE_GUI 64 | plt.show(); 65 | #else 66 | plt.savefig(Args("scatter_with_legend2.png")); 67 | #endif 68 | return 0; 69 | } 70 | 71 | int main() { 72 | py::scoped_interpreter guard{}; 73 | main1(); 74 | main2(); 75 | } 76 | -------------------------------------------------------------------------------- /gallery/lines_bars_and_markers/simple_plot.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/lines_bars_and_markers/simple_plot.html 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace matplotlibcpp17; 13 | 14 | int main() { 15 | py::scoped_interpreter guard{}; 16 | auto plt = pyplot::import(); 17 | const auto t_ = xt::arange(0.0, 2.0, 0.01); 18 | const auto s_ = xt::sin(2 * M_PI * t_) + 1.0; 19 | const vector t(t_.begin(), t_.end()), s(s_.begin(), s_.end()); 20 | 21 | auto [fig, ax] = plt.subplots(); 22 | ax.plot(Args(t, s), Kwargs("color"_a = "blue", "linewidth"_a = 1.0)); 23 | ax.set(Args(), Kwargs("xlabel"_a = "time (s)", "ylabel"_a = "voltage (mV)", 24 | "title"_a = "About as simple as it gets, folks")); 25 | ax.grid(); 26 | 27 | #if USE_GUI 28 | plt.show(); 29 | #else 30 | plt.savefig(Args("simple_plot.png")); 31 | #endif 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /gallery/lines_bars_and_markers/step_demo.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/lines_bars_and_markers/step_demo.html 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace matplotlibcpp17; 13 | 14 | int main() { 15 | py::scoped_interpreter guard{}; 16 | auto plt = pyplot::import(); 17 | 18 | const auto x_ = xt::arange(14) * 1.0; 19 | const auto y_ = xt::sin(x_ / 2.0); 20 | const auto y1_ = y_ + 1.0, y2_ = y_ + 2.0; 21 | const vector x(x_.begin(), x_.end()), y(y_.begin(), y_.end()), 22 | y1(y1_.begin(), y1_.end()), y2(y2_.begin(), y2_.end()); 23 | 24 | plt.step(Args(x, y2), Kwargs("label"_a = "pre (default)")); 25 | plt.plot(Args(x, y2, "o--"), Kwargs("color"_a = "grey", "alpha"_a = 0.3)); 26 | 27 | plt.step(Args(x, y1), Kwargs("where"_a = "mid", "label"_a = "mid")); 28 | plt.plot(Args(x, y1, "o--"), Kwargs("color"_a = "grey", "alpha"_a = 0.3)); 29 | 30 | plt.step(Args(x, y), Kwargs("where"_a = "post", "label"_a = "post")); 31 | plt.plot(Args(x, y, "o--"), Kwargs("color"_a = "grey", "alpha"_a = 0.3)); 32 | 33 | plt.grid(Args(), Kwargs("axis"_a = "x", "color"_a = "0.95")); 34 | plt.legend(Args(), Kwargs("title"_a = "Parameter where:")); 35 | plt.title(Args("plt.step(where...)")); 36 | plt.show(); 37 | } 38 | -------------------------------------------------------------------------------- /gallery/mplot3d/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_demo(lines3d lines3d.cpp) 2 | add_demo(lorenz_attractor lorenz_attractor.cpp) 3 | add_demo(contour3d contour3d.cpp) 4 | add_demo(subplot3d subplot3d.cpp) 5 | add_demo(errorbar3d errorbar3d.cpp) 6 | add_demo(surface3d surface3d) 7 | 8 | add_custom_target( 9 | mplot3d 10 | DEPENDS lines3d lorenz_attractor contour3d subplot3d errorbar3d surface3d 11 | COMMAND lines3d 12 | COMMAND lorenz_attractor 13 | COMMAND contour3d 14 | COMMAND subplot3d 15 | COMMAND errorbar3d 16 | COMMAND surface3d 17 | COMMENT "running mplot3d" 18 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../images") 19 | -------------------------------------------------------------------------------- /gallery/mplot3d/contour3d.cpp: -------------------------------------------------------------------------------- 1 | // example https://matplotlib.org/stable/gallery/mplot3d/contour3d.html 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | using namespace std; 13 | using namespace matplotlibcpp17; 14 | 15 | // looks like vector> is naturally converted thanks to pybind11: 16 | // https://github.com/pybind/pybind11/issues/1071 17 | using mesh2D = vector>; 18 | 19 | // from mpl_toolkits.axes3d.py 20 | tuple get_test_data(double delta = 0.05) { 21 | const auto xs = xt::arange(-3.0, 3.0, delta); 22 | const auto ys = xt::arange(-3.0, 3.0, delta); 23 | const auto [X0, Y0] = xt::meshgrid(xs, ys); // 120x160 24 | const auto Z1 = 25 | xt::exp(-(xt::pow(X0, 2) + xt::pow(Y0, 2)) / 2.0) / (2 * M_PI); 26 | const auto Z2 = 27 | xt::exp(-(xt::pow((X0 - 1.0) / 1.5, 2) + xt::pow((Y0 - 1.0) / 0.5, 2)) / 28 | 2) / 29 | (2 * M_PI * 0.5 * 1.5); 30 | const auto Z0 = Z2 - Z1; 31 | const auto X = X0 * 10; 32 | const auto Y = Y0 * 10; 33 | const auto Z = Z0 * 500; 34 | const int szx = xs.shape()[0], szy = ys.shape()[0]; 35 | mesh2D X_(szx), Y_(szx), Z_(szx); 36 | for (int i = 0; i < szx; ++i) { 37 | X_[i].resize(szy); 38 | Y_[i].resize(szy); 39 | Z_[i].resize(szy); 40 | for (int j = 0; j < szy; ++j) { 41 | X_[i][j] = X(i, j); 42 | Y_[i][j] = Y(i, j); 43 | Z_[i][j] = Z(i, j); 44 | } 45 | } 46 | return {X_, Y_, Z_}; 47 | } 48 | 49 | int main() { 50 | py::scoped_interpreter guard{}; 51 | auto plt = matplotlibcpp17::pyplot::import(); 52 | // this is required for "projection = 3d" 53 | matplotlibcpp17::mplot3d::import(); 54 | auto fig = plt.figure(); 55 | auto ax = fig.add_subplot(Args(), Kwargs("projection"_a = "3d")); 56 | const auto [X, Y, Z] = get_test_data(0.05); 57 | ax.contour(Args(X, Y, Z), Kwargs("cmap"_a = cm::coolwarm)); 58 | #if USE_GUI 59 | plt.show(); 60 | #else 61 | plt.savefig(Args("contour3d.png")); 62 | #endif 63 | } 64 | -------------------------------------------------------------------------------- /gallery/mplot3d/errorbar3d.cpp: -------------------------------------------------------------------------------- 1 | // example from https://matplotlib.org/stable/gallery/mplot3d/errorbar3d.html 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | using namespace matplotlibcpp17; 14 | 15 | int main() { 16 | py::scoped_interpreter guard{}; 17 | auto plt = pyplot::import(); 18 | // this is required for "projection = 3d" 19 | matplotlibcpp17::mplot3d::import(); 20 | auto ax = plt.figure().add_subplot(Args(), Kwargs("projection"_a = "3d")); 21 | const auto t_ = xt::arange(0.0, 2 * M_PI + 0.1, 0.01); 22 | const auto x_ = xt::sin(1.0 * t_); 23 | const auto y_ = xt::cos(3.0 * t_); 24 | const auto z_ = xt::sin(5.0 * t_); 25 | vector t(t_.begin(), t_.end()), x(x_.begin(), x_.end()), 26 | y(y_.begin(), y_.end()), z(z_.begin(), z_.end()); 27 | 28 | const int estep = 15; 29 | vector i(t_.shape()[0]), zuplims, zlolims; 30 | std::iota(i.begin(), i.end(), t_.shape()[0]); 31 | std::transform(i.begin(), i.end(), std::back_inserter(zuplims), [](int i) { 32 | return (i % 15 == 0) and ((i / estep) % 3 == 0); 33 | }); 34 | std::transform(i.begin(), i.end(), std::back_inserter(zlolims), [](int i) { 35 | return (i % 15 == 0) and ((i / estep) % 3 == 2); 36 | }); 37 | 38 | ax.errorbar(Args(x, y, z, 0.2), 39 | Kwargs("zuplims"_a = zuplims, "zlolims"_a = zlolims, 40 | "errorevery"_a = estep)); 41 | 42 | ax.set_xlabel(Args("X label")); 43 | ax.set_ylabel(Args("Y label")); 44 | ax.set_zlabel(Args("Z label")); 45 | 46 | plt.show(); 47 | } 48 | -------------------------------------------------------------------------------- /gallery/mplot3d/lines3d.cpp: -------------------------------------------------------------------------------- 1 | // example from https://matplotlib.org/stable/gallery/mplot3d/lines3d.html 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace matplotlibcpp17; 13 | 14 | int main() { 15 | py::scoped_interpreter guard{}; 16 | auto plt = matplotlibcpp17::pyplot::import(); 17 | // this is required for "projection = 3d" 18 | matplotlibcpp17::mplot3d::import(); 19 | auto fig = plt.figure(); 20 | auto ax = fig.add_subplot(Args(), Kwargs("projection"_a = "3d")); 21 | const auto theta_ = xt::linspace(-4 * M_PI, 4 * M_PI, 100); 22 | const auto z_ = xt::linspace(-2.0, 2.0, 100); 23 | const auto r_ = 1.0 + xt::pow(z_, 2); 24 | const auto x_ = r_ * xt::sin(theta_); 25 | const auto y_ = r_ * xt::cos(theta_); 26 | const vector z(z_.begin(), z_.end()); 27 | const vector r(r_.begin(), r_.end()); 28 | const vector theta(theta_.begin(), theta_.end()); 29 | const vector x(x_.begin(), x_.end()), y(y_.begin(), y_.end()); 30 | ax.plot(Args(x, y, z), Kwargs("label"_a = "parametric curve")); 31 | ax.legend(); 32 | #if USE_GUI 33 | plt.show(); 34 | #else 35 | plt.savefig(Args("lines3d.png")); 36 | #endif 37 | } 38 | -------------------------------------------------------------------------------- /gallery/mplot3d/lorenz_attractor.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/mplot3d/lorenz_attractor.html 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | using namespace std; 10 | using namespace matplotlibcpp17; 11 | 12 | tuple lorenz(double x, double y, double z, 13 | double s = 10, double r = 28, 14 | double b = 2.667) { 15 | const double x_dot = s * (y - x); 16 | const double y_dot = r * x - y - x * z; 17 | const double z_dot = x * y - b * z; 18 | return {x_dot, y_dot, z_dot}; 19 | } 20 | 21 | int main() { 22 | py::scoped_interpreter guard{}; 23 | auto plt = matplotlibcpp17::pyplot::import(); 24 | // this is required for "projection = 3d" 25 | matplotlibcpp17::mplot3d::import(); 26 | auto fig = plt.figure(); 27 | auto ax = fig.add_subplot(Args(), Kwargs("projection"_a = "3d")); 28 | 29 | const double dt = 0.01; 30 | const int num_steps = 10000; 31 | vector xs, ys, zs; 32 | xs.push_back(0.0); 33 | ys.push_back(1.0); 34 | zs.push_back(1.05); 35 | for (int i = 0; i < num_steps; ++i) { 36 | auto [x_dot, y_dot, z_dot] = lorenz(xs[i], ys[i], zs[i]); 37 | xs.push_back(xs[i] + x_dot * dt); 38 | ys.push_back(ys[i] + y_dot * dt); 39 | zs.push_back(zs[i] + z_dot * dt); 40 | } 41 | ax.plot(Args(xs, ys, zs)); 42 | ax.set_xlabel(Args("X Axis")); 43 | ax.set_ylabel(Args("Y Axis")); 44 | ax.set_zlabel(Args("Z Axis")); 45 | #if USE_GUI 46 | plt.show(); 47 | #else 48 | plt.savefig(Args("lorenz_attractor.png")); 49 | #endif 50 | } 51 | -------------------------------------------------------------------------------- /gallery/mplot3d/subplot3d.cpp: -------------------------------------------------------------------------------- 1 | // example https://matplotlib.org/stable/gallery/mplot3d/subplot3d.html 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | using namespace std; 13 | using namespace matplotlibcpp17; 14 | 15 | // NOTE: looks like vector> is naturally converted thanks to pybind11 16 | // ref: https://github.com/pybind/pybind11/issues/1071 17 | using mesh2D = vector>; 18 | 19 | // from mpl_toolkits.axes3d.py 20 | tuple get_test_data(double delta = 0.05) { 21 | const auto xs = xt::arange(-3.0, 3.0, delta); 22 | const auto ys = xt::arange(-3.0, 3.0, delta); 23 | const auto [X0, Y0] = xt::meshgrid(xs, ys); // 120x160 24 | const auto Z1 = 25 | xt::exp(-(xt::pow(X0, 2) + xt::pow(Y0, 2)) / 2.0) / (2 * M_PI); 26 | const auto Z2 = 27 | xt::exp(-(xt::pow((X0 - 1.0) / 1.5, 2) + xt::pow((Y0 - 1.0) / 0.5, 2)) / 28 | 2) / 29 | (2 * M_PI * 0.5 * 1.5); 30 | const auto Z0 = Z2 - Z1; 31 | const auto X = X0 * 10; 32 | const auto Y = Y0 * 10; 33 | const auto Z = Z0 * 500; 34 | const int szx = xs.shape()[0], szy = ys.shape()[0]; 35 | mesh2D X_(szx), Y_(szx), Z_(szx); 36 | for (int i = 0; i < szx; ++i) { 37 | X_[i].resize(szy); 38 | Y_[i].resize(szy); 39 | Z_[i].resize(szy); 40 | for (int j = 0; j < szy; ++j) { 41 | X_[i][j] = X(i, j); 42 | Y_[i][j] = Y(i, j); 43 | Z_[i][j] = Z(i, j); 44 | } 45 | } 46 | return {X_, Y_, Z_}; 47 | } 48 | 49 | int main() { 50 | py::scoped_interpreter guard{}; 51 | auto plt = matplotlibcpp17::pyplot::import(); 52 | // this is required for "projection = 3d" 53 | matplotlibcpp17::mplot3d::import(); 54 | auto [w, h] = plt.figaspect(Args(0.5)); 55 | auto fig = plt.figure(Args(), Kwargs("figsize"_a = py::make_tuple(w, h))); 56 | { 57 | auto ax = fig.add_subplot(Args(1, 2, 1), Kwargs("projection"_a = "3d")); 58 | const auto xs = xt::arange(-5.0, 5.0, 0.25); 59 | const auto [X0, Y0] = xt::meshgrid(xs, xs); 60 | const auto R0 = xt::sqrt(xt::pow(X0, 2) + xt::pow(Y0, 2)); 61 | const auto Z0 = xt::sin(R0); 62 | // to vector 63 | const int sz = xs.shape()[0]; 64 | mesh2D X(sz), Y(sz), Z(sz); 65 | for (int i = 0; i < sz; ++i) { 66 | X[i].resize(sz); 67 | Y[i].resize(sz); 68 | Z[i].resize(sz); 69 | for (int j = 0; j < sz; ++j) { 70 | X[i][j] = X0(i, j); 71 | Y[i][j] = Y0(i, j); 72 | Z[i][j] = Z0(i, j); 73 | } 74 | } 75 | // NOTE: conversion to numpy array 76 | // ref: https://github.com/pybind/pybind11/issues/2066 77 | const auto X_ = py::array(py::cast(std::move(X))); 78 | const auto Y_ = py::array(py::cast(std::move(Y))); 79 | const auto Z_ = py::array(py::cast(std::move(Z))); 80 | auto surf = ax.plot_surface( 81 | Args(X_, Y_, Z_), 82 | Kwargs("rstride"_a = 1, "cstride"_a = 1, "linewidth"_a = 0, 83 | "antialiased"_a = false, "cmap"_a = cm::coolwarm)); 84 | ax.set_zlim(Args(-1.01, 1.01)); 85 | fig.colorbar(Args(surf.unwrap()), 86 | Kwargs("shrink"_a = 0.5, "aspect"_a = 10)); 87 | } 88 | { 89 | auto ax = fig.add_subplot(Args(1, 2, 2), Kwargs("projection"_a = "3d")); 90 | const auto [X, Y, Z] = get_test_data(0.05); 91 | const auto X_ = py::array(py::cast(std::move(X))); 92 | const auto Y_ = py::array(py::cast(std::move(Y))); 93 | const auto Z_ = py::array(py::cast(std::move(Z))); 94 | ax.plot_wireframe(Args(X_, Y_, Z_), 95 | Kwargs("rstride"_a = 10, "cstride"_a = 10)); 96 | } 97 | #if USE_GUI 98 | plt.show(); 99 | #else 100 | plt.savefig(Args("subplot3d.png")); 101 | #endif 102 | } 103 | -------------------------------------------------------------------------------- /gallery/mplot3d/surface3d.cpp: -------------------------------------------------------------------------------- 1 | // example from https://matplotlib.org/stable/gallery/mplot3d/surface3d.html 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | using namespace std; 13 | using namespace matplotlibcpp17; 14 | 15 | using mesh2D = vector>; 16 | 17 | int main() { 18 | py::scoped_interpreter guard{}; 19 | auto plt = matplotlibcpp17::pyplot::import(); 20 | // this is required for "projection = 3d" 21 | matplotlibcpp17::mplot3d::import(); 22 | auto [fig, ax] = 23 | plt.subplots(Kwargs("subplot_kw"_a = py::dict("projection"_a = "3d"))); 24 | 25 | const auto xs = xt::arange(-5.0, 5.0, 0.25); 26 | const auto [X0, Y0] = xt::meshgrid(xs, xs); 27 | const auto R0 = xt::sqrt(xt::pow(X0, 2) + xt::pow(Y0, 2)); 28 | const auto Z0 = xt::sin(R0); 29 | // to vector 30 | const int sz = xs.shape()[0]; 31 | mesh2D X(sz), Y(sz), Z(sz); 32 | for (int i = 0; i < sz; ++i) { 33 | X[i].resize(sz); 34 | Y[i].resize(sz); 35 | Z[i].resize(sz); 36 | for (int j = 0; j < sz; ++j) { 37 | X[i][j] = X0(i, j); 38 | Y[i][j] = Y0(i, j); 39 | Z[i][j] = Z0(i, j); 40 | } 41 | } 42 | // to numpy array (vector is converted to list of list) 43 | const auto X_ = py::array(py::cast(std::move(X))); 44 | const auto Y_ = py::array(py::cast(std::move(Y))); 45 | const auto Z_ = py::array(py::cast(std::move(Z))); 46 | const auto surf = ax.plot_surface( 47 | Args(X_, Y_, Z_), 48 | Kwargs("rstride"_a = 1, "cstride"_a = 1, "linewidth"_a = 0, 49 | "antialiased"_a = false, "cmap"_a = cm::coolwarm)); 50 | ax.set_zlim(Args(-1.01, 1.01)); 51 | // TODO 52 | // auto locator = ticker::LinearLocator(Args(10)); 53 | // ax.zaxis.set_major_locator(Args(locator.unwrap())); 54 | // ax.zaxis.set_major_formatter(Args("{x:.02f}")); 55 | fig.colorbar(Args(surf.unwrap()), Kwargs("shrink"_a = 0.5, "aspect"_a = 5)); 56 | plt.show(); 57 | } 58 | -------------------------------------------------------------------------------- /gallery/scales/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_demo(aspect_loglog aspect_loglog.cpp) 2 | 3 | add_custom_target( 4 | scales 5 | DEPENDS aspect_loglog 6 | COMMAND aspect_loglog 7 | COMMENT "running scales" 8 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../images") 9 | -------------------------------------------------------------------------------- /gallery/scales/aspect_loglog.cpp: -------------------------------------------------------------------------------- 1 | // example from https://matplotlib.org/stable/gallery/scales/aspect_loglog.html 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | using namespace std; 9 | using namespace matplotlibcpp17; 10 | 11 | int main() { 12 | py::scoped_interpreter guard{}; 13 | auto plt = pyplot::import(); 14 | auto [fig, axs] = plt.subplots(1, 2); 15 | auto &ax1 = axs[0], ax2 = axs[1]; 16 | ax1.set_xscale(Args("log")); 17 | ax1.set_yscale(Args("log")); 18 | ax1.set_xlim(Args(1e+1, 1e+3)); 19 | ax1.set_ylim(Args(1e+2, 1e+3)); 20 | ax1.set_aspect(Args(1)); 21 | ax1.set_title(Args("adjustable = box")); 22 | 23 | ax2.set_xscale(Args("log")); 24 | ax2.set_yscale(Args("log")); 25 | ax2.set_adjustable(Args("datalim")); 26 | ax2.plot(Args(vector({1, 3, 10}), vector({1, 9, 100}), "o-")); 27 | ax2.set_xlim(Args(1e-1, 1e+2)); 28 | ax2.set_ylim(Args(1e-1, 1e+3)); 29 | ax2.set_aspect(Args(1)); 30 | ax2.set_title(Args("adjustable = datalim")); 31 | 32 | plt.show(); 33 | } 34 | -------------------------------------------------------------------------------- /gallery/shapes_and_collections/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_demo(patch_collection patch_collection.cpp) 2 | add_demo(patches_circle_rectangle patches_circle_rectangle.cpp) 3 | 4 | add_custom_target( 5 | shapes_and_collections 6 | DEPENDS patch_collection patches_circle_rectangle 7 | COMMAND patch_collection 8 | COMMAND patches_circle_rectangle 9 | COMMENT "running shapes_and_collections" 10 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../images") 11 | -------------------------------------------------------------------------------- /gallery/shapes_and_collections/patch_collection.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/shapes_and_collections/patch_collection.html 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace matplotlibcpp17::patches; 13 | using namespace matplotlibcpp17; 14 | 15 | int main() { 16 | py::scoped_interpreter guard{}; 17 | auto plt = matplotlibcpp17::pyplot::import(); 18 | auto [fig, ax] = plt.subplots(); 19 | 20 | const int N = 3; 21 | xt::xarray x = xt::random::rand({N}); 22 | xt::xarray y = xt::random::rand({N}); 23 | xt::xarray radii = 0.1 * xt::random::rand({N}); 24 | py::list patches; // instead of patches = [] 25 | for (int i = 0; i < N; ++i) { 26 | const double x1 = x[i], y1 = y[i], r = radii[i]; 27 | auto circle = patches::Circle(Args(py::make_tuple(x1, y1), r)); 28 | patches.append(circle.unwrap()); 29 | } 30 | 31 | x = xt::random::rand({N}); 32 | y = xt::random::rand({N}); 33 | radii = 0.1 * xt::random::rand({N}); 34 | const xt::xarray theta1 = 360.0 * xt::random::rand({N}); 35 | const xt::xarray theta2 = 360.0 * xt::random::rand({N}); 36 | for (int i = 0; i < N; ++i) { 37 | const double x1 = x[i], y1 = y[i], r = radii[i], th1 = theta1[i], 38 | th2 = theta2[i]; 39 | auto wedge = patches::Wedge(Args(py::make_tuple(x1, y1), r, th1, th2)); 40 | patches.append(wedge.unwrap()); 41 | } 42 | 43 | patches.append( 44 | patches::Wedge(Args(py::make_tuple(0.3, 0.7), 0.1, 0, 360)).unwrap()); 45 | patches.append(patches::Wedge(Args(py::make_tuple(0.7, 0.8), 0.2, 0, 360), 46 | Kwargs("width"_a = 0.05)) 47 | .unwrap()); 48 | patches.append( 49 | patches::Wedge(Args(py::make_tuple(0.8, 0.3), 0.2, 0, 45)).unwrap()); 50 | patches.append(patches::Wedge(Args(py::make_tuple(0.8, 0.3), 0.2, 45, 90), 51 | Kwargs("width"_a = 0.10)) 52 | .unwrap()); 53 | 54 | for (int i = 0; i < N; ++i) { 55 | auto poly__ = xt::random::rand({N, 2}); 56 | vector> poly_(N); 57 | // to vector> 58 | for (int j = 0; j < N; ++j) { 59 | poly_[j].resize(2); 60 | poly_[j][0] = poly__(j, 0); 61 | poly_[j][1] = poly__(j, 1); 62 | } 63 | // to numpy array 64 | auto poly = py::array(py::cast(std::move(poly_))); 65 | auto polygon = Polygon(Args(poly, true)); 66 | patches.append(polygon.unwrap()); 67 | } 68 | 69 | auto colors__ = 100.0 * xt::random::rand({patches.size()}); 70 | const vector colors_(colors__.begin(), colors__.end()); 71 | py::array colors = py::cast(colors_); 72 | auto p = collections::PatchCollection(Args(patches), Kwargs("alpha"_a = 0.4)); 73 | p.set_array(Args(colors)); 74 | ax.add_collection(Args(p.unwrap())); 75 | fig.colorbar(Args(p.unwrap()), Kwargs("ax"_a = ax.unwrap())); 76 | 77 | #if USE_GUI 78 | plt.show(); 79 | #else 80 | plt.savefig(Args("patch_collection.png")); 81 | #endif 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /gallery/shapes_and_collections/patches_circle_rectangle.cpp: -------------------------------------------------------------------------------- 1 | // example from https://note.nkmk.me/python-matplotlib-patches-circle-rectangle 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | using namespace matplotlibcpp17; 11 | using namespace matplotlibcpp17::patches; 12 | 13 | int main() { 14 | py::scoped_interpreter guard{}; 15 | auto plt = matplotlibcpp17::pyplot::import(); 16 | auto fig = plt.figure(); 17 | auto ax = plt.axes(); 18 | auto c = Circle(Args(py::make_tuple(0, 0), 0.5), 19 | Kwargs("fc"_a = "g", "ec"_a = "r")); 20 | auto e = Ellipse(Args(py::make_tuple(-0.25, 0), 0.5, 0.25), 21 | Kwargs("fc"_a = "b", "ec"_a = "y")); 22 | auto r = Rectangle(Args(py::make_tuple(0, 0), 0.25, 0.5), 23 | Kwargs("ec"_a = "#000000", "fill"_a = false)); 24 | ax.add_patch(Args(c.unwrap())); 25 | ax.add_patch(Args(e.unwrap())); 26 | ax.add_patch(Args(r.unwrap())); 27 | plt.axis(Args("scaled")); 28 | ax.set_aspect(Args("equal")); 29 | #if USE_GUI 30 | plt.show(); 31 | #else 32 | plt.savefig(Args("patches_circle_rectangle.png")); 33 | #endif 34 | } 35 | -------------------------------------------------------------------------------- /gallery/statistics/.gitignore: -------------------------------------------------------------------------------- 1 | *.png 2 | -------------------------------------------------------------------------------- /gallery/statistics/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_demo(hist hist.cpp) 2 | add_demo(errorbar errorbar.cpp) 3 | 4 | add_custom_target( 5 | statitics 6 | DEPENDS hist errorbar 7 | COMMAND hist 8 | COMMAND errorbar 9 | COMMENT "running hist" 10 | WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../images") 11 | -------------------------------------------------------------------------------- /gallery/statistics/errorbar.cpp: -------------------------------------------------------------------------------- 1 | // example from https://matplotlib.org/stable/gallery/statistics/errorbar.html 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | 9 | using namespace std; 10 | using namespace matplotlibcpp17; 11 | 12 | int main() { 13 | py::scoped_interpreter guard{}; 14 | auto plt = pyplot::import(); 15 | const auto x_ = xt::arange(0.1, 4.0, 0.5); 16 | const auto y_ = xt::exp(-x_); 17 | const vector x(x_.begin(), x_.end()), y(y_.begin(), y_.end()); 18 | 19 | auto [fig, ax] = plt.subplots(); 20 | ax.errorbar(Args(x, y), Kwargs("xerr"_a = 0.2, "yerr"_a = 0.4)); 21 | #if USE_GUI 22 | plt.show(); 23 | #else 24 | plt.savefig(Args("erorrbar.png")); 25 | #endif 26 | } 27 | -------------------------------------------------------------------------------- /gallery/statistics/hist.cpp: -------------------------------------------------------------------------------- 1 | // example from https://matplotlib.org/stable/gallery/statistics/hist.html 2 | 3 | #include 4 | 5 | #include 6 | 7 | using namespace std; 8 | using namespace matplotlibcpp17; 9 | 10 | int main1() { 11 | int N_points = 100000; 12 | int n_bins = 20; 13 | const auto dist1_ = xt::random::randn({N_points}); 14 | const auto dist2_ = 0.4 * xt::random::randn({N_points}) + 5.0; 15 | const vector dist1(dist1_.begin(), dist1_.end()), 16 | dist2(dist2_.begin(), dist2_.end()); 17 | auto plt = matplotlibcpp17::pyplot::import(); 18 | auto [fig, axs] = 19 | plt.subplots(1, 2, Kwargs("sharey"_a = true, "tight_layout"_a = true)); 20 | auto ax1 = axs[0], ax2 = axs[1]; 21 | auto [N, bins, patches] = ax1.hist(Args(dist1), Kwargs("bins"_a = n_bins)); 22 | // TODO: patches.patches are list of patches::Rectangle. 23 | ax2.hist(Args(dist2), Kwargs("bins"_a = n_bins)); 24 | #if USE_GUI 25 | plt.show(); 26 | #else 27 | plt.savefig(Args("hist1.png")); 28 | #endif 29 | return 0; 30 | } 31 | 32 | // int main2() // pass 33 | 34 | int main3() { 35 | const int N_points = 100000; 36 | const auto dist1_ = xt::random::randn({N_points}); 37 | const auto dist2_ = 0.4 * xt::random::randn({N_points}) + 5.0; 38 | const vector dist1(dist1_.begin(), dist1_.end()), 39 | dist2(dist2_.begin(), dist2_.end()); 40 | 41 | auto plt = matplotlibcpp17::pyplot::import(); 42 | auto [fig, axs] = 43 | plt.subplots(1, 1, 44 | Kwargs("figsize"_a = py::make_tuple(5, 5), "sharex"_a = true, 45 | "sharey"_a = true, "tight_layout"_a = true)); 46 | auto ax1 = axs[0]; 47 | ; 48 | // We can increase the number of bins on each axis 49 | ax1.hist2d(Args(dist1, dist2), Kwargs("bins"_a = 40)); 50 | // TODO: more examples 51 | #if USE_GUI 52 | plt.show(); 53 | #else 54 | plt.savefig(Args("hist3.png")); 55 | #endif 56 | return 0; 57 | } 58 | 59 | int main() { 60 | py::scoped_interpreter guard{}; 61 | main1(); 62 | main3(); 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /gallery/subplots_axes_and_figures/.gitignore: -------------------------------------------------------------------------------- 1 | *.png 2 | -------------------------------------------------------------------------------- /gallery/subplots_axes_and_figures/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_demo(align_labels_demo align_labels_demo.cpp) 2 | add_demo(gridspec_multicolumn gridspec_multicolumn.cpp) 3 | add_demo(multiple_figs_demo multiple_figs_demo.cpp) 4 | add_demo(colorbar_placement colorbar_placement.cpp) 5 | add_demo(subplots subplots.cpp) 6 | add_demo(two_scales two_scales.cpp) 7 | 8 | add_custom_target( 9 | subplots_axes_and_figures 10 | DEPENDS align_labels_demo gridspec_multicolumn multiple_figs_demo 11 | colorbar_placement two_scales 12 | COMMAND align_labels_demo 13 | COMMAND gridspec_multicolumn 14 | COMMAND multiple_figs_demo 15 | COMMAND colorbar_placement 16 | COMMAND two_scales 17 | COMMENT "subplots_axes_and_figures" 18 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) 19 | -------------------------------------------------------------------------------- /gallery/subplots_axes_and_figures/align_labels_demo.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/subplots_axes_and_figures/align_labels_demo.html 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | 10 | using namespace std; 11 | using matplotlibcpp17::gridspec::GridSpec; 12 | using namespace matplotlibcpp17; 13 | 14 | int main() { 15 | py::scoped_interpreter guard{}; 16 | auto plt = matplotlibcpp17::pyplot::import(); 17 | auto fig = plt.figure(Args(), Kwargs("tight_layout"_a = true)); 18 | auto gs = GridSpec(2, 2); 19 | // instead of gs[0, :] 20 | auto ax = fig.add_subplot(Args(gs(0, py::slice(0, 2, 1)).unwrap())); 21 | const auto tmp_ = xt::arange(0, 1000000, 10000); 22 | vector tmp(tmp_.begin(), tmp_.end()); 23 | ax.plot(Args(tmp)); 24 | ax.set_ylabel(Args("YLabel0")); 25 | ax.set_xlabel(Args("XLabel0")); 26 | for (auto i : {0, 1}) { 27 | ax = fig.add_subplot(Args(gs(1, i).unwrap())); 28 | const auto ys_ = xt::arange(1.0, 0.0, -0.1); 29 | const auto xs_ = ys_ * 2000; 30 | const vector xs(xs_.begin(), xs_.end()), ys(ys_.begin(), ys_.end()); 31 | ax.plot(Args(xs, ys)); 32 | ax.set_ylabel(Args(string("YLabel1 " + to_string(i)))); 33 | ax.set_xlabel(Args(string("XLabel1 " + to_string(i)))); 34 | if (i == 0) { 35 | for (auto &&tick : ax.get_xticklabels()) 36 | tick.set_rotation(Args(55)); 37 | } 38 | } 39 | fig.align_labels(); 40 | #if USE_GUI 41 | plt.show(); 42 | #else 43 | plt.savefig(Args("align_labels_demo.png")); 44 | #endif 45 | } 46 | -------------------------------------------------------------------------------- /gallery/subplots_axes_and_figures/colorbar_placement.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/subplots_axes_and_figures/colorbar_placement.html 3 | 4 | #include 5 | 6 | #include 7 | 8 | #include 9 | 10 | using namespace std; 11 | using namespace matplotlibcpp17; 12 | 13 | int main1() { 14 | auto plt = matplotlibcpp17::pyplot::import(); 15 | auto [fig, axs] = plt.subplots(2, 2); 16 | const vector cmaps = {"RdBu_r", "viridis"}; 17 | for (auto col : {0, 1}) { 18 | for (auto row : {0, 1}) { 19 | const auto x_ = xt::random::randn({20, 20}) * (col + 1.0); 20 | vector> x(20); 21 | for (int i = 0; i < 20; ++i) { 22 | x[i].resize(20); 23 | for (int j = 0; j < 20; ++j) 24 | x[i][j] = x_(i, j); 25 | } 26 | auto &ax = axs[col + row * 2]; 27 | auto pcm = ax.pcolormesh(Args(x), Kwargs("cmap"_a = cmaps[col])); 28 | fig.colorbar(Args(pcm.unwrap()), 29 | Kwargs("ax"_a = ax.unwrap(), "shrink"_a = 0.6)); 30 | } 31 | } 32 | #if USE_GUI 33 | plt.show(); 34 | #else 35 | plt.savefig(Args("colorbar_placement1.png")); 36 | #endif 37 | return 0; 38 | } 39 | 40 | int main() { 41 | py::scoped_interpreter guard{}; 42 | main1(); 43 | } 44 | -------------------------------------------------------------------------------- /gallery/subplots_axes_and_figures/gridspec_multicolumn.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/subplots_axes_and_figures/gridspec_multicolumn.html 3 | 4 | #include 5 | 6 | #include 7 | 8 | using namespace std; 9 | using matplotlibcpp17::gridspec::GridSpec; 10 | using namespace matplotlibcpp17; 11 | 12 | int main() { 13 | py::scoped_interpreter guard{}; 14 | auto plt = matplotlibcpp17::pyplot::import(); 15 | 16 | auto fig = plt.figure(Args(), Kwargs("constrained_layout"_a = true)); 17 | 18 | auto gs = GridSpec(3, 3, Kwargs("figure"_a = fig.unwrap())); 19 | vector axs; 20 | axs.push_back(fig.add_subplot(Args(gs(0, py::slice(0, 3, 1)).unwrap()))); 21 | axs.push_back(fig.add_subplot(Args(gs(1, py::slice(0, 2, 1)).unwrap()))); 22 | axs.push_back(fig.add_subplot(Args(gs(py::slice(1, 3, 1), 2).unwrap()))); 23 | axs.push_back(fig.add_subplot(Args(gs(2, 0).unwrap()))); 24 | axs.push_back(fig.add_subplot(Args(gs(2, 1).unwrap()))); 25 | fig.suptitle(Args("GridSpec")); 26 | 27 | int cnt = 1; 28 | for (auto &ax : axs) { 29 | ax.text(Args(0.5, 0.5, string("ax" + to_string(cnt))), 30 | Kwargs("va"_a = "center", "ha"_a = "center")); 31 | ax.tick_params(Args(), 32 | Kwargs("labelbottom"_a = false, "labelleft"_a = false)); 33 | cnt++; 34 | } 35 | 36 | #if USE_GUI 37 | plt.show(); 38 | #else 39 | plt.savefig(Args("gridspec_multicolumn.png")); 40 | #endif 41 | } 42 | -------------------------------------------------------------------------------- /gallery/subplots_axes_and_figures/multiple_figs_demo.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/subplots_axes_and_figures/multiple_figs_demo.html 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace matplotlibcpp17; 13 | 14 | int main() { 15 | py::scoped_interpreter guard{}; 16 | auto plt = matplotlibcpp17::pyplot::import(); 17 | const auto x_ = xt::arange(0.0, 2.0, 0.01); 18 | const auto s1_ = xt::sin(2 * M_PI * x_); 19 | const auto s2_ = xt::sin(4 * M_PI * x_); 20 | vector x(x_.begin(), x_.end()), s1(s1_.begin(), s1_.end()), 21 | s2(s2_.begin(), s2_.end()); 22 | plt.figure(Args(1)); 23 | plt.subplot(211); 24 | plt.plot(Args(x, s1)); 25 | plt.subplot(212); 26 | plt.plot(Args(x, s2)); 27 | #if USE_GUI 28 | plt.show(); 29 | #else 30 | plt.savefig(Args("multiple_figs_demo1.png")); 31 | #endif 32 | plt.figure(Args(2)); 33 | plt.plot(Args(x, s2)); 34 | #if USE_GUI 35 | plt.show(); 36 | #else 37 | plt.savefig(Args("multiple_figs_demo2.png")); 38 | #endif 39 | plt.figure(Args(2)); 40 | plt.subplot(211); 41 | plt.plot(Args(x, s2, "s")); 42 | auto ax = plt.gca(); 43 | ax.set_xticklabels(Args(py::list())); 44 | #if USE_GUI 45 | plt.show(); 46 | #else 47 | plt.savefig(Args("multiple_figs_demo3.png")); 48 | #endif 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /gallery/subplots_axes_and_figures/subplots.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | using namespace matplotlibcpp17; 5 | 6 | int main() { 7 | py::scoped_interpreter guard{}; 8 | auto plt = matplotlibcpp17::pyplot::import(); 9 | { 10 | auto [fig, axs] = plt.subplots(3, 1); 11 | std::cout << axs.size() << std::endl; 12 | } 13 | { 14 | auto [fig, axs] = plt.subplots(1, 1); 15 | std::cout << axs.size() << std::endl; 16 | } 17 | { 18 | auto [fig, axs] = plt.subplots(3, 3); 19 | std::cout << axs.size() << std::endl; 20 | } 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /gallery/subplots_axes_and_figures/two_scales.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/subplots_axes_and_figures/two_scales.html 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace matplotlibcpp17; 13 | 14 | int main() { 15 | auto t_ = xt::arange(0.01, 10.0, 0.01); 16 | const auto data1_ = xt::exp(t_); 17 | const auto data2_ = xt::sin(2 * M_PI * t_); 18 | const vector t(t_.begin(), t_.end()), 19 | data1(data1_.begin(), data1_.end()), data2(data2_.begin(), data2_.end()); 20 | 21 | py::scoped_interpreter guard{}; 22 | auto plt = pyplot::import(); 23 | auto [fig, ax1] = plt.subplots(); 24 | 25 | auto color = "tab:red"; 26 | ax1.set_xlabel(Args("time (s)")); 27 | ax1.set_ylabel(Args("exp"), Kwargs("color"_a = color)); 28 | ax1.plot(Args(t, data1), Kwargs("color"_a = color)); 29 | ax1.tick_params(Args(), Kwargs("axis"_a = "y", "labelcolor"_a = color)); 30 | 31 | auto ax2 = 32 | ax1.twinx(); // instantiate a second axes that shares the same x-axis 33 | 34 | color = "tab:blue"; 35 | ax2.set_ylabel(Args("sin"), Kwargs("color"_a = color)); 36 | ax2.plot(Args(t, data2), Kwargs("color"_a = color)); 37 | ax2.tick_params(Args(), Kwargs("axis"_a = "y", "labelcolor"_a = color)); 38 | 39 | fig.tight_layout(); 40 | plt.show(); 41 | } 42 | -------------------------------------------------------------------------------- /gallery/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(test_shared_lib) 2 | add_subdirectory(test_static_lib) 3 | -------------------------------------------------------------------------------- /gallery/tests/test_shared_lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # create library 2 | add_library(test_shared_lib SHARED test_lib.cpp) 3 | target_compile_options(test_shared_lib PUBLIC "-fPIC") 4 | target_link_libraries(test_shared_lib matplotlibcpp17::matplotlibcpp17) 5 | # link it 6 | add_executable(test_lib_main test_lib_main.cpp) 7 | target_link_libraries(test_lib_main test_shared_lib) 8 | -------------------------------------------------------------------------------- /gallery/tests/test_shared_lib/test_lib.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/lines_bars_and_markers/simple_plot.html 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | template std::vector arange(T start, T end, T h) { 10 | int N = static_cast((end - start) / h); 11 | std::vector xs(N); 12 | T val = start; 13 | while (val <= end) { 14 | xs.push_back(val); 15 | val += h; 16 | } 17 | return xs; 18 | } 19 | 20 | using namespace std; 21 | using namespace matplotlibcpp17; 22 | 23 | void func() { 24 | auto plt = matplotlibcpp17::pyplot::import(); 25 | auto t = arange(0.0, 2.0, 0.01); 26 | decltype(t) s; 27 | transform(t.begin(), t.end(), back_inserter(s), 28 | [](double x) { return 1.0 + sin(2 * M_PI * x); }); 29 | 30 | auto [fig, ax] = plt.subplots(); 31 | ax.plot(Args(t, s), Kwargs("color"_a = "blue", "linewidth"_a = 1.0)); 32 | ax.set(Args(), Kwargs("xlabel"_a = "time (s)", "ylabel"_a = "voltage (mV)", 33 | "title"_a = "About as simple as it gets, folks")); 34 | ax.grid(); 35 | 36 | fig.savefig(Args("test.png")); 37 | plt.show(); 38 | } 39 | -------------------------------------------------------------------------------- /gallery/tests/test_shared_lib/test_lib.h: -------------------------------------------------------------------------------- 1 | void func(); 2 | -------------------------------------------------------------------------------- /gallery/tests/test_shared_lib/test_lib_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "test_lib.h" 4 | 5 | namespace py = pybind11; 6 | 7 | int main() { 8 | py::scoped_interpreter guard{}; 9 | func(); 10 | } 11 | -------------------------------------------------------------------------------- /gallery/tests/test_static_lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # create library 2 | add_library(test_static_lib STATIC test_lib.cpp) 3 | target_compile_options(test_static_lib PUBLIC "-fPIC") 4 | target_link_libraries(test_static_lib matplotlibcpp17::matplotlibcpp17) 5 | # link it 6 | add_executable(test_lib_static_main test_lib_main.cpp) 7 | target_link_libraries(test_lib_static_main test_static_lib) 8 | -------------------------------------------------------------------------------- /gallery/tests/test_static_lib/test_lib.cpp: -------------------------------------------------------------------------------- 1 | // example from 2 | // https://matplotlib.org/stable/gallery/lines_bars_and_markers/simple_plot.html 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | template std::vector arange(T start, T end, T h) { 10 | int N = static_cast((end - start) / h); 11 | std::vector xs(N); 12 | T val = start; 13 | while (val <= end) { 14 | xs.push_back(val); 15 | val += h; 16 | } 17 | return xs; 18 | } 19 | 20 | using namespace std; 21 | using namespace matplotlibcpp17; 22 | 23 | void func() { 24 | auto plt = matplotlibcpp17::pyplot::import(); 25 | auto t = arange(0.0, 2.0, 0.01); 26 | decltype(t) s; 27 | transform(t.begin(), t.end(), back_inserter(s), 28 | [](double x) { return 1.0 + sin(2 * M_PI * x); }); 29 | 30 | auto [fig, ax] = plt.subplots(); 31 | ax.plot(Args(t, s), Kwargs("color"_a = "blue", "linewidth"_a = 1.0)); 32 | ax.set(Args(), Kwargs("xlabel"_a = "time (s)", "ylabel"_a = "voltage (mV)", 33 | "title"_a = "About as simple as it gets, folks")); 34 | ax.grid(); 35 | 36 | fig.savefig(Args("test.png")); 37 | plt.show(); 38 | } 39 | -------------------------------------------------------------------------------- /gallery/tests/test_static_lib/test_lib.h: -------------------------------------------------------------------------------- 1 | void func(); 2 | -------------------------------------------------------------------------------- /gallery/tests/test_static_lib/test_lib_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "test_lib.h" 4 | 5 | namespace py = pybind11; 6 | 7 | int main() { 8 | py::scoped_interpreter guard{}; 9 | func(); 10 | } 11 | -------------------------------------------------------------------------------- /hello_world/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | # example of CMakeLists.txt with installed matplotlibcpp17 4 | project(matplotlibcpp17_hello_world) 5 | 6 | find_package(Python3 COMPONENTS Interpreter Development) 7 | find_package(pybind11 REQUIRED) 8 | find_package(matplotlibcpp17 REQUIRED) 9 | 10 | add_executable(hello_world hello_world.cpp) 11 | target_include_directories(hello_world PUBLIC ${Python3_INCLUDE_DIRS}) 12 | target_link_libraries(hello_world ${Python3_LIBRARIES} pybind11::embed 13 | matplotlibcpp17::matplotlibcpp17) 14 | -------------------------------------------------------------------------------- /hello_world/hello_world.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | int main() { 6 | pybind11::scoped_interpreter guard{}; 7 | auto plt = matplotlibcpp17::pyplot::import(); 8 | /// user code 9 | plt.plot(Args(std::vector({1, 3, 2, 4})), 10 | Kwargs("color"_a = "blue", "linewidth"_a = 1.0)); 11 | plt.show(); 12 | } 13 | -------------------------------------------------------------------------------- /include/matplotlibcpp17/animation.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file animation.h 3 | * @brief corresponding header for matplotlib.animation 4 | **/ 5 | #pragma once 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace matplotlibcpp17::animation { 12 | 13 | /** 14 | * @brief A wrapper class for matplotlib.animation.ArtistAnimation 15 | **/ 16 | struct DECL_STRUCT_ATTR ArtistAnimation : public BaseWrapper { 17 | public: 18 | ArtistAnimation(const pybind11::tuple &args, const pybind11::dict &kwargs) { 19 | pybind11::object attr = pybind11::module::import("matplotlib.animation") 20 | .attr("ArtistAnimation"); 21 | self = attr(*args, **kwargs); 22 | load_attrs(); 23 | } 24 | // save 25 | ObjectWrapper save(const pybind11::tuple &args = pybind11::tuple(), 26 | const pybind11::dict &kwargs = pybind11::dict()); 27 | 28 | private: 29 | void load_attrs() { LOAD_FUNC_ATTR(save, self); } 30 | pybind11::object save_attr; 31 | }; 32 | 33 | // save 34 | ObjectWrapper ArtistAnimation::save(const pybind11::tuple &args, 35 | const pybind11::dict &kwargs) { 36 | pybind11::object ret = save_attr(*args, **kwargs); 37 | return ObjectWrapper(std::move(ret)); 38 | } 39 | 40 | } // namespace matplotlibcpp17::animation 41 | -------------------------------------------------------------------------------- /include/matplotlibcpp17/axes.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file axes.h 3 | * @brief corresponding header for matplotlib.axes 4 | **/ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | namespace matplotlibcpp17::axes { 20 | 21 | /** 22 | * @brief Return type for hist() 23 | **/ 24 | using HistType = std::tuple, std::vector, 25 | container::BarContainer>; 26 | 27 | /** 28 | * @brief A wrapper class for matplotlib.axes.Axes 29 | **/ 30 | struct DECL_STRUCT_ATTR Axes : public BaseWrapper { 31 | public: 32 | Axes(const pybind11::object &axes) { 33 | self = axes; 34 | load_attrs(); 35 | } 36 | Axes(pybind11::object &&axes) { 37 | self = std::move(axes); 38 | load_attrs(); 39 | } 40 | 41 | // add_artist 42 | ObjectWrapper add_artist(const pybind11::tuple &args = pybind11::tuple(), 43 | const pybind11::dict &kwargs = pybind11::dict()); 44 | 45 | // add_collection 46 | ObjectWrapper add_collection(const pybind11::tuple &args = pybind11::tuple(), 47 | const pybind11::dict &kwargs = pybind11::dict()); 48 | 49 | // add_patch 50 | ObjectWrapper add_patch(const pybind11::tuple &args = pybind11::tuple(), 51 | const pybind11::dict &kwargs = pybind11::dict()); 52 | 53 | // axhline 54 | ObjectWrapper axhline(const pybind11::tuple &args = pybind11::tuple(), 55 | const pybind11::dict &kwargs = pybind11::dict()); 56 | // axvline 57 | ObjectWrapper axvline(const pybind11::tuple &args = pybind11::tuple(), 58 | const pybind11::dict &kwargs = pybind11::dict()); 59 | 60 | // bar 61 | container::BarContainer bar(const pybind11::tuple &args = pybind11::tuple(), 62 | const pybind11::dict &kwargs = pybind11::dict()); 63 | 64 | // bar_label 65 | ObjectWrapper bar_label(const pybind11::tuple &args = pybind11::tuple(), 66 | const pybind11::dict &kwargs = pybind11::dict()); 67 | 68 | // barh 69 | container::BarContainer barh(const pybind11::tuple &args = pybind11::tuple(), 70 | const pybind11::dict &kwargs = pybind11::dict()); 71 | 72 | // cla 73 | ObjectWrapper cla(const pybind11::tuple &args = pybind11::tuple(), 74 | const pybind11::dict &kwargs = pybind11::dict()); 75 | 76 | // contour 77 | ObjectWrapper contour(const pybind11::tuple &args = pybind11::tuple(), 78 | const pybind11::dict &kwargs = pybind11::dict()); 79 | 80 | // contourf 81 | ObjectWrapper contourf(const pybind11::tuple &args = pybind11::tuple(), 82 | const pybind11::dict &kwargs = pybind11::dict()); 83 | 84 | // errorbar 85 | ObjectWrapper errorbar(const pybind11::tuple &args = pybind11::tuple(), 86 | const pybind11::dict &kwargs = pybind11::dict()); 87 | 88 | // fill 89 | ObjectWrapper fill(const pybind11::tuple &args = pybind11::tuple(), 90 | const pybind11::dict &kwargs = pybind11::dict()); 91 | 92 | // fill_between 93 | ObjectWrapper fill_between(const pybind11::tuple &args = pybind11::tuple(), 94 | const pybind11::dict &kwargs = pybind11::dict()); 95 | 96 | // fill_betweenx 97 | ObjectWrapper fill_betweenx(const pybind11::tuple &args = pybind11::tuple(), 98 | const pybind11::dict &kwargs = pybind11::dict()); 99 | 100 | // get_lines 101 | ObjectWrapper get_lines(const pybind11::tuple &args = pybind11::tuple(), 102 | const pybind11::dict &kwargs = pybind11::dict()); 103 | 104 | // get_xaxis_transform 105 | ObjectWrapper 106 | get_xaxis_transform(const pybind11::tuple &args = pybind11::tuple(), 107 | const pybind11::dict &kwargs = pybind11::dict()); 108 | 109 | // get_xlim 110 | std::tuple get_xlim(); 111 | 112 | // get_xticklabels 113 | std::vector get_xticklabels(); 114 | 115 | // grid 116 | ObjectWrapper grid(const pybind11::tuple &args = pybind11::tuple(), 117 | const pybind11::dict &kwargs = pybind11::dict()); 118 | 119 | // hist 120 | HistType hist(const pybind11::tuple &args = pybind11::tuple(), 121 | const pybind11::dict &kwargs = pybind11::dict()); 122 | 123 | // hist2d 124 | ObjectWrapper hist2d(const pybind11::tuple &args = pybind11::tuple(), 125 | const pybind11::dict &kwargs = pybind11::dict()); 126 | 127 | // imshow 128 | ObjectWrapper imshow(const pybind11::tuple &args = pybind11::tuple(), 129 | const pybind11::dict &kwargs = pybind11::dict()); 130 | 131 | // invert_yaxis 132 | ObjectWrapper invert_yaxis(const pybind11::tuple &args = pybind11::tuple(), 133 | const pybind11::dict &kwargs = pybind11::dict()); 134 | 135 | // legend 136 | legend::Legend legend(const pybind11::tuple &args = pybind11::tuple(), 137 | const pybind11::dict &kwargs = pybind11::dict()); 138 | 139 | // pcolormesh 140 | collections::QuadMesh 141 | pcolormesh(const pybind11::tuple &args = pybind11::tuple(), 142 | const pybind11::dict &kwargs = pybind11::dict()); 143 | 144 | // plot 145 | ObjectWrapper plot(const pybind11::tuple &args = pybind11::tuple(), 146 | const pybind11::dict &kwargs = pybind11::dict()); 147 | 148 | // plot_surface 149 | ObjectWrapper plot_surface(const pybind11::tuple &args = pybind11::tuple(), 150 | const pybind11::dict &kwargs = pybind11::dict()); 151 | 152 | // plot_wireframe 153 | ObjectWrapper plot_wireframe(const pybind11::tuple &args = pybind11::tuple(), 154 | const pybind11::dict &kwargs = pybind11::dict()); 155 | 156 | // quiver 157 | quiver::Quiver quiver(const pybind11::tuple &args = pybind11::tuple(), 158 | const pybind11::dict &kwargs = pybind11::dict()); 159 | 160 | // quiverkey 161 | quiver::QuiverKey quiverkey(const pybind11::tuple &args = pybind11::tuple(), 162 | const pybind11::dict &kwargs = pybind11::dict()); 163 | 164 | // scatter 165 | collections::PathCollection 166 | scatter(const pybind11::tuple &args = pybind11::tuple(), 167 | const pybind11::dict &kwargs = pybind11::dict()); 168 | 169 | // set 170 | ObjectWrapper set(const pybind11::tuple &args = pybind11::tuple(), 171 | const pybind11::dict &kwargs = pybind11::dict()); 172 | 173 | // set_adjustable 174 | ObjectWrapper set_adjustable(const pybind11::tuple &args = pybind11::tuple(), 175 | const pybind11::dict &kwargs = pybind11::dict()); 176 | 177 | // set_aspect 178 | ObjectWrapper set_aspect(const pybind11::tuple &args = pybind11::tuple(), 179 | const pybind11::dict &kwargs = pybind11::dict()); 180 | 181 | // set_title 182 | ObjectWrapper set_title(const pybind11::tuple &args = pybind11::tuple(), 183 | const pybind11::dict &kwargs = pybind11::dict()); 184 | 185 | // set_xlabel 186 | ObjectWrapper set_xlabel(const pybind11::tuple &args = pybind11::tuple(), 187 | const pybind11::dict &kwargs = pybind11::dict()); 188 | 189 | // set_xlim 190 | ObjectWrapper set_xlim(const pybind11::tuple &args = pybind11::tuple(), 191 | const pybind11::dict &kwargs = pybind11::dict()); 192 | 193 | // set_xscale 194 | ObjectWrapper set_xscale(const pybind11::tuple &args = pybind11::tuple(), 195 | const pybind11::dict &kwargs = pybind11::dict()); 196 | 197 | // set_xticks 198 | ObjectWrapper set_xticks(const pybind11::tuple &args = pybind11::tuple(), 199 | const pybind11::dict &kwargs = pybind11::dict()); 200 | 201 | // set_xticklabels 202 | ObjectWrapper 203 | set_xticklabels(const pybind11::tuple &args = pybind11::tuple(), 204 | const pybind11::dict &kwargs = pybind11::dict()); 205 | 206 | // set_ylabel 207 | ObjectWrapper set_ylabel(const pybind11::tuple &args = pybind11::tuple(), 208 | const pybind11::dict &kwargs = pybind11::dict()); 209 | 210 | // set_ylim 211 | ObjectWrapper set_ylim(const pybind11::tuple &args = pybind11::tuple(), 212 | const pybind11::dict &kwargs = pybind11::dict()); 213 | 214 | // set_yscale 215 | ObjectWrapper set_yscale(const pybind11::tuple &args = pybind11::tuple(), 216 | const pybind11::dict &kwargs = pybind11::dict()); 217 | 218 | // set_yticks 219 | ObjectWrapper set_yticks(const pybind11::tuple &args = pybind11::tuple(), 220 | const pybind11::dict &kwargs = pybind11::dict()); 221 | 222 | // set_zlabel 223 | ObjectWrapper set_zlabel(const pybind11::tuple &args = pybind11::tuple(), 224 | const pybind11::dict &kwargs = pybind11::dict()); 225 | 226 | // set_zlim 227 | ObjectWrapper set_zlim(const pybind11::tuple &args = pybind11::tuple(), 228 | const pybind11::dict &kwargs = pybind11::dict()); 229 | 230 | // text 231 | ObjectWrapper text(const pybind11::tuple &args = pybind11::tuple(), 232 | const pybind11::dict &kwargs = pybind11::dict()); 233 | 234 | // tick_params 235 | ObjectWrapper tick_params(const pybind11::tuple &args = pybind11::tuple(), 236 | const pybind11::dict &kwargs = pybind11::dict()); 237 | 238 | // twinx 239 | Axes twinx(const pybind11::tuple &args = pybind11::tuple(), 240 | const pybind11::dict &kwargs = pybind11::dict()); 241 | 242 | private: 243 | void load_attrs() { 244 | // NOTE: only when called with projection='3d', `plot_surface`, 245 | // `plot_wireframe`, `set_zlabel` prop exists. 246 | try { 247 | LOAD_FUNC_ATTR(plot_surface, self); 248 | LOAD_FUNC_ATTR(plot_wireframe, self); 249 | LOAD_FUNC_ATTR(set_zlabel, self); 250 | LOAD_FUNC_ATTR(set_zlim, self); 251 | INFO_MSG("Loaded Axes3D"); 252 | projection_3d = true; 253 | } catch (...) { 254 | projection_3d = false; 255 | } 256 | LOAD_FUNC_ATTR(add_artist, self); 257 | LOAD_FUNC_ATTR(add_collection, self); 258 | LOAD_FUNC_ATTR(add_patch, self); 259 | LOAD_FUNC_ATTR(axhline, self); 260 | LOAD_FUNC_ATTR(axvline, self); 261 | LOAD_FUNC_ATTR(bar, self); 262 | #if MATPLOTLIB_MINOR_VER_GTE_4 263 | LOAD_FUNC_ATTR(bar_label, self); 264 | #else 265 | WARN_MSG("Not loading bar_label because matplotlib version is < 3.4.0"); 266 | #endif 267 | LOAD_FUNC_ATTR(barh, self); 268 | LOAD_FUNC_ATTR(cla, self); 269 | LOAD_FUNC_ATTR(contour, self); 270 | LOAD_FUNC_ATTR(contourf, self); 271 | LOAD_FUNC_ATTR(errorbar, self); 272 | LOAD_FUNC_ATTR(fill, self); 273 | LOAD_FUNC_ATTR(fill_between, self); 274 | LOAD_FUNC_ATTR(fill_betweenx, self); 275 | LOAD_FUNC_ATTR(get_lines, self); 276 | LOAD_FUNC_ATTR(get_xaxis_transform, self); 277 | LOAD_FUNC_ATTR(get_xlim, self); 278 | LOAD_FUNC_ATTR(get_xticklabels, self); 279 | LOAD_FUNC_ATTR(grid, self); 280 | LOAD_FUNC_ATTR(hist, self); 281 | LOAD_FUNC_ATTR(hist2d, self); 282 | LOAD_FUNC_ATTR(invert_yaxis, self); 283 | LOAD_FUNC_ATTR(imshow, self); 284 | LOAD_FUNC_ATTR(legend, self); 285 | LOAD_FUNC_ATTR(pcolormesh, self); 286 | LOAD_FUNC_ATTR(plot, self); 287 | LOAD_FUNC_ATTR(quiver, self); 288 | LOAD_FUNC_ATTR(quiverkey, self); 289 | LOAD_FUNC_ATTR(scatter, self); 290 | LOAD_FUNC_ATTR(set, self); 291 | LOAD_FUNC_ATTR(set_adjustable, self); 292 | LOAD_FUNC_ATTR(set_aspect, self); 293 | LOAD_FUNC_ATTR(set_title, self); 294 | LOAD_FUNC_ATTR(set_xlabel, self); 295 | LOAD_FUNC_ATTR(set_xlim, self); 296 | LOAD_FUNC_ATTR(set_xscale, self); 297 | LOAD_FUNC_ATTR(set_xticks, self); 298 | LOAD_FUNC_ATTR(set_xticklabels, self); 299 | LOAD_FUNC_ATTR(set_ylabel, self); 300 | LOAD_FUNC_ATTR(set_ylim, self); 301 | LOAD_FUNC_ATTR(set_yscale, self); 302 | LOAD_FUNC_ATTR(set_yticks, self); 303 | LOAD_FUNC_ATTR(text, self); 304 | LOAD_FUNC_ATTR(tick_params, self); 305 | LOAD_FUNC_ATTR(twinx, self); 306 | } 307 | pybind11::object add_artist_attr; 308 | pybind11::object add_collection_attr; 309 | pybind11::object add_patch_attr; 310 | pybind11::object axhline_attr; 311 | pybind11::object axvline_attr; 312 | pybind11::object bar_attr; 313 | pybind11::object bar_label_attr; 314 | pybind11::object barh_attr; 315 | pybind11::object cla_attr; 316 | pybind11::object contour_attr; 317 | pybind11::object contourf_attr; 318 | pybind11::object errorbar_attr; 319 | pybind11::object fill_attr; 320 | pybind11::object fill_between_attr; 321 | pybind11::object fill_betweenx_attr; 322 | pybind11::object get_lines_attr; 323 | pybind11::object get_xaxis_transform_attr; 324 | pybind11::object get_xlim_attr; 325 | pybind11::object get_xticklabels_attr; 326 | pybind11::object grid_attr; 327 | pybind11::object hist_attr; 328 | pybind11::object hist2d_attr; 329 | pybind11::object invert_yaxis_attr; 330 | pybind11::object imshow_attr; 331 | pybind11::object legend_attr; 332 | pybind11::object pcolormesh_attr; 333 | pybind11::object plot_attr; 334 | pybind11::object plot_surface_attr; 335 | pybind11::object plot_wireframe_attr; 336 | pybind11::object quiver_attr; 337 | pybind11::object quiverkey_attr; 338 | pybind11::object scatter_attr; 339 | pybind11::object set_attr; 340 | pybind11::object set_adjustable_attr; 341 | pybind11::object set_aspect_attr; 342 | pybind11::object set_title_attr; 343 | pybind11::object set_xlabel_attr; 344 | pybind11::object set_xlim_attr; 345 | pybind11::object set_xscale_attr; 346 | pybind11::object set_xticks_attr; 347 | pybind11::object set_xticklabels_attr; 348 | pybind11::object set_ylabel_attr; 349 | pybind11::object set_ylim_attr; 350 | pybind11::object set_yscale_attr; 351 | pybind11::object set_yticks_attr; 352 | pybind11::object set_zlabel_attr; 353 | pybind11::object set_zlim_attr; 354 | pybind11::object text_attr; 355 | pybind11::object tick_params_attr; 356 | pybind11::object twinx_attr; 357 | // 3d 358 | bool projection_3d; 359 | }; 360 | 361 | // add_artist 362 | inline ObjectWrapper Axes::add_artist(const pybind11::tuple &args, 363 | const pybind11::dict &kwargs) { 364 | pybind11::object ret = add_artist_attr(*args, **kwargs); 365 | return ObjectWrapper(std::move(ret)); 366 | } 367 | 368 | // add_collection 369 | inline ObjectWrapper Axes::add_collection(const pybind11::tuple &args, 370 | const pybind11::dict &kwargs) { 371 | pybind11::object ret = add_collection_attr(*args, **kwargs); 372 | return ObjectWrapper(std::move(ret)); 373 | } 374 | 375 | // add_patch 376 | inline ObjectWrapper Axes::add_patch(const pybind11::tuple &args, 377 | const pybind11::dict &kwargs) { 378 | pybind11::object ret = add_patch_attr(*args, **kwargs); 379 | return ObjectWrapper(std::move(ret)); 380 | } 381 | 382 | // axhline 383 | inline ObjectWrapper Axes::axhline(const pybind11::tuple &args, 384 | const pybind11::dict &kwargs) { 385 | pybind11::object ret = axhline_attr(*args, **kwargs); 386 | return ObjectWrapper(std::move(ret)); 387 | } 388 | 389 | // axvline 390 | inline ObjectWrapper Axes::axvline(const pybind11::tuple &args, 391 | const pybind11::dict &kwargs) { 392 | pybind11::object ret = axvline_attr(*args, **kwargs); 393 | return ObjectWrapper(std::move(ret)); 394 | } 395 | 396 | // bar 397 | inline container::BarContainer Axes::bar(const pybind11::tuple &args, 398 | const pybind11::dict &kwargs) { 399 | pybind11::object obj = bar_attr(*args, **kwargs); 400 | return container::BarContainer(obj); 401 | } 402 | 403 | // bar_label 404 | inline ObjectWrapper Axes::bar_label(const pybind11::tuple &args, 405 | const pybind11::dict &kwargs) { 406 | #if MATPLOTLIB_MINOR_VER_GTE_4 407 | pybind11::object ret = bar_label_attr(*args, **kwargs); 408 | return ObjectWrapper(std::move(ret)); 409 | #else 410 | ERROR_MSG( 411 | "Call to bar_label is invalid because matplotlib version is < 3.4.0"); 412 | std::exit(0); 413 | #endif 414 | } 415 | 416 | // barh 417 | inline container::BarContainer Axes::barh(const pybind11::tuple &args, 418 | const pybind11::dict &kwargs) { 419 | pybind11::object obj = barh_attr(*args, **kwargs); 420 | return container::BarContainer(obj); 421 | } 422 | 423 | // cla 424 | inline ObjectWrapper Axes::cla(const pybind11::tuple &args, 425 | const pybind11::dict &kwargs) { 426 | pybind11::object ret = cla_attr(*args, **kwargs); 427 | return ObjectWrapper(std::move(ret)); 428 | } 429 | 430 | // contour 431 | inline ObjectWrapper Axes::contour(const pybind11::tuple &args, 432 | const pybind11::dict &kwargs) { 433 | pybind11::object ret = contour_attr(*args, **kwargs); 434 | return ObjectWrapper(std::move(ret)); 435 | } 436 | 437 | // contourf 438 | inline ObjectWrapper Axes::contourf(const pybind11::tuple &args, 439 | const pybind11::dict &kwargs) { 440 | pybind11::object ret = contourf_attr(*args, **kwargs); 441 | return ObjectWrapper(std::move(ret)); 442 | } 443 | 444 | // errorbar 445 | inline ObjectWrapper Axes::errorbar(const pybind11::tuple &args, 446 | const pybind11::dict &kwargs) { 447 | if (projection_3d) { 448 | #if MATPLOTLIB_MINOR_VER_GTE_4 449 | pybind11::object obj = errorbar_attr(*args, **kwargs); 450 | return obj; 451 | #else 452 | ERROR_MSG("Call to errorbar with projection='3d' is invalid because " 453 | "matplotlib version is < 3.4.0"); 454 | std::exit(0); 455 | #endif 456 | } else { 457 | pybind11::object ret = errorbar_attr(*args, **kwargs); 458 | return ObjectWrapper(std::move(ret)); 459 | } 460 | } 461 | 462 | // fill 463 | inline ObjectWrapper Axes::fill(const pybind11::tuple &args, 464 | const pybind11::dict &kwargs) { 465 | pybind11::object ret = fill_attr(*args, **kwargs); 466 | return ObjectWrapper(std::move(ret)); 467 | } 468 | 469 | // fill_between 470 | inline ObjectWrapper Axes::fill_between(const pybind11::tuple &args, 471 | const pybind11::dict &kwargs) { 472 | pybind11::object ret = fill_between_attr(*args, **kwargs); 473 | return ObjectWrapper(std::move(ret)); 474 | } 475 | 476 | // fill_betweenx 477 | inline ObjectWrapper Axes::fill_betweenx(const pybind11::tuple &args, 478 | const pybind11::dict &kwargs) { 479 | pybind11::object ret = fill_betweenx_attr(*args, **kwargs); 480 | return ObjectWrapper(std::move(ret)); 481 | } 482 | 483 | // get_lines 484 | inline ObjectWrapper Axes::get_lines(const pybind11::tuple &args, 485 | const pybind11::dict &kwargs) { 486 | pybind11::object ret = get_lines_attr(*args, **kwargs); 487 | return ObjectWrapper(std::move(ret)); 488 | } 489 | 490 | // get_xaxis_transform 491 | inline ObjectWrapper Axes::get_xaxis_transform(const pybind11::tuple &args, 492 | const pybind11::dict &kwargs) { 493 | pybind11::object ret = get_xaxis_transform_attr(*args, **kwargs); 494 | return ObjectWrapper(std::move(ret)); 495 | } 496 | 497 | // get_xlim 498 | inline std::tuple Axes::get_xlim() { 499 | pybind11::list ret = get_xlim_attr(); 500 | double x1 = ret[0].cast(); 501 | double x2 = ret[1].cast(); 502 | return {x1, x2}; 503 | } 504 | 505 | // get_xticklabels 506 | inline std::vector Axes::get_xticklabels() { 507 | pybind11::list ret = get_xticklabels_attr(); 508 | std::vector texts; 509 | for (pybind11::size_t i = 0; i < ret.size(); ++i) { 510 | texts.push_back(text::Text(ret[i])); 511 | } 512 | return texts; 513 | } 514 | 515 | // grid 516 | inline ObjectWrapper Axes::grid(const pybind11::tuple &args, 517 | const pybind11::dict &kwargs) { 518 | pybind11::object ret = grid_attr(*args, **kwargs); 519 | return ObjectWrapper(std::move(ret)); 520 | } 521 | 522 | // hist 523 | inline std::tuple, std::vector, 524 | container::BarContainer> 525 | Axes::hist(const pybind11::tuple &args, const pybind11::dict &kwargs) { 526 | pybind11::list ret = hist_attr(*args, **kwargs); 527 | // parse N, bins, patches 528 | pybind11::list N_obj = ret[0], bins_obj = ret[1]; 529 | pybind11::object patches_obj = ret[2]; 530 | std::vector N, bins; 531 | for (auto it = N_obj.begin(); it != N_obj.end(); it++) { 532 | N.push_back(it->cast()); 533 | } 534 | for (auto it = bins_obj.begin(); it != bins_obj.end(); it++) { 535 | bins.push_back(it->cast()); 536 | } 537 | return {N, bins, container::BarContainer(patches_obj)}; 538 | } 539 | 540 | // hist2d 541 | inline ObjectWrapper Axes::hist2d(const pybind11::tuple &args, 542 | const pybind11::dict &kwargs) { 543 | pybind11::object ret = hist2d_attr(*args, **kwargs); 544 | return ObjectWrapper(std::move(ret)); 545 | } 546 | 547 | // invert_yaxis 548 | inline ObjectWrapper Axes::invert_yaxis(const pybind11::tuple &args, 549 | const pybind11::dict &kwargs) { 550 | pybind11::object ret = invert_yaxis_attr(*args, **kwargs); 551 | return ObjectWrapper(std::move(ret)); 552 | } 553 | 554 | // imshow 555 | inline ObjectWrapper Axes::imshow(const pybind11::tuple &args, 556 | const pybind11::dict &kwargs) { 557 | pybind11::object ret = imshow_attr(*args, **kwargs); 558 | return ObjectWrapper(std::move(ret)); 559 | } 560 | 561 | // legend 562 | inline legend::Legend Axes::legend(const pybind11::tuple &args, 563 | const pybind11::dict &kwargs) { 564 | pybind11::object obj = legend_attr(*args, **kwargs); 565 | return legend::Legend(obj); 566 | } 567 | 568 | // pcolormesh 569 | inline collections::QuadMesh Axes::pcolormesh(const pybind11::tuple &args, 570 | const pybind11::dict &kwargs) { 571 | pybind11::object ret = pcolormesh_attr(*args, **kwargs); 572 | return collections::QuadMesh(ret); 573 | } 574 | 575 | // plot 576 | inline ObjectWrapper Axes::plot(const pybind11::tuple &args, 577 | const pybind11::dict &kwargs) { 578 | pybind11::object ret = plot_attr(*args, **kwargs); 579 | return ObjectWrapper(std::move(ret)); 580 | } 581 | 582 | // plot_surface 583 | inline ObjectWrapper Axes::plot_surface(const pybind11::tuple &args, 584 | const pybind11::dict &kwargs) { 585 | pybind11::object ret = plot_surface_attr(*args, **kwargs); 586 | return ObjectWrapper(std::move(ret)); 587 | } 588 | 589 | // plot_wireframe 590 | inline ObjectWrapper Axes::plot_wireframe(const pybind11::tuple &args, 591 | const pybind11::dict &kwargs) { 592 | pybind11::object ret = plot_wireframe_attr(*args, **kwargs); 593 | return ObjectWrapper(std::move(ret)); 594 | } 595 | 596 | // quiver 597 | inline quiver::Quiver Axes::quiver(const pybind11::tuple &args, 598 | const pybind11::dict &kwargs) { 599 | pybind11::object obj = quiver_attr(*args, **kwargs); 600 | return quiver::Quiver(obj); 601 | } 602 | 603 | // quiverkey 604 | inline quiver::QuiverKey Axes::quiverkey(const pybind11::tuple &args, 605 | const pybind11::dict &kwargs) { 606 | pybind11::object obj = quiverkey_attr(*args, **kwargs); 607 | return quiver::QuiverKey(obj); 608 | } 609 | 610 | // scatter 611 | inline collections::PathCollection Axes::scatter(const pybind11::tuple &args, 612 | const pybind11::dict &kwargs) { 613 | pybind11::object obj = scatter_attr(*args, **kwargs); 614 | return collections::PathCollection(obj); 615 | } 616 | 617 | // set 618 | inline ObjectWrapper Axes::set(const pybind11::tuple &args, 619 | const pybind11::dict &kwargs) { 620 | pybind11::object ret = set_attr(*args, **kwargs); 621 | return ObjectWrapper(std::move(ret)); 622 | } 623 | 624 | // set_adjustable 625 | inline ObjectWrapper Axes::set_adjustable(const pybind11::tuple &args, 626 | const pybind11::dict &kwargs) { 627 | pybind11::object ret = set_adjustable_attr(*args, **kwargs); 628 | return ObjectWrapper(std::move(ret)); 629 | } 630 | 631 | // set_aspect 632 | inline ObjectWrapper Axes::set_aspect(const pybind11::tuple &args, 633 | const pybind11::dict &kwargs) { 634 | pybind11::object ret = set_aspect_attr(*args, **kwargs); 635 | return ObjectWrapper(std::move(ret)); 636 | } 637 | 638 | // set_title 639 | inline ObjectWrapper Axes::set_title(const pybind11::tuple &args, 640 | const pybind11::dict &kwargs) { 641 | pybind11::object ret = set_title_attr(*args, **kwargs); 642 | return ObjectWrapper(std::move(ret)); 643 | } 644 | 645 | // set_xlabel 646 | inline ObjectWrapper Axes::set_xlabel(const pybind11::tuple &args, 647 | const pybind11::dict &kwargs) { 648 | pybind11::object ret = set_xlabel_attr(*args, **kwargs); 649 | return ObjectWrapper(std::move(ret)); 650 | } 651 | 652 | // set_xlim 653 | inline ObjectWrapper Axes::set_xlim(const pybind11::tuple &args, 654 | const pybind11::dict &kwargs) { 655 | pybind11::object ret = set_xlim_attr(*args, **kwargs); 656 | return ObjectWrapper(std::move(ret)); 657 | } 658 | 659 | // set_xscale 660 | inline ObjectWrapper Axes::set_xscale(const pybind11::tuple &args, 661 | const pybind11::dict &kwargs) { 662 | pybind11::object ret = set_xscale_attr(*args, **kwargs); 663 | return ObjectWrapper(std::move(ret)); 664 | } 665 | 666 | // set_xticks 667 | inline ObjectWrapper Axes::set_xticks(const pybind11::tuple &args, 668 | const pybind11::dict &kwargs) { 669 | pybind11::object ret = set_xticks_attr(*args, **kwargs); 670 | return ObjectWrapper(std::move(ret)); 671 | } 672 | 673 | // set_xticklabels 674 | inline ObjectWrapper Axes::set_xticklabels(const pybind11::tuple &args, 675 | const pybind11::dict &kwargs) { 676 | pybind11::object ret = set_xticklabels_attr(*args, **kwargs); 677 | return ObjectWrapper(std::move(ret)); 678 | } 679 | 680 | // set_ylabel 681 | inline ObjectWrapper Axes::set_ylabel(const pybind11::tuple &args, 682 | const pybind11::dict &kwargs) { 683 | pybind11::object ret = set_ylabel_attr(*args, **kwargs); 684 | return ObjectWrapper(std::move(ret)); 685 | } 686 | 687 | // set_ylim 688 | inline ObjectWrapper Axes::set_ylim(const pybind11::tuple &args, 689 | const pybind11::dict &kwargs) { 690 | pybind11::object ret = set_ylim_attr(*args, **kwargs); 691 | return ObjectWrapper(std::move(ret)); 692 | } 693 | 694 | // set_yscale 695 | inline ObjectWrapper Axes::set_yscale(const pybind11::tuple &args, 696 | const pybind11::dict &kwargs) { 697 | pybind11::object ret = set_yscale_attr(*args, **kwargs); 698 | return ObjectWrapper(std::move(ret)); 699 | } 700 | 701 | // set_yticks 702 | inline ObjectWrapper Axes::set_yticks(const pybind11::tuple &args, 703 | const pybind11::dict &kwargs) { 704 | pybind11::object ret = set_yticks_attr(*args, **kwargs); 705 | return ObjectWrapper(std::move(ret)); 706 | } 707 | 708 | // set_zlabel 709 | inline ObjectWrapper Axes::set_zlabel(const pybind11::tuple &args, 710 | const pybind11::dict &kwargs) { 711 | pybind11::object ret = set_zlabel_attr(*args, **kwargs); 712 | return ObjectWrapper(std::move(ret)); 713 | } 714 | 715 | // set_zlim 716 | inline ObjectWrapper Axes::set_zlim(const pybind11::tuple &args, 717 | const pybind11::dict &kwargs) { 718 | pybind11::object ret = set_zlim_attr(*args, **kwargs); 719 | return ObjectWrapper(std::move(ret)); 720 | } 721 | 722 | // text 723 | inline ObjectWrapper Axes::text(const pybind11::tuple &args, 724 | const pybind11::dict &kwargs) { 725 | pybind11::object ret = text_attr(*args, **kwargs); 726 | return ObjectWrapper(std::move(ret)); 727 | } 728 | 729 | // tick_params 730 | inline ObjectWrapper Axes::tick_params(const pybind11::tuple &args, 731 | const pybind11::dict &kwargs) { 732 | pybind11::object ret = tick_params_attr(*args, **kwargs); 733 | return ObjectWrapper(std::move(ret)); 734 | } 735 | 736 | // twinx 737 | inline Axes Axes::twinx(const pybind11::tuple &args, 738 | const pybind11::dict &kwargs) { 739 | pybind11::object ret = twinx_attr(*args, **kwargs); 740 | return Axes(ret); 741 | } 742 | 743 | } // namespace matplotlibcpp17::axes 744 | -------------------------------------------------------------------------------- /include/matplotlibcpp17/cm.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file cm.h 3 | * @brief corresponding header for matplotlib.cm 4 | **/ 5 | #pragma once 6 | 7 | #include 8 | 9 | namespace matplotlibcpp17::cm { 10 | 11 | // TODO: more colors 12 | static const char *coolwarm = "coolwarm"; 13 | static const char *PuBu_r = "PuBu_r"; 14 | static const char *RdYlGn = "RdYlGn"; 15 | 16 | } // namespace matplotlibcpp17::cm 17 | -------------------------------------------------------------------------------- /include/matplotlibcpp17/collections.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file collections.h 3 | * @brief corresponding header for matplotlib.collections 4 | **/ 5 | #pragma once 6 | 7 | #include 8 | 9 | #include 10 | 11 | #include 12 | 13 | namespace matplotlibcpp17::collections { 14 | 15 | /** 16 | * @brief A wrapper class for matplotlib.collections.PathCollection 17 | **/ 18 | struct DECL_STRUCT_ATTR PathCollection : public BaseWrapper { 19 | public: 20 | PathCollection(const pybind11::object &pathcollection) { 21 | self = pathcollection; 22 | load_attrs(); 23 | } 24 | PathCollection(pybind11::object &&pathcollection) { 25 | self = std::move(pathcollection); 26 | load_attrs(); 27 | } 28 | 29 | // legend_elements 30 | std::pair 31 | legend_elements(const pybind11::tuple &args = pybind11::tuple(), 32 | const pybind11::dict &kwargs = pybind11::dict()); 33 | 34 | private: 35 | void load_attrs() { LOAD_FUNC_ATTR(legend_elements, self); } 36 | pybind11::object legend_elements_attr; 37 | }; 38 | 39 | // legend_elements 40 | /// NOTE: this func does not return list of Line2Ds(handles) and list of 41 | /// strs(labels) unlike original python func 42 | inline std::pair 43 | PathCollection::legend_elements(const pybind11::tuple &args, 44 | const pybind11::dict &kwargs) { 45 | pybind11::list ret = legend_elements_attr(*args, **kwargs); 46 | pybind11::object handles = ret[0]; 47 | pybind11::object labels = ret[1]; 48 | return {ObjectWrapper(std::move(handles)), ObjectWrapper(std::move(labels))}; 49 | } 50 | 51 | /** 52 | * @brief A wrapper class for matplotlib.collections.PatchCollection 53 | **/ 54 | struct DECL_STRUCT_ATTR PatchCollection : public BaseWrapper { 55 | public: 56 | PatchCollection(const pybind11::tuple &args = pybind11::tuple(), 57 | const pybind11::dict &kwargs = pybind11::dict()) { 58 | pybind11::object attr = pybind11::module::import("matplotlib.collections") 59 | .attr("PatchCollection"); 60 | self = attr(*args, **kwargs); 61 | load_attrs(); 62 | } 63 | 64 | // set_array 65 | ObjectWrapper set_array(const pybind11::tuple &args = pybind11::tuple(), 66 | const pybind11::dict &kwargs = pybind11::dict()); 67 | 68 | private: 69 | void load_attrs() { LOAD_FUNC_ATTR(set_array, self); } 70 | pybind11::object set_array_attr; 71 | }; 72 | 73 | inline ObjectWrapper PatchCollection::set_array(const pybind11::tuple &args, 74 | const pybind11::dict &kwargs) { 75 | pybind11::object ret = set_array_attr(*args, **kwargs); 76 | return ObjectWrapper(std::move(ret)); 77 | } 78 | 79 | /** 80 | * @brief A wrapper class for matplotlib.collections.QuadMesh 81 | **/ 82 | struct DECL_STRUCT_ATTR QuadMesh : public BaseWrapper { 83 | public: 84 | QuadMesh(const pybind11::object &quadmesh) { self = quadmesh; } 85 | QuadMesh(pybind11::object &&quadmesh) { self = std::move(quadmesh); } 86 | }; 87 | 88 | } // namespace matplotlibcpp17::collections 89 | -------------------------------------------------------------------------------- /include/matplotlibcpp17/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #define LOAD_FUNC_ATTR(obj, mod) \ 5 | do { \ 6 | obj##_attr = mod.attr(#obj); \ 7 | } while (0) 8 | 9 | #define DECL_STRUCT_ATTR __attribute__((visibility("hidden"))) 10 | 11 | #include 12 | #include 13 | 14 | #define INFO_MSG(msg) \ 15 | do { \ 16 | std::cout << "Info [" __FILE__ << "@" << __LINE__ << "]: "; \ 17 | std::cout << #msg << std::endl; \ 18 | } while (0) 19 | 20 | #define WARN_MSG(msg) \ 21 | do { \ 22 | std::cout << "Warn [" __FILE__ << "@" << __LINE__ << "]: "; \ 23 | std::cout << #msg << std::endl; \ 24 | } while (0) 25 | 26 | #define ERROR_MSG(msg) \ 27 | do { \ 28 | std::cerr << "Error [" __FILE__ << "@" << __LINE__ << "]: "; \ 29 | std::cerr << #msg << std::endl; \ 30 | } while (0) 31 | 32 | #include 33 | 34 | namespace matplotlibcpp17 { 35 | 36 | /** 37 | * @brief A base class for python wrapper classes 38 | **/ 39 | struct DECL_STRUCT_ATTR BaseWrapper { 40 | public: 41 | pybind11::object unwrap() const { return self; } 42 | 43 | protected: 44 | pybind11::object self; 45 | }; 46 | 47 | /** 48 | * @brief A proxy class for pybind object 49 | **/ 50 | struct ObjectWrapper : public BaseWrapper { 51 | public: 52 | ObjectWrapper(const pybind11::object &object) { self = object; } 53 | ObjectWrapper(pybind11::object &&object) { self = std::move(object); } 54 | }; 55 | 56 | } // namespace matplotlibcpp17 57 | -------------------------------------------------------------------------------- /include/matplotlibcpp17/container.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file container.h 3 | * @brief corresponding header for matplotlib.axes 4 | **/ 5 | #pragma once 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace matplotlibcpp17::container { 12 | 13 | /** 14 | * @brief A wrapper class for matplotlib.container.BarContainer 15 | **/ 16 | struct DECL_STRUCT_ATTR BarContainer : public BaseWrapper { 17 | public: 18 | BarContainer(const pybind11::object &bar_container) { self = bar_container; } 19 | BarContainer(pybind11::object &&bar_container) { 20 | self = std::move(bar_container); 21 | } 22 | }; 23 | 24 | } // namespace matplotlibcpp17::container 25 | -------------------------------------------------------------------------------- /include/matplotlibcpp17/figure.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file figure.h 3 | * @brief corresponding header for matplotlib.figure 4 | **/ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | namespace matplotlibcpp17::figure { 14 | 15 | /** 16 | * @brief A wrapper class for matplotlib.figure.Figure 17 | **/ 18 | struct DECL_STRUCT_ATTR Figure : public BaseWrapper { 19 | public: 20 | Figure(const pybind11::object &figure) { 21 | self = figure; 22 | load_attrs(); 23 | } 24 | Figure(pybind11::object &&figure) { 25 | self = std::move(figure); 26 | load_attrs(); 27 | } 28 | // add_axes 29 | axes::Axes add_axes(const pybind11::tuple &args = pybind11::tuple(), 30 | const pybind11::dict &kwargs = pybind11::dict()); 31 | 32 | // add_gridspec 33 | gridspec::GridSpec 34 | add_gridspec(int nrow, int ncol, 35 | const pybind11::dict &kwargs = pybind11::dict()); 36 | 37 | // add_subplot 38 | axes::Axes add_subplot(const pybind11::tuple &args = pybind11::tuple(), 39 | const pybind11::dict &kwargs = pybind11::dict()); 40 | 41 | // align_labels 42 | ObjectWrapper align_labels(const pybind11::tuple &args = pybind11::tuple(), 43 | const pybind11::dict &kwargs = pybind11::dict()); 44 | 45 | // colorbar 46 | ObjectWrapper colorbar(const pybind11::tuple &args = pybind11::tuple(), 47 | const pybind11::dict &kwargs = pybind11::dict()); 48 | 49 | // savefig 50 | ObjectWrapper savefig(const pybind11::tuple &args = pybind11::tuple(), 51 | const pybind11::dict &kwargs = pybind11::dict()); 52 | 53 | // suptitle 54 | ObjectWrapper suptitle(const pybind11::tuple &args = pybind11::tuple(), 55 | const pybind11::dict &kwargs = pybind11::dict()); 56 | 57 | // tight_layout 58 | ObjectWrapper tight_layout(const pybind11::tuple &args = pybind11::tuple(), 59 | const pybind11::dict &kwargs = pybind11::dict()); 60 | 61 | private: 62 | void load_attrs() { 63 | LOAD_FUNC_ATTR(add_axes, self); 64 | LOAD_FUNC_ATTR(add_gridspec, self); 65 | LOAD_FUNC_ATTR(add_subplot, self); 66 | LOAD_FUNC_ATTR(align_labels, self); 67 | LOAD_FUNC_ATTR(colorbar, self); 68 | LOAD_FUNC_ATTR(savefig, self); 69 | LOAD_FUNC_ATTR(suptitle, self); 70 | LOAD_FUNC_ATTR(tight_layout, self); 71 | } 72 | pybind11::object add_axes_attr; 73 | pybind11::object add_gridspec_attr; 74 | pybind11::object add_subplot_attr; 75 | pybind11::object align_labels_attr; 76 | pybind11::object colorbar_attr; 77 | pybind11::object savefig_attr; 78 | pybind11::object suptitle_attr; 79 | pybind11::object tight_layout_attr; 80 | }; 81 | 82 | // add_axes 83 | inline axes::Axes Figure::add_axes(const pybind11::tuple &args, 84 | const pybind11::dict &kwargs) { 85 | pybind11::object obj = add_axes_attr(*args, **kwargs); 86 | return axes::Axes(obj); 87 | } 88 | 89 | // add_gridspec 90 | inline gridspec::GridSpec Figure::add_gridspec(int nrow, int ncol, 91 | const pybind11::dict &kwargs) { 92 | return gridspec::GridSpec(nrow, ncol, kwargs); 93 | } 94 | 95 | // add_subplot 96 | inline axes::Axes Figure::add_subplot(const pybind11::tuple &args, 97 | const pybind11::dict &kwargs) { 98 | pybind11::object obj = add_subplot_attr(*args, **kwargs); 99 | return axes::Axes(obj); 100 | } 101 | 102 | // align_labels 103 | inline ObjectWrapper Figure::align_labels(const pybind11::tuple &args, 104 | const pybind11::dict &kwargs) { 105 | pybind11::object ret = align_labels_attr(*args, **kwargs); 106 | return ObjectWrapper(std::move(ret)); 107 | } 108 | 109 | // colorbar 110 | inline ObjectWrapper Figure::colorbar(const pybind11::tuple &args, 111 | const pybind11::dict &kwargs) { 112 | pybind11::object ret = colorbar_attr(*args, **kwargs); 113 | return ObjectWrapper(std::move(ret)); 114 | } 115 | 116 | // savefig 117 | inline ObjectWrapper Figure::savefig(const pybind11::tuple &args, 118 | const pybind11::dict &kwargs) { 119 | pybind11::object ret = savefig_attr(*args, **kwargs); 120 | return ObjectWrapper(std::move(ret)); 121 | } 122 | 123 | // suptitle 124 | inline ObjectWrapper Figure::suptitle(const pybind11::tuple &args, 125 | const pybind11::dict &kwargs) { 126 | pybind11::object ret = suptitle_attr(*args, **kwargs); 127 | return ObjectWrapper(std::move(ret)); 128 | } 129 | 130 | // tight_layout 131 | inline ObjectWrapper Figure::tight_layout(const pybind11::tuple &args, 132 | const pybind11::dict &kwargs) { 133 | pybind11::object ret = tight_layout_attr(*args, **kwargs); 134 | return ObjectWrapper(std::move(ret)); 135 | } 136 | 137 | } // namespace matplotlibcpp17::figure 138 | -------------------------------------------------------------------------------- /include/matplotlibcpp17/gridspec.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file gridspec.h 3 | * @brief corresponding header for matplotlib.axes 4 | **/ 5 | #pragma once 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace matplotlibcpp17::gridspec { 12 | 13 | /** 14 | * @brief A wrapper class for matplotlib.gridspec.SubplotSpec 15 | **/ 16 | struct DECL_STRUCT_ATTR SubplotSpec : public BaseWrapper { 17 | public: 18 | SubplotSpec(const pybind11::object &subplotspec) { self = subplotspec; } 19 | SubplotSpec(pybind11::object &&subplotspec) { self = std::move(subplotspec); } 20 | }; 21 | 22 | /** 23 | * @brief A wrapper class for matplotlib.gridspec.GridSpec 24 | **/ 25 | struct DECL_STRUCT_ATTR GridSpec : public BaseWrapper { 26 | public: 27 | GridSpec(int nrow_, int ncol_, 28 | const pybind11::dict &kwargs = pybind11::dict()) { 29 | nrow = nrow_; 30 | ncol = ncol_; 31 | gridspec_attr = 32 | pybind11::module::import("matplotlib.gridspec").attr("GridSpec"); 33 | self = gridspec_attr(nrow, ncol, **kwargs); 34 | } 35 | template 36 | SubplotSpec operator()(const Rows &r, const Cols &c) { 37 | pybind11::object obj = self[pybind11::make_tuple(r, c)]; 38 | return SubplotSpec(std::move(obj)); 39 | } 40 | 41 | private: 42 | int nrow, ncol; 43 | pybind11::object gridspec_attr; 44 | }; 45 | 46 | } // namespace matplotlibcpp17::gridspec 47 | -------------------------------------------------------------------------------- /include/matplotlibcpp17/legend.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file legend.h 3 | * @brief corresponding header for matplotlib.legend 4 | **/ 5 | #pragma once 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace matplotlibcpp17::legend { 12 | 13 | /** 14 | * @brief A wrapper class for matplotlib.legend.Legend 15 | **/ 16 | struct DECL_STRUCT_ATTR Legend : public BaseWrapper { 17 | public: 18 | Legend(const pybind11::object &obj) { self = obj; } 19 | Legend(pybind11::object &&obj) { self = std::move(obj); } 20 | }; 21 | 22 | } // namespace matplotlibcpp17::legend 23 | -------------------------------------------------------------------------------- /include/matplotlibcpp17/mplot3d.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mplot3d.h 3 | * @brief header file for mplot3d 4 | **/ 5 | #pragma once 6 | 7 | #include 8 | 9 | namespace matplotlibcpp17::mplot3d { 10 | 11 | pybind11::object import() { 12 | return pybind11::module::import("mpl_toolkits.mplot3d").attr("Axes3D"); 13 | } 14 | 15 | } // namespace matplotlibcpp17::mplot3d -------------------------------------------------------------------------------- /include/matplotlibcpp17/patches.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file pathces.h 3 | * @brief corresponding header for matplotlib.patches 4 | **/ 5 | #pragma once 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace matplotlibcpp17::patches { 12 | 13 | /** 14 | * @brief A wrapper class for matplotlib.patches.Circle 15 | **/ 16 | struct DECL_STRUCT_ATTR Circle : public BaseWrapper { 17 | public: 18 | Circle(const pybind11::tuple &args = pybind11::tuple(), 19 | const pybind11::dict &kwargs = pybind11::dict()) { 20 | circle_attr = pybind11::module::import("matplotlib.patches").attr("Circle"); 21 | self = circle_attr(*args, **kwargs); 22 | } 23 | 24 | private: 25 | pybind11::object circle_attr; 26 | }; 27 | 28 | /** 29 | * @brief A wrapper class for matplotlib.patches.Ellipse 30 | **/ 31 | struct DECL_STRUCT_ATTR Ellipse : public BaseWrapper { 32 | public: 33 | Ellipse(const pybind11::tuple &args = pybind11::tuple(), 34 | const pybind11::dict &kwargs = pybind11::dict()) { 35 | ellipse_attr = 36 | pybind11::module::import("matplotlib.patches").attr("Ellipse"); 37 | self = ellipse_attr(*args, **kwargs); 38 | } 39 | 40 | private: 41 | pybind11::object ellipse_attr; 42 | }; 43 | 44 | /** 45 | * @brief A wrapper class for matplotlib.patches.Rectangle 46 | **/ 47 | struct DECL_STRUCT_ATTR Rectangle : public BaseWrapper { 48 | public: 49 | Rectangle(const pybind11::tuple &args = pybind11::tuple(), 50 | const pybind11::dict &kwargs = pybind11::dict()) { 51 | rectangle_attr = 52 | pybind11::module::import("matplotlib.patches").attr("Rectangle"); 53 | self = rectangle_attr(*args, **kwargs); 54 | } 55 | 56 | private: 57 | pybind11::object rectangle_attr; 58 | }; 59 | 60 | /** 61 | * @brief A wrapper class for matplotlib.patches.Wedge 62 | **/ 63 | struct DECL_STRUCT_ATTR Wedge : public BaseWrapper { 64 | public: 65 | Wedge(const pybind11::tuple &args = pybind11::tuple(), 66 | const pybind11::dict &kwargs = pybind11::dict()) { 67 | wedge_attr = pybind11::module::import("matplotlib.patches").attr("Wedge"); 68 | self = wedge_attr(*args, **kwargs); 69 | } 70 | 71 | private: 72 | pybind11::object wedge_attr; 73 | }; 74 | 75 | /** 76 | * @brief A wrapper class for matplotlib.patches.Polygon 77 | **/ 78 | struct DECL_STRUCT_ATTR Polygon : public BaseWrapper { 79 | public: 80 | Polygon(const pybind11::tuple &args = pybind11::tuple(), 81 | const pybind11::dict &kwargs = pybind11::dict()) { 82 | polygon_attr = 83 | pybind11::module::import("matplotlib.patches").attr("Polygon"); 84 | self = polygon_attr(*args, **kwargs); 85 | } 86 | 87 | private: 88 | pybind11::object polygon_attr; 89 | }; 90 | 91 | } // namespace matplotlibcpp17::patches 92 | -------------------------------------------------------------------------------- /include/matplotlibcpp17/pyplot.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file pyplot.h 3 | * @brief corresponding header for matplotlib.pyplot 4 | **/ 5 | #pragma once 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace matplotlibcpp17::pyplot { 19 | 20 | /** 21 | * @brief A class corresponding to pyplot module 22 | **/ 23 | struct DECL_STRUCT_ATTR PyPlot { 24 | public: 25 | PyPlot() {} 26 | PyPlot(pybind11::module mod_) { 27 | mod = mod_; 28 | load_attrs(); 29 | } 30 | // axes 31 | axes::Axes axes(const pybind11::dict &kwargs = pybind11::dict()); 32 | 33 | // axis 34 | ObjectWrapper axis(const pybind11::tuple &args = pybind11::tuple(), 35 | const pybind11::dict &kwargs = pybind11::dict()); 36 | 37 | // cla 38 | ObjectWrapper cla(const pybind11::tuple &args = pybind11::tuple(), 39 | const pybind11::dict &kwargs = pybind11::dict()); 40 | 41 | // clf 42 | ObjectWrapper clf(const pybind11::tuple &args = pybind11::tuple(), 43 | const pybind11::dict &kwargs = pybind11::dict()); 44 | 45 | // clim 46 | ObjectWrapper clim(const pybind11::tuple &args = pybind11::tuple(), 47 | const pybind11::dict &kwargs = pybind11::dict()); 48 | 49 | // colorbar 50 | ObjectWrapper colorbar(const pybind11::tuple &args = pybind11::tuple(), 51 | const pybind11::dict &kwargs = pybind11::dict()); 52 | 53 | // errorbar 54 | ObjectWrapper errorbar(const pybind11::tuple &args = pybind11::tuple(), 55 | const pybind11::dict &kwargs = pybind11::dict()); 56 | 57 | // figaspect 58 | std::tuple 59 | figaspect(const pybind11::tuple &args = pybind11::tuple(), 60 | const pybind11::dict &kwargs = pybind11::dict()); 61 | 62 | // figure 63 | figure::Figure figure(const pybind11::tuple &args = pybind11::tuple(), 64 | const pybind11::dict &kwargs = pybind11::dict()); 65 | 66 | // gca 67 | axes::Axes gca(const pybind11::tuple &args = pybind11::tuple(), 68 | const pybind11::dict &kwargs = pybind11::dict()); 69 | 70 | // gcf 71 | figure::Figure gcf(const pybind11::tuple &args = pybind11::tuple(), 72 | const pybind11::dict &kwargs = pybind11::dict()); 73 | 74 | // gci 75 | ObjectWrapper gci(const pybind11::tuple &args = pybind11::tuple(), 76 | const pybind11::dict &kwargs = pybind11::dict()); 77 | 78 | // grid 79 | ObjectWrapper grid(const pybind11::tuple &args = pybind11::tuple(), 80 | const pybind11::dict &kwargs = pybind11::dict()); 81 | 82 | // imshow 83 | ObjectWrapper imshow(const pybind11::tuple &args = pybind11::tuple(), 84 | const pybind11::dict &kwargs = pybind11::dict()); 85 | 86 | // legend 87 | ObjectWrapper legend(const pybind11::tuple &args = pybind11::tuple(), 88 | const pybind11::dict &kwargs = pybind11::dict()); 89 | 90 | // pause 91 | ObjectWrapper pause(const pybind11::tuple &args = pybind11::tuple(), 92 | const pybind11::dict &kwargs = pybind11::dict()); 93 | 94 | // plot 95 | ObjectWrapper plot(const pybind11::tuple &args = pybind11::tuple(), 96 | const pybind11::dict &kwargs = pybind11::dict()); 97 | 98 | // quiver 99 | ObjectWrapper quiver(const pybind11::tuple &args = pybind11::tuple(), 100 | const pybind11::dict &kwargs = pybind11::dict()); 101 | 102 | // savefig 103 | ObjectWrapper savefig(const pybind11::tuple &args = pybind11::tuple(), 104 | const pybind11::dict &kwargs = pybind11::dict()); 105 | 106 | // scatter 107 | ObjectWrapper scatter(const pybind11::tuple &args = pybind11::tuple(), 108 | const pybind11::dict &kwargs = pybind11::dict()); 109 | 110 | // show 111 | ObjectWrapper show(const pybind11::tuple &args = pybind11::tuple(), 112 | const pybind11::dict &kwargs = pybind11::dict()); 113 | 114 | // step 115 | ObjectWrapper step(const pybind11::tuple &args = pybind11::tuple(), 116 | const pybind11::dict &kwargs = pybind11::dict()); 117 | 118 | // subplot 119 | axes::Axes subplot(const pybind11::dict &kwargs = pybind11::dict()); 120 | axes::Axes subplot(int cri); 121 | 122 | // subplots 123 | std::tuple 124 | subplots(const pybind11::dict &kwargs = pybind11::dict()); 125 | std::tuple> 126 | subplots(int r, int c, const pybind11::dict &kwargs = pybind11::dict()); 127 | 128 | // title 129 | ObjectWrapper title(const pybind11::tuple &args = pybind11::tuple(), 130 | const pybind11::dict &kwargs = pybind11::dict()); 131 | 132 | // xlabel 133 | ObjectWrapper xlabel(const pybind11::tuple &args = pybind11::tuple(), 134 | const pybind11::dict &kwargs = pybind11::dict()); 135 | 136 | // xlim 137 | ObjectWrapper xlim(const pybind11::tuple &args = pybind11::tuple(), 138 | const pybind11::dict &kwargs = pybind11::dict()); 139 | 140 | // ylabel 141 | ObjectWrapper ylabel(const pybind11::tuple &args = pybind11::tuple(), 142 | const pybind11::dict &kwargs = pybind11::dict()); 143 | 144 | // ylim 145 | ObjectWrapper ylim(const pybind11::tuple &args = pybind11::tuple(), 146 | const pybind11::dict &kwargs = pybind11::dict()); 147 | 148 | private: 149 | void load_attrs() { 150 | LOAD_FUNC_ATTR(axes, mod); 151 | LOAD_FUNC_ATTR(axis, mod); 152 | LOAD_FUNC_ATTR(cla, mod); 153 | LOAD_FUNC_ATTR(clf, mod); 154 | LOAD_FUNC_ATTR(clim, mod); 155 | LOAD_FUNC_ATTR(colorbar, mod); 156 | LOAD_FUNC_ATTR(errorbar, mod); 157 | LOAD_FUNC_ATTR(figaspect, mod); 158 | LOAD_FUNC_ATTR(figure, mod); 159 | LOAD_FUNC_ATTR(gca, mod); 160 | LOAD_FUNC_ATTR(gcf, mod); 161 | LOAD_FUNC_ATTR(gci, mod); 162 | LOAD_FUNC_ATTR(grid, mod); 163 | LOAD_FUNC_ATTR(imshow, mod); 164 | LOAD_FUNC_ATTR(legend, mod); 165 | LOAD_FUNC_ATTR(pause, mod); 166 | LOAD_FUNC_ATTR(plot, mod); 167 | LOAD_FUNC_ATTR(quiver, mod); 168 | LOAD_FUNC_ATTR(savefig, mod); 169 | LOAD_FUNC_ATTR(scatter, mod); 170 | LOAD_FUNC_ATTR(show, mod); 171 | LOAD_FUNC_ATTR(step, mod); 172 | LOAD_FUNC_ATTR(subplot, mod); 173 | LOAD_FUNC_ATTR(subplots, mod); 174 | LOAD_FUNC_ATTR(title, mod); 175 | LOAD_FUNC_ATTR(xlabel, mod); 176 | LOAD_FUNC_ATTR(xlim, mod); 177 | LOAD_FUNC_ATTR(ylabel, mod); 178 | LOAD_FUNC_ATTR(ylim, mod); 179 | } 180 | pybind11::module mod; 181 | pybind11::object axes_attr; 182 | pybind11::object axis_attr; 183 | pybind11::object cla_attr; 184 | pybind11::object clf_attr; 185 | pybind11::object clim_attr; 186 | pybind11::object colorbar_attr; 187 | pybind11::object errorbar_attr; 188 | pybind11::object figaspect_attr; 189 | pybind11::object figure_attr; 190 | pybind11::object gca_attr; 191 | pybind11::object gcf_attr; 192 | pybind11::object gci_attr; 193 | pybind11::object grid_attr; 194 | pybind11::object imshow_attr; 195 | pybind11::object legend_attr; 196 | pybind11::object pause_attr; 197 | pybind11::object plot_attr; 198 | pybind11::object quiver_attr; 199 | pybind11::object savefig_attr; 200 | pybind11::object scatter_attr; 201 | pybind11::object show_attr; 202 | pybind11::object step_attr; 203 | pybind11::object subplot_attr; 204 | pybind11::object subplots_attr; 205 | pybind11::object title_attr; 206 | pybind11::object xlabel_attr; 207 | pybind11::object xlim_attr; 208 | pybind11::object ylabel_attr; 209 | pybind11::object ylim_attr; 210 | }; 211 | 212 | // axes 213 | inline axes::Axes PyPlot::axes(const pybind11::dict &kwargs) { 214 | pybind11::object ax_obj = axes_attr(**kwargs); 215 | return axes::Axes(ax_obj); 216 | } 217 | 218 | // axis 219 | inline ObjectWrapper PyPlot::axis(const pybind11::tuple &args, 220 | const pybind11::dict &kwargs) { 221 | pybind11::object ret = axis_attr(*args, **kwargs); 222 | return ObjectWrapper(std::move(ret)); 223 | } 224 | 225 | // cla 226 | inline ObjectWrapper PyPlot::cla(const pybind11::tuple &args, 227 | const pybind11::dict &kwargs) { 228 | pybind11::object ret = cla_attr(*args, **kwargs); 229 | return ObjectWrapper(std::move(ret)); 230 | } 231 | 232 | // clf 233 | inline ObjectWrapper PyPlot::clf(const pybind11::tuple &args, 234 | const pybind11::dict &kwargs) { 235 | pybind11::object ret = clf_attr(*args, **kwargs); 236 | return ObjectWrapper(std::move(ret)); 237 | } 238 | 239 | // clim 240 | inline ObjectWrapper PyPlot::clim(const pybind11::tuple &args, 241 | const pybind11::dict &kwargs) { 242 | pybind11::object ret = clim_attr(*args, **kwargs); 243 | return ObjectWrapper(std::move(ret)); 244 | } 245 | 246 | // colorbar 247 | inline ObjectWrapper PyPlot::colorbar(const pybind11::tuple &args, 248 | const pybind11::dict &kwargs) { 249 | pybind11::object ret = colorbar_attr(*args, **kwargs); 250 | return ObjectWrapper(std::move(ret)); 251 | } 252 | 253 | // errorbar 254 | inline ObjectWrapper PyPlot::errorbar(const pybind11::tuple &args, 255 | const pybind11::dict &kwargs) { 256 | pybind11::object ret = errorbar_attr(*args, **kwargs); 257 | return ObjectWrapper(std::move(ret)); 258 | } 259 | 260 | // figaspect 261 | inline std::tuple 262 | PyPlot::figaspect(const pybind11::tuple &args, const pybind11::dict &kwargs) { 263 | pybind11::list l = figaspect_attr(*args, **kwargs); 264 | double width = l[0].cast(); 265 | double height = l[1].cast(); 266 | return {width, height}; 267 | } 268 | 269 | // figure 270 | inline figure::Figure PyPlot::figure(const pybind11::tuple &args, 271 | const pybind11::dict &kwargs) { 272 | pybind11::object fig_obj = figure_attr(*args, **kwargs); 273 | return figure::Figure(fig_obj); 274 | } 275 | 276 | // gca 277 | inline axes::Axes PyPlot::gca(const pybind11::tuple &args, 278 | const pybind11::dict &kwargs) { 279 | pybind11::object obj = gca_attr(*args, **kwargs); 280 | return axes::Axes(obj); 281 | } 282 | 283 | // gcf 284 | inline figure::Figure PyPlot::gcf(const pybind11::tuple &args, 285 | const pybind11::dict &kwargs) { 286 | pybind11::object obj = gcf_attr(*args, **kwargs); 287 | return figure::Figure(obj); 288 | } 289 | 290 | // gci 291 | inline ObjectWrapper PyPlot::gci(const pybind11::tuple &args, 292 | const pybind11::dict &kwargs) { 293 | pybind11::object obj = gci_attr(*args, **kwargs); 294 | return obj; 295 | } 296 | 297 | // grid 298 | inline ObjectWrapper PyPlot::grid(const pybind11::tuple &args, 299 | const pybind11::dict &kwargs) { 300 | pybind11::object obj = grid_attr(*args, **kwargs); 301 | return obj; 302 | } 303 | 304 | // imshow 305 | inline ObjectWrapper PyPlot::imshow(const pybind11::tuple &args, 306 | const pybind11::dict &kwargs) { 307 | pybind11::object obj = imshow_attr(*args, **kwargs); 308 | return obj; 309 | } 310 | 311 | // legend 312 | inline ObjectWrapper PyPlot::legend(const pybind11::tuple &args, 313 | const pybind11::dict &kwargs) { 314 | pybind11::object ret = legend_attr(*args, **kwargs); 315 | return ObjectWrapper(std::move(ret)); 316 | } 317 | 318 | // pause 319 | inline ObjectWrapper PyPlot::pause(const pybind11::tuple &args, 320 | const pybind11::dict &kwargs) { 321 | pybind11::object ret = pause_attr(*args, **kwargs); 322 | return ObjectWrapper(std::move(ret)); 323 | } 324 | 325 | // plot 326 | inline ObjectWrapper PyPlot::plot(const pybind11::tuple &args, 327 | const pybind11::dict &kwargs) { 328 | pybind11::object ret = plot_attr(*args, **kwargs); 329 | return ObjectWrapper(std::move(ret)); 330 | } 331 | 332 | // quiver 333 | inline ObjectWrapper PyPlot::quiver(const pybind11::tuple &args, 334 | const pybind11::dict &kwargs) { 335 | pybind11::object ret = quiver_attr(*args, **kwargs); 336 | return ObjectWrapper(std::move(ret)); 337 | } 338 | 339 | // scatter 340 | inline ObjectWrapper PyPlot::scatter(const pybind11::tuple &args, 341 | const pybind11::dict &kwargs) { 342 | pybind11::object ret = scatter_attr(*args, **kwargs); 343 | return ObjectWrapper(std::move(ret)); 344 | } 345 | 346 | // savefig 347 | inline ObjectWrapper PyPlot::savefig(const pybind11::tuple &args, 348 | const pybind11::dict &kwargs) { 349 | pybind11::object ret = savefig_attr(*args, **kwargs); 350 | return ObjectWrapper(std::move(ret)); 351 | } 352 | 353 | // show 354 | inline ObjectWrapper PyPlot::show(const pybind11::tuple &args, 355 | const pybind11::dict &kwargs) { 356 | pybind11::object ret = show_attr(*args, **kwargs); 357 | return ObjectWrapper(std::move(ret)); 358 | } 359 | 360 | // step 361 | inline ObjectWrapper PyPlot::step(const pybind11::tuple &args, 362 | const pybind11::dict &kwargs) { 363 | pybind11::object ret = step_attr(*args, **kwargs); 364 | return ObjectWrapper(std::move(ret)); 365 | } 366 | 367 | // subplot 368 | inline axes::Axes PyPlot::subplot(const pybind11::dict &kwargs) { 369 | return axes::Axes(subplot_attr(**kwargs)); 370 | } 371 | 372 | inline axes::Axes PyPlot::subplot(int cri) { 373 | pybind11::object obj = subplot_attr(cri); 374 | return axes::Axes(obj); 375 | } 376 | 377 | // subplots 378 | inline std::tuple 379 | PyPlot::subplots(const pybind11::dict &kwargs) { 380 | pybind11::list ret = subplots_attr(**kwargs); 381 | pybind11::object fig = ret[0]; 382 | pybind11::object ax = ret[1]; 383 | return {figure::Figure(fig), axes::Axes(ax)}; 384 | } 385 | 386 | inline std::tuple> 387 | PyPlot::subplots(int r, int c, const pybind11::dict &kwargs) { 388 | // subplots() returns [][] (if r > 1 && c > 1) else [] 389 | // return []axes in row-major 390 | // NOTE: equal to Axes.flat 391 | pybind11::tuple args = pybind11::make_tuple(r, c); 392 | pybind11::list ret = subplots_attr(*args, **kwargs); 393 | std::vector axes; 394 | pybind11::object fig = ret[0]; 395 | figure::Figure figure(fig); 396 | if (r == 1 and c == 1) { 397 | // python returns Axes 398 | axes.push_back(axes::Axes(ret[1])); 399 | } else if (r == 1 or c == 1) { 400 | // python returns []Axes 401 | pybind11::list axs = ret[1]; 402 | for (int i = 0; i < r * c; ++i) 403 | axes.push_back(axes::Axes(axs[i])); 404 | } else { 405 | // python returns [][]Axes 406 | pybind11::list axs = ret[1]; 407 | for (pybind11::size_t i = 0; i < axs.size(); ++i) { 408 | pybind11::list axsi = axs[i]; 409 | for (unsigned j = 0; j < axsi.size(); ++j) 410 | axes.push_back(axes::Axes(axsi[j])); 411 | } 412 | } 413 | return {figure, axes}; 414 | } 415 | 416 | // title 417 | inline ObjectWrapper PyPlot::title(const pybind11::tuple &args, 418 | const pybind11::dict &kwargs) { 419 | pybind11::object ret = title_attr(*args, **kwargs); 420 | return ObjectWrapper(std::move(ret)); 421 | } 422 | 423 | // xlabel 424 | inline ObjectWrapper PyPlot::xlabel(const pybind11::tuple &args, 425 | const pybind11::dict &kwargs) { 426 | pybind11::object ret = xlabel_attr(*args, **kwargs); 427 | return ObjectWrapper(std::move(ret)); 428 | } 429 | 430 | // xlim 431 | inline ObjectWrapper PyPlot::xlim(const pybind11::tuple &args, 432 | const pybind11::dict &kwargs) { 433 | pybind11::object ret = xlim_attr(*args, **kwargs); 434 | return ObjectWrapper(std::move(ret)); 435 | } 436 | 437 | // ylabel 438 | inline ObjectWrapper PyPlot::ylabel(const pybind11::tuple &args, 439 | const pybind11::dict &kwargs) { 440 | pybind11::object ret = ylabel_attr(*args, **kwargs); 441 | return ObjectWrapper(std::move(ret)); 442 | } 443 | 444 | // ylim 445 | inline ObjectWrapper PyPlot::ylim(const pybind11::tuple &args, 446 | const pybind11::dict &kwargs) { 447 | pybind11::object ret = ylim_attr(*args, **kwargs); 448 | return ObjectWrapper(std::move(ret)); 449 | } 450 | 451 | inline PyPlot import() { 452 | auto mod = pybind11::module::import("matplotlib.pyplot"); 453 | auto g_pyplot = PyPlot(mod); 454 | return g_pyplot; 455 | } 456 | 457 | } // namespace matplotlibcpp17::pyplot 458 | 459 | // Args & Kwargs 460 | template pybind11::tuple Args(ArgsT &&...args) { 461 | return pybind11::make_tuple(std::forward(args)...); 462 | } 463 | 464 | using Kwargs = pybind11::dict; 465 | 466 | // Export this 467 | namespace py = pybind11; 468 | using namespace py::literals; 469 | -------------------------------------------------------------------------------- /include/matplotlibcpp17/quiver.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file quiver.h 3 | * @brief corresponding header for matplotlib.quiver 4 | **/ 5 | #pragma once 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace matplotlibcpp17::quiver { 12 | 13 | /** 14 | * @brief A wrapper class for matplotlib.quiver.Quiver 15 | **/ 16 | struct DECL_STRUCT_ATTR Quiver : public BaseWrapper { 17 | public: 18 | Quiver(const pybind11::object &q) { self = q; } 19 | Quiver(pybind11::object &&q) { self = std::move(q); } 20 | }; 21 | 22 | /** 23 | * @brief A wrapper class for matplotlib.quiver.QuiverKey 24 | **/ 25 | struct DECL_STRUCT_ATTR QuiverKey : public BaseWrapper { 26 | QuiverKey(const pybind11::object &qk) { self = qk; } 27 | QuiverKey(pybind11::object &&qk) { self = std::move(qk); } 28 | }; 29 | 30 | } // namespace matplotlibcpp17::quiver 31 | -------------------------------------------------------------------------------- /include/matplotlibcpp17/text.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file text.h 3 | * @brief corresponding header for matplotlib.text 4 | **/ 5 | #pragma once 6 | 7 | #include 8 | 9 | #include 10 | 11 | /** 12 | * @brief A wrapper class for matplotlib.text.Text 13 | **/ 14 | namespace matplotlibcpp17::text { 15 | 16 | struct DECL_STRUCT_ATTR Text : public BaseWrapper { 17 | public: 18 | Text(const pybind11::object &text) { 19 | self = text; 20 | load_attrs(); 21 | } 22 | Text(pybind11::object &&text) { 23 | self = std::move(text); 24 | load_attrs(); 25 | } 26 | 27 | ObjectWrapper set_rotation(const pybind11::tuple &args = pybind11::tuple(), 28 | const pybind11::dict &kwargs = pybind11::dict()); 29 | 30 | private: 31 | void load_attrs() { LOAD_FUNC_ATTR(set_rotation, self); } 32 | pybind11::object set_rotation_attr; 33 | }; 34 | 35 | inline ObjectWrapper Text::set_rotation(const pybind11::tuple &args, 36 | const pybind11::dict &kwargs) { 37 | pybind11::object ret = set_rotation_attr(*args, **kwargs); 38 | return ObjectWrapper(std::move(ret)); 39 | } 40 | 41 | } // namespace matplotlibcpp17::text 42 | -------------------------------------------------------------------------------- /include/matplotlibcpp17/ticker.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ticker.h 3 | * @brief corresponding header for matplotlib.ticker 4 | **/ 5 | #pragma once 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace matplotlibcpp17::ticker { 12 | 13 | struct DECL_STRUCT_ATTR LogLocator : public BaseWrapper { 14 | public: 15 | LogLocator() { 16 | pybind11::object attr = 17 | pybind11::module::import("matplotlib.ticker").attr("LogLocator"); 18 | self = attr(); 19 | } 20 | }; 21 | 22 | } // namespace matplotlibcpp17::ticker 23 | --------------------------------------------------------------------------------