Skip to content

Commit

Permalink
adding GridSpec, Text, and align_labels_demo.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
soblin committed Jan 25, 2022
1 parent 509b34e commit 56fed52
Show file tree
Hide file tree
Showing 12 changed files with 153 additions and 34 deletions.
1 change: 1 addition & 0 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ NamespaceIndentation: None
Language: Cpp
Standard: Auto
ColumnLimit: 80
SortIncludes: false
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
project(matplotlib-cpp11)
cmake_minimum_required(VERSION 3.0)

find_package(PythonLibs 3 REQUIRED)
Expand All @@ -16,7 +17,9 @@ endfunction()

if(${ADD_DEMO})
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "-Wall -g")
add_demo(simple_plot gallery/lines_bars_and_markers/simple_plot.cpp)
add_demo(align_labels_demo gallery/subplots_axes_and_figures/align_labels_demo.cpp)
endif()

if(NOT DEFINED DO_TEST)
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,11 @@ This project aims to replace [matplotlibcpp](https://github.com/lava/matplotlib-
## Usage

Just add include path to `include` directory of this project.

## Demos

`gallery` folder contains corresponding examples from [the official website of matplotlib](https://matplotlib.org/stable/gallery) with the same structure.

## Contributing

Contributions to this project are welcome if you could add or want/need more modules :)
7 changes: 4 additions & 3 deletions gallery/lines_bars_and_markers/simple_plot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ template <typename T> std::vector<T> arange(T start, T end, T h) {
int N = static_cast<int>((end - start) / h);
std::vector<T> xs(N);
T val = start;
while (val <= end) {
xs.push_back(val);
for (int i = 0; i < N; ++i) {
xs[i] = val;
;
val += h;
}
return xs;
Expand All @@ -26,7 +27,7 @@ template <typename T> std::vector<T> arange(T start, T end, T h) {
using namespace std;

int main() {
py::scoped_interpreter guard{};
py::initialize_interpreter();
auto plt = matplotlib_cpp11::import();
auto t = arange(0.0, 2.0, 0.01);
decltype(t) s;
Expand Down
54 changes: 54 additions & 0 deletions gallery/subplots_axes_and_figures/align_labels_demo.cpp
Original file line number Diff line number Diff line change
@@ -1,2 +1,56 @@
// example from
// https://matplotlib.org/stable/gallery/subplots_axes_and_figures/align_labels_demo.html#sphx-glr-gallery-subplots-axes-and-figures-align-labels-demo-py

#include <pybind11/embed.h>
#include <pybind11/stl.h>

#include <matplotlib_cpp11/matplotlib_cpp11.h>

#include <algorithm>
#include <iostream>
#include <vector>

namespace py = pybind11;
using namespace py::literals;

template <typename T> std::vector<T> arange(T start, T end, T h) {
int N = static_cast<int>((end - start) / h);
std::vector<T> xs(N);
T val = start;
for (int i = 0; i < N; ++i) {
xs[i] = val;
;
val += h;
}
return xs;
}

using namespace std;
namespace pyplot = matplotlib_cpp11;

int main() {
py::initialize_interpreter();
auto plt = pyplot::import();
auto fig = pyplot::Figure(plt.figure("tight_layout"_a = true));
auto gs = pyplot::GridSpec(2, 2);
auto ax = pyplot::Axes(fig.add_subplot(gs(0, -1)));
ax.plot(arange(0, 1000000, 10000));
ax.set_ylabel("YLabel0");
ax.set_xlabel("XLabel0");
for (auto i : {0, 1}) {
ax = pyplot::Axes(fig.add_subplot(gs(1, i)));
auto ys = arange(1.0, 0.0, -0.1);
decltype(ys) xs;
std::for_each(ys.begin(), ys.end(),
[&](auto val) { xs.push_back(val * 2000); });
ax.plot(xs, ys);
ax.set_ylabel(string("YLabel1 " + to_string(i)));
ax.set_xlabel(string("XLabel1 " + to_string(i)));
if (i == 0) {
for (auto &&tick : ax.get_xticklabels())
tick.set_rotation(55);
}
}
fig.align_labels();
plt.show();
}
21 changes: 16 additions & 5 deletions include/matplotlib_cpp11/axes.h
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
#include <vector>

struct __attribute__((visibility("hidden"))) Axes {
Axes() {}
Axes(pybind11::object axes) {
self = axes;
load_attrs();
}
Axes(pybind11::module mod) {
self = mod.attr("axes");
load_attrs();
}
void load_attrs() {
LOAD_ATTR(plot, self);
LOAD_ATTR(set, self);
LOAD_ATTR(grid, self);
LOAD_ATTR(set_xlabel, self);
LOAD_ATTR(set_ylabel, self);
get_xticklabels_attr = self.attr("get_xticklabels");
}
pybind11::object self;
pybind11::object plot;
pybind11::object set;
pybind11::object grid;
pybind11::object set_xlabel;
pybind11::object set_ylabel;
pybind11::object get_xticklabels_attr;
std::vector<Text> get_xticklabels() {
pybind11::list ret = get_xticklabels_attr();
std::vector<Text> texts;
for (pybind11::size_t i = 0; i < ret.size(); ++i) {
texts.push_back(Text(ret[i]));
}
return texts;
}
};
4 changes: 4 additions & 0 deletions include/matplotlib_cpp11/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#define LOAD_ATTR(attr_, mod_) \
do { \
attr_ = mod_.attr(#attr_); \
} while (0)
10 changes: 5 additions & 5 deletions include/matplotlib_cpp11/figure.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
struct __attribute__((visibility("hidden"))) Figure {
Figure() {}
Figure(pybind11::object figure) {
self = figure;
load_attrs();
}
Figure(pybind11::module mod) {
self = mod.attr("figure");
load_attrs();
void load_attrs() {
LOAD_ATTR(savefig, self);
LOAD_ATTR(add_subplot, self);
LOAD_ATTR(align_labels, self);
}
void load_attrs() { LOAD_ATTR(savefig, self); }
pybind11::object self;
pybind11::object savefig;
pybind11::object add_subplot;
pybind11::object align_labels;
};
29 changes: 29 additions & 0 deletions include/matplotlib_cpp11/gridspec.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
struct __attribute__((visibility("hidden"))) GridSpec {
GridSpec(int nrow_, int ncol_) {
nrow = nrow_;
ncol = ncol_;
load_attrs();
}
void load_attrs() {
gridspec_attr =
pybind11::module::import("matplotlib.gridspec").attr("GridSpec");
self = gridspec_attr(nrow, ncol);
}
pybind11::object operator()(int r, int c) {
// if r == -1 or c == -1, do slice
if (r == -1) {
if (c == -1) {
return self;
}
auto rs = pybind11::slice(0, nrow, 1);
return self[pybind11::make_tuple(rs, c)];
} else if (c == -1) {
auto cs = pybind11::slice(0, ncol, 1);
return self[pybind11::make_tuple(r, cs)];
} else
return self[pybind11::make_tuple(r, c)];
}
int nrow, ncol;
pybind11::object self;
pybind11::object gridspec_attr;
};
22 changes: 3 additions & 19 deletions include/matplotlib_cpp11/matplotlib_cpp11.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,14 @@

namespace matplotlib_cpp11 {

static bool g_imported = false;

#define LOAD_ATTR(attr_, mod_) \
do { \
attr_ = mod_.attr(#attr_); \
} while (0)
#include "common.h"

#include "text.h"
#include "axes.h"
#include "figure.h"
#include "gridspec.h"
#include "pyplot.h"

static pyplot &import() {
static pyplot g_pyplot;
static Figure g_figure;
static Axes g_axes;
if (not g_imported) {
g_imported = true;
// pyplot singleton
auto mod = pybind11::module::import("matplotlib.pyplot");
g_pyplot = pyplot(mod);
}
return g_pyplot;
}

} // namespace matplotlib_cpp11

#endif /* MATPLOTLIBCPP_11_H */
19 changes: 17 additions & 2 deletions include/matplotlib_cpp11/pyplot.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ struct __attribute__((visibility("hidden"))) pyplot {
LOAD_ATTR(show, mod);
subplot_attr = mod.attr("subplot");
subplots_attr = mod.attr("subplots");
LOAD_ATTR(figure, mod);
LOAD_ATTR(axes, mod);
}
pybind11::module mod;
pybind11::object plot;
Expand All @@ -22,6 +24,19 @@ struct __attribute__((visibility("hidden"))) pyplot {
pybind11::object fig = ret[0], ax = ret[1];
return {Figure(fig), Axes(ax)};
}
Figure figure() { return Figure(mod); }
Axes axes() { return Axes(mod); }
pybind11::object figure;
pybind11::object axes;
};

static bool g_imported = false;

static pyplot &import() {
static pyplot g_pyplot;
if (not g_imported) {
g_imported = true;
// pyplot singleton
auto mod = pybind11::module::import("matplotlib.pyplot");
g_pyplot = pyplot(mod);
}
return g_pyplot;
}
9 changes: 9 additions & 0 deletions include/matplotlib_cpp11/text.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
struct __attribute__((visibility("hidden"))) Text {
Text(pybind11::object text) {
self = text;
load_attrs();
}
void load_attrs() { LOAD_ATTR(set_rotation, self); }
pybind11::object self;
pybind11::object set_rotation;
};

0 comments on commit 56fed52

Please sign in to comment.