From 53eb7b023a505f2f7dffca6618f44a44e7235c9d Mon Sep 17 00:00:00 2001 From: soblin Date: Thu, 3 Mar 2022 18:13:03 +0900 Subject: [PATCH 1/8] updated CMakeLists.txt --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 97ce1a8..9640953 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,6 +96,7 @@ install(EXPORT ${PROJECT_NAME}_Targets install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME} DESTINATION include ) +set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE") # uninstall target ## actually it's just `xargs rm < install_manifest.txt` From 80d6e78064ca1ae04e17bd5d9246fa84e445b9ab Mon Sep 17 00:00:00 2001 From: soblin Date: Thu, 3 Mar 2022 18:34:56 +0900 Subject: [PATCH 2/8] added package.cmake for creating .deb file --- CMakeLists.txt | 4 +++- cmake/package.cmake | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 cmake/package.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 9640953..b18530b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ endfunction() if(${ADD_DEMO}) find_package(Python3 COMPONENTS NumPy REQUIRED) - find_package(xtensor REQUIRED) + find_package(xtensor 0.24.0 REQUIRED) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_FLAGS "-Wall -g -DUSE_GUI=${USE_GUI}") add_subdirectory(gallery/lines_bars_and_markers) @@ -97,6 +97,8 @@ install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME} DESTINATION include ) set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE") +# create .deb +include("${PROJECT_SOURCE_DIR}/cmake/package.cmake") # uninstall target ## actually it's just `xargs rm < install_manifest.txt` diff --git a/cmake/package.cmake b/cmake/package.cmake new file mode 100644 index 0000000..62ec0da --- /dev/null +++ b/cmake/package.cmake @@ -0,0 +1,23 @@ +# https://decovar.dev/blog/2021/09/23/cmake-cpack-package-deb-apt/ +set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${CMAKE_PROJECT_DESCRIPTION}) +set(CPACK_VERBATIM_VARIABLES YES) +set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME}) +SET(CPACK_OUTPUT_FILE_PREFIX "${PROJECT_BINARY_DIR}/") +set(CPACK_PACKAGING_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}) +set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) +set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) +set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) +set(CPACK_PACKAGE_CONTACT "example@example.com") +set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Deb Example") +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") +set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md") +# package name for deb +set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) +set(CPACK_COMPONENTS_GROUPING ALL_COMPONENTS_IN_ONE) +# without this you won't be able to pack only specified component +set(CPACK_DEB_COMPONENT_INSTALL YES) + +include(CPack) + +# run cpack -G DEB to create .deb From 311bbe348e18822d4ecfa32642422e7e37a63f7b Mon Sep 17 00:00:00 2001 From: MamoruSobue Date: Fri, 4 Mar 2022 04:06:12 +0900 Subject: [PATCH 3/8] adding # if-else-endif for matplotlib minor version --- CMakeLists.txt | 28 +++++++++++++++++-- .../patch_collection.cpp | 1 + include/matplotlibcpp17/axes.h | 12 +++++++- include/matplotlibcpp17/common.h | 20 +++++++++++++ 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b18530b..471a120 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,29 @@ project( find_package(Python3 COMPONENTS Interpreter Development REQUIRED) find_package(pybind11 2.4.3 REQUIRED) -set(matplotlibcpp17_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include") + +# check matplotlib minor version +execute_process( + COMMAND + "python3" "-c" + "import matplotlib; +print(str(matplotlib.__version__))" + RESULT_VARIABLE MATPLOTLIB_VERSION_CHECKING + OUTPUT_VARIABLE MATPLOTLIB_VERSION + ) + +if(NOT MATPLOTLIB_VERSION_CHECKING MATCHES 0) + message(FATAL_ERROR + "Could not check matplotlib.__version__") +endif() +message("Detected matplotlib version is ${MATPLOTLIB_VERSION}") +if(${MATPLOTLIB_VERSION} VERSION_LESS 3.4) + message(WARNING "Detected matplotlib version is < 3.4.0") + set(MATPLOTLIB_MINOR_VER_GTE_4 0) +else() + set(MATPLOTLIB_MINOR_VER_GTE_4 1) +endif() + # gallery if(NOT DEFINED USE_GUI) @@ -20,6 +42,8 @@ if(NOT DEFINED ADD_DEMO) set(ADD_DEMO 1) endif() +set(matplotlibcpp17_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include") + function(add_demo name path) add_executable(${name} ${path}) target_include_directories(${name} PUBLIC @@ -33,7 +57,7 @@ if(${ADD_DEMO}) find_package(Python3 COMPONENTS NumPy REQUIRED) find_package(xtensor 0.24.0 REQUIRED) set(CMAKE_CXX_STANDARD 17) - set(CMAKE_CXX_FLAGS "-Wall -g -DUSE_GUI=${USE_GUI}") + set(CMAKE_CXX_FLAGS "-Wall -g -DUSE_GUI=${USE_GUI} -DMATPLOTLIB_MINOR_VER_GTE_4=${MATPLOTLIB_MINOR_VER_GTE_4}") add_subdirectory(gallery/lines_bars_and_markers) add_subdirectory(gallery/subplots_axes_and_figures) add_subdirectory(gallery/statistics) diff --git a/gallery/shapes_and_collections/patch_collection.cpp b/gallery/shapes_and_collections/patch_collection.cpp index 41e4554..3450c9e 100644 --- a/gallery/shapes_and_collections/patch_collection.cpp +++ b/gallery/shapes_and_collections/patch_collection.cpp @@ -60,6 +60,7 @@ int main() { py::list colors = py::cast(colors_); auto p = collections::PatchCollection(Args(patches), Kwargs("alpha"_a = 0.4)); p.set_array(Args(colors)); + // NOTE: error in python3.6.9 ? ax.add_collection(Args(p.unwrap())); fig.colorbar(Args(p.unwrap()), Kwargs("ax"_a = ax.unwrap())); #if USE_GUI diff --git a/include/matplotlibcpp17/axes.h b/include/matplotlibcpp17/axes.h index 5ea63cb..41ff7e8 100644 --- a/include/matplotlibcpp17/axes.h +++ b/include/matplotlibcpp17/axes.h @@ -206,7 +206,11 @@ struct DECL_STRUCT_ATTR Axes : public BaseWrapper { LOAD_FUNC_ATTR(add_patch, self); LOAD_FUNC_ATTR(axhline, self); LOAD_FUNC_ATTR(bar, self); +#if MATPLOTLIB_MINOR_VER_GTE_4 LOAD_FUNC_ATTR(bar_label, self); +#else + WARN_MSG("Not loading bar_label because matplotlib version is < 3.4.0"); +#endif LOAD_FUNC_ATTR(barh, self); LOAD_FUNC_ATTR(contour, self); LOAD_FUNC_ATTR(fill, self); @@ -227,7 +231,7 @@ struct DECL_STRUCT_ATTR Axes : public BaseWrapper { plot_surface_attr = self.attr("plot_surface"); plot_wireframe_attr = self.attr("plot_wireframe"); set_zlabel_attr = self.attr("set_zlabel"); - std::cout << "Loaded Axes3D." << std::endl; + INFO_MSG("Loaded Axes3D"); } catch(...) {} LOAD_FUNC_ATTR(quiver, self); @@ -325,8 +329,14 @@ container::BarContainer Axes::bar(const pybind11::tuple &args, // bar_label pybind11::object Axes::bar_label(const pybind11::tuple &args, const pybind11::dict &kwargs) { +#if MATPLOTLIB_MINOR_VER_GTE_4 pybind11::object ret = bar_label_attr(*args, **kwargs); return ret; +#else + ERROR_MSG( + "Call to bar_label is invalid because matplotlib version is < 3.4.0"); + std::exit(0); +#endif } // barh diff --git a/include/matplotlibcpp17/common.h b/include/matplotlibcpp17/common.h index 639030a..a1029f7 100644 --- a/include/matplotlibcpp17/common.h +++ b/include/matplotlibcpp17/common.h @@ -8,6 +8,26 @@ #define DECL_STRUCT_ATTR __attribute__((visibility("hidden"))) +#include + +#define INFO_MSG(msg) \ + do { \ + std::cout << "Info [" __FILE__ << "@" << __LINE__ << "]: "; \ + std::cout << #msg << std::endl; \ + } while (0) + +#define WARN_MSG(msg) \ + do { \ + std::cout << "Warn [" __FILE__ << "@" << __LINE__ << "]: "; \ + std::cout << #msg << std::endl; \ + } while (0) + +#define ERROR_MSG(msg) \ + do { \ + std::cerr << "Error [" __FILE__ << "@" << __LINE__ << "]: "; \ + std::cerr << #msg << std::endl; \ + } while (0) + #include namespace matplotlibcpp17 { From a3bdf3893b28f16c4c30b7e3dd9ffc2f9ce163b9 Mon Sep 17 00:00:00 2001 From: MamoruSobue Date: Tue, 8 Mar 2022 06:43:49 +0900 Subject: [PATCH 4/8] added lines_bars_and_markers/errorbar_limits_simple --- gallery/lines_bars_and_markers/CMakeLists.txt | 5 +- .../errorbar_limits_simple.cpp | 54 +++++++++++++++++++ include/matplotlibcpp17/pyplot.h | 13 +++++ 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 gallery/lines_bars_and_markers/errorbar_limits_simple.cpp diff --git a/gallery/lines_bars_and_markers/CMakeLists.txt b/gallery/lines_bars_and_markers/CMakeLists.txt index 6f02e56..a1fd23b 100644 --- a/gallery/lines_bars_and_markers/CMakeLists.txt +++ b/gallery/lines_bars_and_markers/CMakeLists.txt @@ -6,10 +6,10 @@ add_demo(fill_between_demo fill_between_demo.cpp) add_demo(fill_betweenx_demo fill_betweenx_demo.cpp) add_demo(scatter_with_legend scatter_with_legend.cpp) add_demo(scatter_hist scatter_hist.cpp) +add_demo(errorbar_limits_simple errorbar_limits_simple.cpp) -# TODO: macro for this! add_custom_target(lines_bars_and_markers - DEPENDS bar_label_demo fill simple_plot scatter_symbol fill_between_demo fill_betweenx_demo scatter_with_legend scatter_hist + DEPENDS bar_label_demo fill simple_plot scatter_symbol fill_between_demo fill_betweenx_demo scatter_with_legend scatter_hist errorbar_limits_simple COMMAND bar_label_demo COMMAND fill COMMAND simple_plot @@ -18,6 +18,7 @@ add_custom_target(lines_bars_and_markers COMMAND fill_betweenx_demo COMMAND scatter_with_legend COMMAND scatter_hist + COMMAND errorbar_limits_simple COMMENT "running lines_bars_and_markers" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../images" ) diff --git a/gallery/lines_bars_and_markers/errorbar_limits_simple.cpp b/gallery/lines_bars_and_markers/errorbar_limits_simple.cpp new file mode 100644 index 0000000..963135f --- /dev/null +++ b/gallery/lines_bars_and_markers/errorbar_limits_simple.cpp @@ -0,0 +1,54 @@ +// example +// https://matplotlib.org/stable/gallery/lines_bars_and_markers/errorbar_limits_simple.html + +#include +#include + +#include + +#include +#include + +#include + +namespace py = pybind11; +using namespace py::literals; +using namespace std; +using namespace matplotlibcpp17; + +int main() { + py::scoped_interpreter guard{}; + auto plt = pyplot::import(); + auto fig = plt.figure(); + auto x_ = xt::arange(0.0, 10.0, 1.0); + auto y_ = 2.5 * xt::sin(x_ / 20 * M_PI); + auto y1_ = y_ + 1.0, y2_ = y_ + 2.0, y3_ = y_ + 3.0; + auto yerr_ = xt::linspace(0.05, 0.2, 10); + vector x(x_.begin(), x_.end()), y(y_.begin(), y_.end()), + yerr(yerr_.begin(), yerr_.end()), y3(y3_.begin(), y3_.end()), + y2(y2_.begin(), y2_.end()), y1(y1_.begin(), y1_.end()); + plt.errorbar(Args(x, y3), + Kwargs("yerr"_a = yerr, "label"_a = "both limits (default)")); + plt.errorbar(Args(x, y2), Kwargs("yerr"_a = yerr, "uplims"_a = true, + "label"_a = "uplims=True")); + plt.errorbar(Args(x, y1), + Kwargs("yerr"_a = yerr, "uplims"_a = true, "lolims"_a = true, + "label"_a = "uplims=True, lolims=True")); + + vector upperlimits, lowerlimits; + for (auto i : {0, 1, 2, 3, 4}) { + upperlimits.push_back(true); + upperlimits.push_back(false); + lowerlimits.push_back(false); + lowerlimits.push_back(true); + } + plt.errorbar(Args(x, y), Kwargs("yerr"_a = yerr, "uplims"_a = upperlimits, + "lolims"_a = lowerlimits, + "label"_a = "subsets of uplims and lolims")); + plt.legend(Args(), Kwargs("loc"_a = "lower right")); +#if USE_GUI + plt.show(); +#else + plt.savefig(Args("errorbar_limits_simple.png")); +#endif +} diff --git a/include/matplotlibcpp17/pyplot.h b/include/matplotlibcpp17/pyplot.h index d188626..7e2f43c 100644 --- a/include/matplotlibcpp17/pyplot.h +++ b/include/matplotlibcpp17/pyplot.h @@ -41,6 +41,10 @@ struct DECL_STRUCT_ATTR PyPlot { pybind11::object clf(const pybind11::tuple &args = pybind11::tuple(), const pybind11::dict &kwargs = pybind11::dict()); + // errorbar + pybind11::object errorbar(const pybind11::tuple &args = pybind11::tuple(), + const pybind11::dict &kwargs = pybind11::dict()); + // figaspect std::tuple figaspect(const pybind11::tuple &args = pybind11::tuple(), @@ -118,6 +122,7 @@ struct DECL_STRUCT_ATTR PyPlot { LOAD_FUNC_ATTR(axis, mod); LOAD_FUNC_ATTR(cla, mod); LOAD_FUNC_ATTR(clf, mod); + LOAD_FUNC_ATTR(errorbar, mod); LOAD_FUNC_ATTR(figaspect, mod); LOAD_FUNC_ATTR(figure, mod); LOAD_FUNC_ATTR(gca, mod); @@ -141,6 +146,7 @@ struct DECL_STRUCT_ATTR PyPlot { pybind11::object axis_attr; pybind11::object cla_attr; pybind11::object clf_attr; + pybind11::object errorbar_attr; pybind11::object figaspect_attr; pybind11::object figure_attr; pybind11::object gca_attr; @@ -187,6 +193,13 @@ pybind11::object PyPlot::clf(const pybind11::tuple &args, return ret; } +// errorbar +pybind11::object PyPlot::errorbar(const pybind11::tuple &args, + const pybind11::dict &kwargs) { + pybind11::object ret = errorbar_attr(*args, **kwargs); + return ret; +} + // figaspect std::tuple PyPlot::figaspect(const pybind11::tuple &args, const pybind11::dict &kwargs) { From 042bea71037f5b55d3738d5a6a1ae9d235da54f3 Mon Sep 17 00:00:00 2001 From: MamoruSobue Date: Tue, 8 Mar 2022 07:15:37 +0900 Subject: [PATCH 5/8] added lines_bars_and_markers/errorbar_subsample --- gallery/lines_bars_and_markers/CMakeLists.txt | 4 +- .../errorbar_subsample.cpp | 54 +++++++++++++++++++ include/matplotlibcpp17/axes.h | 13 +++++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 gallery/lines_bars_and_markers/errorbar_subsample.cpp diff --git a/gallery/lines_bars_and_markers/CMakeLists.txt b/gallery/lines_bars_and_markers/CMakeLists.txt index a1fd23b..c936eb7 100644 --- a/gallery/lines_bars_and_markers/CMakeLists.txt +++ b/gallery/lines_bars_and_markers/CMakeLists.txt @@ -7,9 +7,10 @@ add_demo(fill_betweenx_demo fill_betweenx_demo.cpp) add_demo(scatter_with_legend scatter_with_legend.cpp) add_demo(scatter_hist scatter_hist.cpp) add_demo(errorbar_limits_simple errorbar_limits_simple.cpp) +add_demo(errorbar_subsample errorbar_subsample.cpp) add_custom_target(lines_bars_and_markers - DEPENDS bar_label_demo fill simple_plot scatter_symbol fill_between_demo fill_betweenx_demo scatter_with_legend scatter_hist errorbar_limits_simple + DEPENDS bar_label_demo fill simple_plot scatter_symbol fill_between_demo fill_betweenx_demo scatter_with_legend scatter_hist errorbar_limits_simple errorbar_subsample COMMAND bar_label_demo COMMAND fill COMMAND simple_plot @@ -19,6 +20,7 @@ add_custom_target(lines_bars_and_markers COMMAND scatter_with_legend COMMAND scatter_hist COMMAND errorbar_limits_simple + COMMAND errorbar_subsample COMMENT "running lines_bars_and_markers" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../images" ) diff --git a/gallery/lines_bars_and_markers/errorbar_subsample.cpp b/gallery/lines_bars_and_markers/errorbar_subsample.cpp new file mode 100644 index 0000000..4b54b1f --- /dev/null +++ b/gallery/lines_bars_and_markers/errorbar_subsample.cpp @@ -0,0 +1,54 @@ +// example from +// https://matplotlib.org/stable/gallery/lines_bars_and_markers/errorbar_subsample.html + +#include +#include + +#include + +#include +#include + +#include + +namespace py = pybind11; +using namespace py::literals; +using namespace std; +using namespace matplotlibcpp17; + +int main() { + auto x_ = xt::arange(0.1, 4.0, 0.1); + auto y1_ = xt::exp(-1.0 * x_); + auto y2_ = xt::exp(-0.5 * x_); + auto y1err_ = 0.1 + 0.1 * xt::sqrt(x_); + auto y2err_ = 0.1 + 0.1 * xt::sqrt(x_ / 2.0); + vector x(x_.begin(), x_.end()), y1(y1_.begin(), y1_.end()), + y2(y2_.begin(), y2_.end()), y1err(y1err_.begin(), y1err_.end()), + y2err(y2err_.begin(), y2err_.end()); + + py::scoped_interpreter guard{}; + auto plt = pyplot::import(); + auto [fig, axs] = plt.subplots( + 1, 3, Kwargs("sharex"_a = true, "figsize"_a = py::make_tuple(12, 6))); + auto ax0 = axs[0], ax1 = axs[1], ax2 = axs[2]; + ax0.set_title(Args("all errorbars")); + ax0.errorbar(Args(x, y1), Kwargs("yerr"_a = y1err)); + ax0.errorbar(Args(x, y1), Kwargs("yerr"_a = y2err)); + + ax1.set_title(Args("only every 6th errorbar")); + ax1.errorbar(Args(x, y1), Kwargs("yerr"_a = y1err, "errorevery"_a = 6)); + ax1.errorbar(Args(x, y2), Kwargs("yerr"_a = y2err, "errorevery"_a = 6)); + + ax2.set_title(Args("second seris shifted by 3")); + ax2.errorbar(Args(x, y1), + Kwargs("yerr"_a = y1err, "errorevery"_a = py::make_tuple(0, 6))); + ax2.errorbar(Args(x, y2), + Kwargs("yerr"_a = y2err, "errorevery"_a = py::make_tuple(3, 6))); + + fig.suptitle(Args("Errorbar subsampling")); +#if USE_GUI + plt.show(); +#else + plt.savefig(Args("erorbar_subsample.png")); +#endif +} diff --git a/include/matplotlibcpp17/axes.h b/include/matplotlibcpp17/axes.h index 41ff7e8..b4e424c 100644 --- a/include/matplotlibcpp17/axes.h +++ b/include/matplotlibcpp17/axes.h @@ -69,6 +69,10 @@ struct DECL_STRUCT_ATTR Axes : public BaseWrapper { pybind11::object contour(const pybind11::tuple &args = pybind11::tuple(), const pybind11::dict &kwargs = pybind11::dict()); + // errorbar + pybind11::object errorbar(const pybind11::tuple &args = pybind11::tuple(), + const pybind11::dict &kwargs = pybind11::dict()); + // fill pybind11::object fill(const pybind11::tuple &args = pybind11::tuple(), const pybind11::dict &kwargs = pybind11::dict()); @@ -213,6 +217,7 @@ struct DECL_STRUCT_ATTR Axes : public BaseWrapper { #endif LOAD_FUNC_ATTR(barh, self); LOAD_FUNC_ATTR(contour, self); + LOAD_FUNC_ATTR(errorbar, self); LOAD_FUNC_ATTR(fill, self); LOAD_FUNC_ATTR(fill_between, self); LOAD_FUNC_ATTR(fill_betweenx, self); @@ -258,6 +263,7 @@ struct DECL_STRUCT_ATTR Axes : public BaseWrapper { pybind11::object bar_label_attr; pybind11::object barh_attr; pybind11::object contour_attr; + pybind11::object errorbar_attr; pybind11::object fill_attr; pybind11::object fill_between_attr; pybind11::object fill_betweenx_attr; @@ -353,6 +359,13 @@ pybind11::object Axes::contour(const pybind11::tuple &args, return obj; } +// errorbar +pybind11::object Axes::errorbar(const pybind11::tuple &args, + const pybind11::dict &kwargs) { + pybind11::object obj = errorbar_attr(*args, **kwargs); + return obj; +} + // fill pybind11::object Axes::fill(const pybind11::tuple &args, const pybind11::dict &kwargs) { From a4ffc57e2bbadd2695451fb299ebd9cdff5e9e36 Mon Sep 17 00:00:00 2001 From: MamoruSobue Date: Tue, 8 Mar 2022 07:20:12 +0900 Subject: [PATCH 6/8] added statistics/errorbar --- gallery/statistics/CMakeLists.txt | 4 +++- gallery/statistics/errorbar.cpp | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 gallery/statistics/errorbar.cpp diff --git a/gallery/statistics/CMakeLists.txt b/gallery/statistics/CMakeLists.txt index 577ba1e..be84ebb 100644 --- a/gallery/statistics/CMakeLists.txt +++ b/gallery/statistics/CMakeLists.txt @@ -1,8 +1,10 @@ add_demo(hist hist.cpp) +add_demo(errorbar errorbar.cpp) add_custom_target(statitics - DEPENDS hist + DEPENDS hist errorbar COMMAND hist + COMMAND errorbar COMMENT "running hist" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../images" ) diff --git a/gallery/statistics/errorbar.cpp b/gallery/statistics/errorbar.cpp new file mode 100644 index 0000000..28f74f8 --- /dev/null +++ b/gallery/statistics/errorbar.cpp @@ -0,0 +1,31 @@ +// example from https://matplotlib.org/stable/gallery/statistics/errorbar.html + +#include +#include + +#include + +#include + +#include + +namespace py = pybind11; +using namespace py::literals; +using namespace std; +using namespace matplotlibcpp17; + +int main() { + py::scoped_interpreter guard{}; + auto plt = pyplot::import(); + auto x_ = xt::arange(0.1, 4.0, 0.5); + auto y_ = xt::exp(-x_); + vector x(x_.begin(), x_.end()), y(y_.begin(), y_.end()); + + auto [fig, ax] = plt.subplots(); + ax.errorbar(Args(x, y), Kwargs("xerr"_a = 0.2, "yerr"_a = 0.4)); +#if USE_GUI + plt.show(); +#else + plt.savefig(Args("erorrbar.png")); +#endif +} From b72adfa391ff1a389377d1677359c6eeb5e15106 Mon Sep 17 00:00:00 2001 From: MamoruSobue Date: Tue, 8 Mar 2022 07:58:03 +0900 Subject: [PATCH 7/8] added mplot3d/errorbar3d --- gallery/mplot3d/CMakeLists.txt | 4 ++- gallery/mplot3d/errorbar3d.cpp | 49 ++++++++++++++++++++++++++++++++++ include/matplotlibcpp17/axes.h | 15 ++++++++--- 3 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 gallery/mplot3d/errorbar3d.cpp diff --git a/gallery/mplot3d/CMakeLists.txt b/gallery/mplot3d/CMakeLists.txt index 4c48bc4..c2cc39f 100644 --- a/gallery/mplot3d/CMakeLists.txt +++ b/gallery/mplot3d/CMakeLists.txt @@ -2,13 +2,15 @@ add_demo(lines3d lines3d.cpp) add_demo(lorenz_attractor lorenz_attractor.cpp) add_demo(contour3d contour3d.cpp) add_demo(subplot3d subplot3d.cpp) +add_demo(errorbar3d errorbar3d.cpp) add_custom_target(mplot3d - DEPENDS lines3d lorenz_attractor contour3d subplot3d + DEPENDS lines3d lorenz_attractor contour3d subplot3d errorbar3d COMMAND lines3d COMMAND lorenz_attractor COMMAND contour3d COMMAND subplot3d + COMMAND errorbar3d COMMENT "running mplot3d" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../images" ) diff --git a/gallery/mplot3d/errorbar3d.cpp b/gallery/mplot3d/errorbar3d.cpp new file mode 100644 index 0000000..5efed41 --- /dev/null +++ b/gallery/mplot3d/errorbar3d.cpp @@ -0,0 +1,49 @@ +// example from https://matplotlib.org/stable/gallery/mplot3d/errorbar3d.html + +#include +#include + +#include + +#include +#include + +#include +#include + +namespace py = pybind11; +using namespace py::literals; +using namespace std; +using namespace matplotlibcpp17; + +int main() { + py::scoped_interpreter guard{}; + auto plt = pyplot::import(); + auto ax = plt.figure().add_subplot(Args(), Kwargs("projection"_a = "3d")); + auto t_ = xt::arange(0.0, 2 * M_PI + 0.1, 0.01); + auto x_ = xt::sin(1.0 * t_); + auto y_ = xt::cos(3.0 * t_); + auto z_ = xt::sin(5.0 * t_); + vector t(t_.begin(), t_.end()), x(x_.begin(), x_.end()), + y(y_.begin(), y_.end()), z(z_.begin(), z_.end()); + + const int estep = 15; + vector i, zuplims, zlolims; + std::iota(i.begin(), i.end(), 0); + std::transform(i.begin(), i.end(), std::back_inserter(zuplims), [](int i) { + return (i % 15 == 0) and ((i / estep) % 3 == 0); + }); + std::transform(i.begin(), i.end(), std::back_inserter(zlolims), [](int i) { + return (i % 15 == 0) and ((i / estep) % 3 == 2); + }); + + ax.errorbar(Args(x, y, z, 0.2), + Kwargs("zuplims"_a = zuplims, "zlolims"_a = zlolims, + "errorevery"_a = estep)); + + ax.set_xlabel(Args("X label")); + ax.set_ylabel(Args("Y label")); + ax.set_zlabel(Args("Z label")); + + plt.show(); +} diff --git a/include/matplotlibcpp17/axes.h b/include/matplotlibcpp17/axes.h index b4e424c..56dd024 100644 --- a/include/matplotlibcpp17/axes.h +++ b/include/matplotlibcpp17/axes.h @@ -237,8 +237,10 @@ struct DECL_STRUCT_ATTR Axes : public BaseWrapper { plot_wireframe_attr = self.attr("plot_wireframe"); set_zlabel_attr = self.attr("set_zlabel"); INFO_MSG("Loaded Axes3D"); + projection_3d = true; + } catch (...) { + projection_3d = false; } - catch(...) {} LOAD_FUNC_ATTR(quiver, self); LOAD_FUNC_ATTR(quiverkey, self); LOAD_FUNC_ATTR(scatter, self); @@ -295,6 +297,7 @@ struct DECL_STRUCT_ATTR Axes : public BaseWrapper { pybind11::object set_zlabel_attr; pybind11::object text_attr; pybind11::object tick_params_attr; + bool projection_3d; }; // add_artist @@ -362,8 +365,14 @@ pybind11::object Axes::contour(const pybind11::tuple &args, // errorbar pybind11::object Axes::errorbar(const pybind11::tuple &args, const pybind11::dict &kwargs) { - pybind11::object obj = errorbar_attr(*args, **kwargs); - return obj; + if (not projection_3d) { + pybind11::object obj = errorbar_attr(*args, **kwargs); + return obj; + } else { + ERROR_MSG("Call to errorbar with projection='3d' is invalid because " + "matplotlib version is < 3.4.0"); + std::exit(0); + } } // fill From 8cc51659c4d4d461c18a0ac48ac1eed56ef19723 Mon Sep 17 00:00:00 2001 From: soblin Date: Mon, 7 Mar 2022 23:18:44 +0900 Subject: [PATCH 8/8] fixed feature/error-bar on matplotlib==3.5.1 --- CMakeLists.txt | 2 +- gallery/mplot3d/errorbar3d.cpp | 4 ++-- include/matplotlibcpp17/axes.h | 9 +++++++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 471a120..7067417 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,7 @@ if(NOT MATPLOTLIB_VERSION_CHECKING MATCHES 0) message(FATAL_ERROR "Could not check matplotlib.__version__") endif() -message("Detected matplotlib version is ${MATPLOTLIB_VERSION}") +message(STATUS "Detected matplotlib version is ${MATPLOTLIB_VERSION}") if(${MATPLOTLIB_VERSION} VERSION_LESS 3.4) message(WARNING "Detected matplotlib version is < 3.4.0") set(MATPLOTLIB_MINOR_VER_GTE_4 0) diff --git a/gallery/mplot3d/errorbar3d.cpp b/gallery/mplot3d/errorbar3d.cpp index 5efed41..b5bf7c3 100644 --- a/gallery/mplot3d/errorbar3d.cpp +++ b/gallery/mplot3d/errorbar3d.cpp @@ -28,8 +28,8 @@ int main() { y(y_.begin(), y_.end()), z(z_.begin(), z_.end()); const int estep = 15; - vector i, zuplims, zlolims; - std::iota(i.begin(), i.end(), 0); + vector i(t_.shape()[0]), zuplims, zlolims; + std::iota(i.begin(), i.end(), t_.shape()[0]); std::transform(i.begin(), i.end(), std::back_inserter(zuplims), [](int i) { return (i % 15 == 0) and ((i / estep) % 3 == 0); }); diff --git a/include/matplotlibcpp17/axes.h b/include/matplotlibcpp17/axes.h index 56dd024..df89efe 100644 --- a/include/matplotlibcpp17/axes.h +++ b/include/matplotlibcpp17/axes.h @@ -365,13 +365,18 @@ pybind11::object Axes::contour(const pybind11::tuple &args, // errorbar pybind11::object Axes::errorbar(const pybind11::tuple &args, const pybind11::dict &kwargs) { - if (not projection_3d) { + if (projection_3d) { +#if MATPLOTLIB_MINOR_VER_GTE_4 pybind11::object obj = errorbar_attr(*args, **kwargs); return obj; - } else { +#else ERROR_MSG("Call to errorbar with projection='3d' is invalid because " "matplotlib version is < 3.4.0"); std::exit(0); +#endif + } else { + pybind11::object obj = errorbar_attr(*args, **kwargs); + return obj; } }