diff --git a/CMakeLists.txt b/CMakeLists.txt index 17d99f988dfc7ed3f96831e045751297c5f2d37a..a1334a69b7767f35d1e57f54ec37927f069ff5af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,10 +35,11 @@ endif() # gallery if(NOT DEFINED USE_GUI) set(USE_GUI 1) - message(STATUS "USE_GUI = ON") + message(STATUS "set USE_GUI = ON") endif() if(NOT DEFINED ADD_DEMO) set(ADD_DEMO 1) + message(STATUS "set ADD_DEMO = ON") endif() if(USE_GUI) message(STATUS "USE_GUI = ON") @@ -70,13 +71,14 @@ if(${ADD_DEMO}) 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/lines_bars_and_markers) add_subdirectory(gallery/subplots_axes_and_figures) - # add_subdirectory(gallery/statistics) - # add_subdirectory(gallery/images_contours_and_fields) - # add_subdirectory(gallery/shapes_and_collections) - # add_subdirectory(gallery/artist_animation) - # add_subdirectory(gallery/mplot3d) + add_subdirectory(gallery/statistics) + add_subdirectory(gallery/images_contours_and_fields) + add_subdirectory(gallery/shapes_and_collections) + add_subdirectory(gallery/artist_animation) + add_subdirectory(gallery/mplot3d) + add_subdirectory(gallery/scales) endif() # test diff --git a/gallery/images_contours_and_fields/CMakeLists.txt b/gallery/images_contours_and_fields/CMakeLists.txt index e3765f99ea3f9138c23e27d63859b8e8a1f231be..68c01bf694805a68734fb5638c81098b2f784270 100644 --- a/gallery/images_contours_and_fields/CMakeLists.txt +++ b/gallery/images_contours_and_fields/CMakeLists.txt @@ -1,8 +1,10 @@ add_demo(quiver_demo quiver_demo.cpp) +add_demo(contourf_log contourf_log) add_custom_target(images_contours_and_fields - DEPENDS quiver_demo + DEPENDS quiver_demo contourf_log COMMAND quiver_demo - COMMENT "running quiver_demo" + COMMAND contourf_log + COMMENT "running images_contours_and_fields" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../images" ) diff --git a/gallery/images_contours_and_fields/contourf_log.cpp b/gallery/images_contours_and_fields/contourf_log.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f90323a381b4c5cfe631a732dd06c086e082afcc --- /dev/null +++ b/gallery/images_contours_and_fields/contourf_log.cpp @@ -0,0 +1,58 @@ +// example from +// https://matplotlib.org/stable/gallery/images_contours_and_fields/contourf_log.html + +#include <matplotlibcpp17/pyplot.h> +#include <matplotlibcpp17/cm.h> +#include <matplotlibcpp17/ticker.h> + +#include <xtensor/xbuilder.hpp> +#include <xtensor/xview.hpp> +#include <xtensor/xmath.hpp> + +#include <vector> + +using namespace std; +using namespace matplotlibcpp17; +using namespace xt::placeholders; + +using mesh2D = vector<vector<double>>; + +int main() { + const int N = 100; + auto x_ = xt::linspace(-3.0, 3.0, N); + auto y_ = xt::linspace(-2.0, 2.0, N); + + auto [X_, Y_] = xt::meshgrid(x_, y_); + auto Z1_ = xt::exp(-xt::pow(X_, 2) - xt::pow(Y_, 2)); + auto Z2_ = xt::exp(-xt::pow(X_ * 10, 2) - xt::pow(Y_ * 10, 2)); + xt::xarray<double> z_ = Z1_ + 50 * Z2_; + // instead of x[:5, :5] = -1.0 + auto v = xt::view(z_, xt::range(_, 5), xt::range(_, 5)); + v = 0.0; + // to vector<vector>> + const int xsz = x_.shape()[0], ysz = y_.shape()[0]; + mesh2D X(xsz), Y(xsz), z(xsz); + for (int i = 0; i < xsz; ++i) { + X[i].resize(ysz); + Y[i].resize(ysz); + z[i].resize(ysz); + for (int j = 0; j < ysz; ++j) { + X[i][j] = X_(i, j); + Y[i][j] = Y_(i, j); + z[i][j] = z_(i, j); + } + } + + py::scoped_interpreter guard{}; + // to numpy array + auto Xpy = py::array(py::cast(std::move(X))); + auto Ypy = py::array(py::cast(std::move(Y))); + auto zpy = py::array(py::cast(std::move(z))); + auto plt = pyplot::import(); + auto [fig, ax] = plt.subplots(); + auto cs = ax.contourf(Args(Xpy, Ypy, zpy), + Kwargs("locator"_a = ticker::LogLocator().unwrap(), + "cmap"_a = cm::PuBu_r())); + fig.colorbar(Args(cs)); + plt.show(); +} diff --git a/gallery/scales/CMakeLists.txt b/gallery/scales/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..2bde8aa227050afff60c166f1037c42e2c3ab21d --- /dev/null +++ b/gallery/scales/CMakeLists.txt @@ -0,0 +1,8 @@ +add_demo(aspect_loglog aspect_loglog.cpp) + +add_custom_target(scales + DEPENDS aspect_loglog + COMMAND aspect_loglog + COMMENT "running scales" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../images" +) diff --git a/gallery/scales/aspect_loglog.cpp b/gallery/scales/aspect_loglog.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7ea04518f4bdbfe6b8f48bac755f266c92e980bc --- /dev/null +++ b/gallery/scales/aspect_loglog.cpp @@ -0,0 +1,33 @@ +// example from https://matplotlib.org/stable/gallery/scales/aspect_loglog.html + +#include <matplotlibcpp17/pyplot.h> +#include <matplotlibcpp17/animation.h> + +#include <vector> + +using namespace std; +using namespace matplotlibcpp17; + +int main() { + py::scoped_interpreter guard{}; + auto plt = pyplot::import(); + auto [fig, axs] = plt.subplots(1, 2); + auto &ax1 = axs[0], ax2 = axs[1]; + ax1.set_xscale(Args("log")); + ax1.set_yscale(Args("log")); + ax1.set_xlim(Args(1e+1, 1e+3)); + ax1.set_ylim(Args(1e+2, 1e+3)); + ax1.set_aspect(Args(1)); + ax1.set_title(Args("adjustable = box")); + + ax2.set_xscale(Args("log")); + ax2.set_yscale(Args("log")); + ax2.set_adjustable(Args("datalim")); + ax2.plot(Args(vector<int>({1, 3, 10}), vector<int>({1, 9, 100}), "o-")); + ax2.set_xlim(Args(1e-1, 1e+2)); + ax2.set_ylim(Args(1e-1, 1e+3)); + ax2.set_aspect(Args(1)); + ax2.set_title(Args("adjustable = datalim")); + + plt.show(); +} diff --git a/include/matplotlibcpp17/axes.h b/include/matplotlibcpp17/axes.h index cefecfd0f45a56cc6025f6704f67c041068196a4..0970c3b6a95a6dc6535b12430ce12fb6ca66bb01 100644 --- a/include/matplotlibcpp17/axes.h +++ b/include/matplotlibcpp17/axes.h @@ -69,6 +69,10 @@ public: pybind11::object contour(const pybind11::tuple &args = pybind11::tuple(), const pybind11::dict &kwargs = pybind11::dict()); + // contourf + pybind11::object contourf(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()); @@ -159,6 +163,11 @@ public: pybind11::object set(const pybind11::tuple &args = pybind11::tuple(), const pybind11::dict &kwargs = pybind11::dict()); + // set_adjustable + pybind11::object + set_adjustable(const pybind11::tuple &args = pybind11::tuple(), + const pybind11::dict &kwargs = pybind11::dict()); + // set_aspect pybind11::object set_aspect(const pybind11::tuple &args = pybind11::tuple(), const pybind11::dict &kwargs = pybind11::dict()); @@ -175,6 +184,10 @@ public: pybind11::object set_xlim(const pybind11::tuple &args = pybind11::tuple(), const pybind11::dict &kwargs = pybind11::dict()); + // set_xscale + pybind11::object set_xscale(const pybind11::tuple &args = pybind11::tuple(), + const pybind11::dict &kwargs = pybind11::dict()); + // set_xticks pybind11::object set_xticks(const pybind11::tuple &args = pybind11::tuple(), const pybind11::dict &kwargs = pybind11::dict()); @@ -192,6 +205,10 @@ public: pybind11::object set_ylim(const pybind11::tuple &args = pybind11::tuple(), const pybind11::dict &kwargs = pybind11::dict()); + // set_yscale + pybind11::object set_yscale(const pybind11::tuple &args = pybind11::tuple(), + const pybind11::dict &kwargs = pybind11::dict()); + // set_yticks pybind11::object set_yticks(const pybind11::tuple &args = pybind11::tuple(), const pybind11::dict &kwargs = pybind11::dict()); @@ -230,6 +247,7 @@ private: #endif LOAD_FUNC_ATTR(barh, self); LOAD_FUNC_ATTR(contour, self); + LOAD_FUNC_ATTR(contourf, self); LOAD_FUNC_ATTR(errorbar, self); LOAD_FUNC_ATTR(fill, self); LOAD_FUNC_ATTR(fill_between, self); @@ -260,14 +278,17 @@ private: LOAD_FUNC_ATTR(quiverkey, self); LOAD_FUNC_ATTR(scatter, self); LOAD_FUNC_ATTR(set, self); + LOAD_FUNC_ATTR(set_adjustable, self); LOAD_FUNC_ATTR(set_aspect, self); LOAD_FUNC_ATTR(set_title, self); LOAD_FUNC_ATTR(set_xlabel, self); LOAD_FUNC_ATTR(set_xlim, self); + LOAD_FUNC_ATTR(set_xscale, self); LOAD_FUNC_ATTR(set_xticks, self); LOAD_FUNC_ATTR(set_xticklabels, self); LOAD_FUNC_ATTR(set_ylabel, self); LOAD_FUNC_ATTR(set_ylim, self); + LOAD_FUNC_ATTR(set_yscale, self); LOAD_FUNC_ATTR(set_yticks, self); LOAD_FUNC_ATTR(text, self); LOAD_FUNC_ATTR(tick_params, self); @@ -281,6 +302,7 @@ private: pybind11::object bar_label_attr; pybind11::object barh_attr; pybind11::object contour_attr; + pybind11::object contourf_attr; pybind11::object errorbar_attr; pybind11::object fill_attr; pybind11::object fill_between_attr; @@ -302,14 +324,17 @@ private: pybind11::object quiverkey_attr; pybind11::object scatter_attr; pybind11::object set_attr; + pybind11::object set_adjustable_attr; pybind11::object set_aspect_attr; pybind11::object set_title_attr; pybind11::object set_xlabel_attr; pybind11::object set_xlim_attr; + pybind11::object set_xscale_attr; pybind11::object set_xticks_attr; pybind11::object set_xticklabels_attr; pybind11::object set_ylabel_attr; pybind11::object set_ylim_attr; + pybind11::object set_yscale_attr; pybind11::object set_yticks_attr; pybind11::object set_zlabel_attr; pybind11::object set_zlim_attr; @@ -381,6 +406,13 @@ pybind11::object Axes::contour(const pybind11::tuple &args, return obj; } +// contourf +pybind11::object Axes::contourf(const pybind11::tuple &args, + const pybind11::dict &kwargs) { + pybind11::object obj = contourf_attr(*args, **kwargs); + return obj; +} + // errorbar pybind11::object Axes::errorbar(const pybind11::tuple &args, const pybind11::dict &kwargs) { @@ -553,6 +585,13 @@ pybind11::object Axes::set(const pybind11::tuple &args, return ret; } +// set_adjustable +pybind11::object Axes::set_adjustable(const pybind11::tuple &args, + const pybind11::dict &kwargs) { + pybind11::object ret = set_adjustable_attr(*args, **kwargs); + return ret; +} + // set_aspect pybind11::object Axes::set_aspect(const pybind11::tuple &args, const pybind11::dict &kwargs) { @@ -581,6 +620,13 @@ pybind11::object Axes::set_xlim(const pybind11::tuple &args, return ret; } +// set_xscale +pybind11::object Axes::set_xscale(const pybind11::tuple &args, + const pybind11::dict &kwargs) { + pybind11::object ret = set_xscale_attr(*args, **kwargs); + return ret; +} + // set_xticks pybind11::object Axes::set_xticks(const pybind11::tuple &args, const pybind11::dict &kwargs) { @@ -609,6 +655,13 @@ pybind11::object Axes::set_ylim(const pybind11::tuple &args, return ret; } +// set_yscale +pybind11::object Axes::set_yscale(const pybind11::tuple &args, + const pybind11::dict &kwargs) { + pybind11::object ret = set_yscale_attr(*args, **kwargs); + return ret; +} + // set_yticks pybind11::object Axes::set_yticks(const pybind11::tuple &args, const pybind11::dict &kwargs) { diff --git a/include/matplotlibcpp17/cm.h b/include/matplotlibcpp17/cm.h index 02e6e61b5a9e6bd7752aa246d70546c893c44389..c436e5caa997d4bf7b34cd41999541560446381e 100644 --- a/include/matplotlibcpp17/cm.h +++ b/include/matplotlibcpp17/cm.h @@ -16,6 +16,12 @@ pybind11::object coolwarm() { return ret; } +pybind11::object PuBu_r() { + pybind11::object ret = + pybind11::module::import("matplotlib.cm").attr("PuBu_r"); + return ret; +} + } // namespace matplotlibcpp17::cm #endif /* MATPLOTLIBCPP17_CM_H */ diff --git a/include/matplotlibcpp17/ticker.h b/include/matplotlibcpp17/ticker.h new file mode 100644 index 0000000000000000000000000000000000000000..7051ccdfa71f909e7715cc0a488d9a05e3495996 --- /dev/null +++ b/include/matplotlibcpp17/ticker.h @@ -0,0 +1,26 @@ +/** + * @file ticker.h + * @brief corresponding header for matplotlib.ticker + **/ + +#ifndef MATPLOTLIBCPP17_TICKER_H +#define MATPLOTLIBCPP17_TICKER_H + +#include <pybind11/pybind11.h> + +#include <matplotlibcpp17/common.h> + +namespace matplotlibcpp17::ticker { + +struct DECL_STRUCT_ATTR LogLocator : public BaseWrapper { +public: + LogLocator() { + pybind11::object attr = + pybind11::module::import("matplotlib.ticker").attr("LogLocator"); + self = attr(); + } +}; + +} // namespace matplotlibcpp17::ticker + +#endif /* MATPLOTLIBCPP17_ANIMATION_H */