Skip to content

Commit b51db01

Browse files
committed
added image_demo demo
Signed-off-by: soblin <hilo.soblin@gmail.com>
1 parent d29f1fb commit b51db01

File tree

5 files changed

+98
-8
lines changed

5 files changed

+98
-8
lines changed

README.md

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ gives
6868

6969
![minimal example](./gallery/images/hello_world.png)
7070

71-
### example1 - subplots
71+
### subplots
7272

7373
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).
7474

@@ -91,7 +91,7 @@ From [gallery/subplots_axes_and_figures/align_labels_demo.cpp](https://github.co
9191

9292
![subplots_axes_and_figures](./gallery/images/align_labels_demo.png)
9393

94-
### example2 - bar plot
94+
### bar plot
9595

9696
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<Figure, Axes>`.
9797

@@ -120,7 +120,26 @@ From [gallery/lines_bars_and_markers/bar_label_demo.cpp](https://github.com/sobl
120120
121121
![bar_label_demo1](./gallery/images/bar_label_demo1.png)
122122
123-
### example3 - fill
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<vector<double>> 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
124143

125144
Fucntions like `subplots`, `TBD`s are overloaded because they return different types depending on the arguments. Here `subplots()` returns `tuple<Figure, vector<Axes>>`.
126145

@@ -138,7 +157,7 @@ From [gallery/lines_bars_and_markers](https://github.com/soblin/matplotlibcpp17/
138157
139158
![fill](./gallery/images/fill.png)
140159
141-
### example4 - quiver
160+
### quiver
142161
143162
Use `.unwrap()` method to pass wrapper class of matplotlibcpp17 to plotting functions.
144163
@@ -161,7 +180,7 @@ From [gallery/images_contours_and_fields/quiver_demo.cpp](https://github.com/sob
161180

162181
![quiver_demo3](./gallery/images/quiver_demo_3.png)
163182

164-
### example5 - gif
183+
### gif
165184

166185
Currently only `ArtistAnimation` is supported. `FuncAnimation` interface maybe implemented in the future.
167186

gallery/images/image_demo.png

37.8 KB
Loading
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
add_demo(quiver_demo quiver_demo.cpp)
22
add_demo(contourf_log contourf_log)
3+
add_demo(image_demo image_demo)
34

45
add_custom_target(
56
images_contours_and_fields
6-
DEPENDS quiver_demo contourf_log
7+
DEPENDS quiver_demo contourf_log image_demo
78
COMMAND quiver_demo
89
COMMAND contourf_log
10+
COMMAND image_demo
911
COMMENT "running images_contours_and_fields"
1012
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../images")
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// example from
2+
// https://matplotlib.org/stable/gallery/images_contours_and_fields/image_demo.html
3+
4+
#include <matplotlibcpp17/pyplot.h>
5+
6+
#include <xtensor/xbuilder.hpp>
7+
#include <xtensor/xview.hpp>
8+
9+
#include <vector>
10+
#include <string>
11+
#include <algorithm>
12+
13+
using namespace std;
14+
using namespace matplotlibcpp17;
15+
16+
using mesh2D = vector<vector<double>>;
17+
18+
int main() {
19+
const double delta = 0.025;
20+
const auto x = xt::arange<double>(-3.0, 3.0, delta);
21+
auto [X_, Y_] = xt::meshgrid(x, x);
22+
auto Z1_ = xt::exp(-xt::pow(X_, 2) - xt::pow(Y_, 2));
23+
auto Z2_ = xt::exp(-xt::pow(X_ - 1, 2) - xt::pow(Y_ - 1, 2));
24+
auto Z_ = (Z1_ - Z2_) * 2.0;
25+
26+
// to vector
27+
vector<double> X(X_.begin(), X_.end()), Y(Y_.begin(), Y_.end()),
28+
Z1(Z1_.begin(), Z1_.end()), Z2(Z2_.begin(), Z2_.end());
29+
// to vector<vector>
30+
const int xsz = x.shape()[0], ysz = x.shape()[0];
31+
mesh2D Z2D(xsz);
32+
for (int i = 0; i < xsz; ++i) {
33+
Z2D[i].resize(ysz);
34+
for (int j = 0; j < ysz; ++j) {
35+
Z2D[i][j] = Z_(i, j);
36+
}
37+
}
38+
39+
py::scoped_interpreter guard{};
40+
auto plt = matplotlibcpp17::pyplot::import();
41+
auto [fig, ax] = plt.subplots();
42+
const double vmax = *max_element(Z_.begin(), Z_.end()),
43+
vmin = *min_element(Z_.begin(), Z_.end());
44+
auto Zpy = py::array(py::cast(std::move(Z2D)));
45+
ax.imshow(Args(Zpy), Kwargs("interpolation"_a = "bilinear",
46+
"cmap"_a = "RdYlGn", "origin"_a = "lower",
47+
"extent"_a = py::make_tuple(-3, 3, -3, 3),
48+
"vmax"_a = vmax, "vmin"_a = vmin));
49+
#if USE_GUI
50+
plt.show();
51+
#else
52+
plt.savefig(Args("image_demo.png"));
53+
#endif
54+
return 0;
55+
}

include/matplotlibcpp17/axes.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ struct DECL_STRUCT_ATTR Axes : public BaseWrapper {
118118
pybind11::object hist2d(const pybind11::tuple &args = pybind11::tuple(),
119119
const pybind11::dict &kwargs = pybind11::dict());
120120

121+
// imshow
122+
pybind11::object imshow(const pybind11::tuple &args = pybind11::tuple(),
123+
const pybind11::dict &kwargs = pybind11::dict());
124+
121125
// invert_yaxis
122126
pybind11::object
123127
invert_yaxis(const pybind11::tuple &args = pybind11::tuple(),
@@ -260,10 +264,12 @@ struct DECL_STRUCT_ATTR Axes : public BaseWrapper {
260264
LOAD_FUNC_ATTR(hist, self);
261265
LOAD_FUNC_ATTR(hist2d, self);
262266
LOAD_FUNC_ATTR(invert_yaxis, self);
267+
LOAD_FUNC_ATTR(imshow, self);
263268
LOAD_FUNC_ATTR(legend, self);
264269
LOAD_FUNC_ATTR(pcolormesh, self);
265270
LOAD_FUNC_ATTR(plot, self);
266-
// NOTE: only when called with projection='3d', `plot_surface`, `plot_wireframe`, `set_zlabel` prop exists.
271+
// NOTE: only when called with projection='3d', `plot_surface`,
272+
// `plot_wireframe`, `set_zlabel` prop exists.
267273
try {
268274
LOAD_FUNC_ATTR(plot_surface, self);
269275
LOAD_FUNC_ATTR(plot_wireframe, self);
@@ -315,6 +321,7 @@ struct DECL_STRUCT_ATTR Axes : public BaseWrapper {
315321
pybind11::object hist_attr;
316322
pybind11::object hist2d_attr;
317323
pybind11::object invert_yaxis_attr;
324+
pybind11::object imshow_attr;
318325
pybind11::object legend_attr;
319326
pybind11::object pcolormesh_attr;
320327
pybind11::object plot_attr;
@@ -463,7 +470,7 @@ pybind11::object Axes::get_lines(const pybind11::tuple &args,
463470
pybind11::object Axes::get_xaxis_transform(const pybind11::tuple &args,
464471
const pybind11::dict &kwargs) {
465472
pybind11::object ret = get_xaxis_transform_attr(*args, **kwargs);
466-
return ret;
473+
return ret;
467474
}
468475

469476
// get_xlim
@@ -522,6 +529,13 @@ pybind11::object Axes::invert_yaxis(const pybind11::tuple &args,
522529
return ret;
523530
}
524531

532+
// imshow
533+
pybind11::object Axes::imshow(const pybind11::tuple &args,
534+
const pybind11::dict &kwargs) {
535+
pybind11::object ret = imshow_attr(*args, **kwargs);
536+
return ret;
537+
}
538+
525539
// legend
526540
legend::Legend Axes::legend(const pybind11::tuple &args,
527541
const pybind11::dict &kwargs) {

0 commit comments

Comments
 (0)