-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 43d0068
Showing
10 changed files
with
1,772 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
cmake_minimum_required(VERSION 3.15) | ||
project(matplotlibcpp) | ||
|
||
set(CMAKE_CXX_STANDARD 17) | ||
|
||
find_package(Boost COMPONENTS python3 numpy3) | ||
find_package(Python3 COMPONENTS Interpreter Development NumPy) | ||
|
||
add_library(matplotlibcpp INTERFACE) | ||
target_include_directories(matplotlibcpp INTERFACE ${CMAKE_CURRENT_LIST_DIR}/inc) | ||
target_link_libraries(matplotlibcpp INTERFACE Python3::Python Python3::NumPy Boost::python3 Boost::numpy3) | ||
|
||
|
||
file(GLOB SRCS ${CMAKE_CURRENT_LIST_DIR}/test/*.cpp) | ||
foreach(SRC ${SRCS}) | ||
get_filename_component(TARGET_NAME ${SRC} NAME_WE) | ||
add_executable(${TARGET_NAME} ${SRC}) | ||
target_link_libraries(${TARGET_NAME} matplotlibcpp) | ||
endforeach() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#pragma once | ||
|
||
#include "matplotlibcpp/axes.hpp" | ||
#include "matplotlibcpp/figure.hpp" | ||
#include "matplotlibcpp/pyplot.hpp" | ||
#include "matplotlibcpp/animation.hpp" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#pragma once | ||
|
||
#include "util.hpp" | ||
|
||
namespace matplotlibcpp::animation | ||
{ | ||
|
||
struct FuncAnimation | ||
{ | ||
template <class... TKWArgs> | ||
FuncAnimation(const Figure& fig, void (*plotter)(py::object), const std::pair<const char*, TKWArgs>&... kwargs) | ||
: self{ | ||
py::import("matplotlib.animation") | ||
.attr("FuncAnimation")( | ||
*py::make_tuple(fig.self, py::make_function(static_cast<void (*)(py::object)>(plotter))), **to_dict(kwargs...))} | ||
{ | ||
} | ||
|
||
py::object self; | ||
}; | ||
|
||
} // namespace matplotlibcpp::animation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
#pragma once | ||
|
||
#include "util.hpp" | ||
|
||
namespace matplotlibcpp | ||
{ | ||
|
||
struct Axes | ||
{ | ||
explicit Axes(const py::object& self) | ||
: self{self}, | ||
plot_{self.attr("plot")}, scatter_{self.attr("scatter")}, hist_{self.attr("hist")}, | ||
hlines_{self.attr("hlines")}, vlines_{self.attr("vlines")}, annotate_{self.attr("annotate")}, | ||
set_title_{self.attr("set_title")}, set_xlabel_{self.attr("set_xlabel")}, set_ylabel_{self.attr("set_ylabel")} | ||
{ | ||
} | ||
|
||
template <class T, class... TKWArgs> | ||
void plot(const std::vector<T>& x, const std::vector<T>& y, const std::pair<const char*, TKWArgs>&... kwargs) | ||
{ | ||
plot_(*py::make_tuple(to_ndarray(x), to_ndarray(y)), **to_dict(kwargs...)); | ||
} | ||
|
||
template <class T, class... TKWArgs> | ||
void plot(const std::vector<T>& x, const std::vector<T>& y, const char* fmt, const std::pair<const char*, TKWArgs>&... kwargs) | ||
{ | ||
plot_(*py::make_tuple(to_ndarray(x), to_ndarray(y), fmt), **to_dict(kwargs...)); | ||
} | ||
|
||
template <class T, class... TKWArgs> | ||
void scatter(const std::vector<T>& x, const std::vector<T>& y, const std::pair<const char*, TKWArgs>&... kwargs) | ||
{ | ||
scatter_(*py::make_tuple(to_ndarray(x), to_ndarray(y)), **to_dict(kwargs...)); | ||
} | ||
|
||
template <class T, class... TKWArgs> | ||
void hist(const std::vector<T>& x, const std::pair<const char*, TKWArgs>&... kwargs) | ||
{ | ||
hist_(to_ndarray(x), **to_dict(kwargs...)); | ||
} | ||
|
||
template <class... TKWArgs> | ||
void hlines(double y, double xmin, double xmax, const std::pair<const char*, TKWArgs>&... kwargs) | ||
{ | ||
hlines_(*py::make_tuple(y, xmin, xmax), **to_dict(kwargs...)); | ||
} | ||
|
||
template <class... TKWArgs> | ||
void vlines(double x, double ymin, double ymax, const std::pair<const char*, TKWArgs>&... kwargs) | ||
{ | ||
vlines_(*py::make_tuple(self, x, ymin, ymax), **to_dict(kwargs...)); | ||
} | ||
|
||
template <class... TKWArgs> | ||
void arrow(double x0, double y0, double x1, double y1, const std::pair<const char*, TKWArgs>&... arrowprops) | ||
{ | ||
annotate_(py::object(""), | ||
**to_dict(std::make_pair("xy", py::make_tuple(x1, y1)), std::make_pair("xytext", py::make_tuple(x0, y0)), | ||
std::make_pair("arrowprops", to_dict(arrowprops...)))); | ||
} | ||
|
||
void arrow(double x0, double y0, double x1, double y1, const char* arrowstyle = "->") | ||
{ | ||
annotate_(py::object(""), | ||
**to_dict(std::make_pair("xy", py::make_tuple(x1, y1)), std::make_pair("xytext", py::make_tuple(x0, y0)), | ||
std::make_pair("arrowprops", | ||
to_dict(std::make_pair("arrowstyle", arrowstyle))))); | ||
} | ||
|
||
template <class... TKWArgs> | ||
void set_title(const std::string& title, const std::pair<const char*, TKWArgs>&... kwargs) | ||
{ | ||
set_title_(title.c_str(), **to_dict(kwargs...)); | ||
} | ||
|
||
void set_xlabel(const std::string& label) | ||
{ | ||
set_xlabel_(label.c_str()); | ||
} | ||
|
||
void set_ylabel(const std::string& label) | ||
{ | ||
set_ylabel_(label.c_str()); | ||
} | ||
|
||
private: | ||
using object = boost::python::object; | ||
object self; | ||
object plot_, scatter_, hist_, hlines_, vlines_, annotate_, set_title_, set_xlabel_, set_ylabel_; | ||
}; | ||
|
||
} // namespace matplotlibcpp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#pragma once | ||
|
||
#include "util.hpp" | ||
#include "axes.hpp" | ||
|
||
namespace matplotlibcpp | ||
{ | ||
|
||
struct Figure | ||
{ | ||
using object = boost::python::object; | ||
|
||
explicit Figure(const py::object& self) | ||
: self{self}, | ||
add_axes_{self.attr("add_axes")}, | ||
add_subplot_{self.attr("add_subplot")}, | ||
legend{self.attr("legend")}, | ||
tight_layout{self.attr("tight_layout")}, | ||
clf{self.attr("clf")} | ||
{ | ||
} | ||
|
||
Axes add_axes(double l, double b, double w, double h) | ||
{ | ||
auto axes = add_axes_(*py::make_tuple(l, b, w, h)); | ||
return Axes{axes}; | ||
} | ||
|
||
Axes add_subplot(int nrows, int ncols, int index) | ||
{ | ||
auto axes = add_subplot_(*py::make_tuple(nrows, ncols, index)); | ||
return Axes{axes}; | ||
} | ||
|
||
object self; | ||
|
||
// callable | ||
object legend; | ||
object tight_layout; | ||
object clf; | ||
|
||
private: | ||
object add_axes_, add_subplot_; | ||
}; | ||
} // namespace matplotlibcpp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
#pragma once | ||
|
||
#include "util.hpp" | ||
|
||
namespace matplotlibcpp | ||
{ | ||
|
||
struct pyplot | ||
{ | ||
using object = boost::python::object; | ||
|
||
template <class T = double, class... TKWArgs> | ||
static void plot(const std::vector<T>& x, const std::vector<T>& y, const std::pair<const char*, TKWArgs>&... kwargs) | ||
{ | ||
plot_(*py::make_tuple(to_ndarray(x), to_ndarray(y)), **to_dict(kwargs...)); | ||
} | ||
|
||
template <class T = double, class... TKWArgs> | ||
static void plot(const std::vector<T>& x, const std::vector<T>& y, const char* fmt, const std::pair<const char*, TKWArgs>&... kwargs) | ||
{ | ||
plot_(*py::make_tuple(to_ndarray(x), to_ndarray(y), fmt), **to_dict(kwargs...)); | ||
} | ||
|
||
template <class... TKWArgs> | ||
static void arrow(double x0, double y0, double x1, double y1, const std::pair<const char*, TKWArgs>&... arrowprops) | ||
{ | ||
annotate_(*py::make_tuple(py::object("")), | ||
**to_dict(std::make_pair("xy", py::make_tuple(x1, y1)), | ||
std::make_pair("xytext", py::make_tuple(x0, y0)), | ||
std::make_pair("arrowprops", to_dict(arrowprops...)))); | ||
} | ||
|
||
static void arrow(double x0, double y0, double x1, double y1, const char* arrowstyle = "->") | ||
{ | ||
annotate_(*py::make_tuple(py::object("")), | ||
**to_dict(std::make_pair("xy", py::make_tuple(x1, y1)), | ||
std::make_pair("xytext", py::make_tuple(x0, y0)), | ||
std::make_pair("arrowprops", | ||
to_dict(std::make_pair("arrowstyle", arrowstyle))))); | ||
} | ||
|
||
template <class T, class... TKWArgs> | ||
static void scatter(const std::vector<T>& x, const std::vector<T>& y, const std::pair<const char*, TKWArgs>&... kwargs) | ||
{ | ||
scatter_(*py::make_tuple(to_ndarray(x), to_ndarray(y)), **to_dict(kwargs...)); | ||
} | ||
|
||
template <class T, class... TKWArgs> | ||
static void hist(const std::vector<T>& x, const std::pair<const char*, TKWArgs>&... kwargs) | ||
{ | ||
hist_(*py::make_tuple(to_ndarray(x)), **to_dict(kwargs...)); | ||
} | ||
|
||
template <class... TKWArgs> | ||
static void title(const std::string& title, const std::pair<const char*, TKWArgs>&... kwargs) | ||
{ | ||
title_(*py::make_tuple(title.c_str()), **to_dict(kwargs...)); | ||
} | ||
|
||
static void xlim(double left, double right) | ||
{ | ||
xlim_(left, right); | ||
} | ||
|
||
static void ylim(double bottom, double top) | ||
{ | ||
ylim_(bottom, top); | ||
} | ||
|
||
static void xlabel(const std::string& label) | ||
{ | ||
xlabel_(label.c_str()); | ||
} | ||
|
||
static void ylabel(const std::string& label) | ||
{ | ||
ylabel_(label.c_str()); | ||
} | ||
|
||
template <class... TKWArgs> | ||
static void hlines(double y, double xmin, double xmax, const std::pair<const char*, TKWArgs>&... kwargs) | ||
{ | ||
hlines_(*py::make_tuple(y, xmin, xmax), **to_dict(kwargs...)); | ||
} | ||
|
||
template <class... TKWArgs> | ||
static void vlines(double x, double ymin, double ymax, const std::pair<const char*, TKWArgs>&... kwargs) | ||
{ | ||
vlines_(*py::make_tuple(x, ymin, ymax), **to_dict(kwargs...)); | ||
} | ||
|
||
template <class... TKWArgs> | ||
static void subplot(int nrows, int ncols, int index, const std::pair<const char*, TKWArgs>&... kwargs) | ||
{ | ||
subplot_(*py::make_tuple(nrows, ncols, index), **to_dict(kwargs...)); | ||
} | ||
|
||
static void show() { show_(); } | ||
static void legend() { legend_(); } | ||
static void tight_layout() { tight_layout_(); } | ||
static void savefig(const char* path) { savefig_(path); } | ||
static void cla() { cla_(); } | ||
|
||
static Figure figure() | ||
{ | ||
return Figure{figure_()}; | ||
} | ||
|
||
private: | ||
inline static object plot_, scatter_, hist_, annotate_, title_; | ||
inline static object xlim_, ylim_, xlabel_, ylabel_; | ||
inline static object hlines_, vlines_; | ||
inline static object subplot_, show_, legend_, tight_layout_; | ||
inline static object figure_, savefig_, cla_; | ||
|
||
public: | ||
pyplot() | ||
{ | ||
if (!Py_IsInitialized()) { | ||
Py_Initialize(); | ||
np::initialize(); | ||
} | ||
auto dict = py::dict{py::import("matplotlib.pyplot").attr("__dict__")}; | ||
plot_ = dict["plot"]; | ||
scatter_ = dict["scatter"]; | ||
hist_ = dict["hist"]; | ||
annotate_ = dict["annotate"]; | ||
title_ = dict["title"]; | ||
xlim_ = dict["xlim"]; | ||
ylim_ = dict["ylim"]; | ||
xlabel_ = dict["xlabel"]; | ||
ylabel_ = dict["ylabel"]; | ||
hlines_ = dict["hlines"]; | ||
vlines_ = dict["vlines"]; | ||
subplot_ = dict["subplot"]; | ||
show_ = dict["show"]; | ||
legend_ = dict["legend"]; | ||
tight_layout_ = dict["tight_layout"]; | ||
figure_ = dict["figure"]; | ||
savefig_ = dict["savefig"]; | ||
cla_ = dict["cla"]; | ||
} | ||
}; | ||
|
||
|
||
inline auto plt = matplotlibcpp::pyplot{}; | ||
} // namespace matplotlibcpp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#pragma once | ||
|
||
#include <boost/python.hpp> | ||
#include <boost/python/numpy.hpp> | ||
|
||
namespace matplotlibcpp | ||
{ | ||
namespace py = boost::python; | ||
namespace np = boost::python::numpy; | ||
|
||
template <class T, class = std::enable_if_t<std::is_arithmetic_v<typename T::value_type>>> | ||
np::ndarray to_ndarray(const T& vec) | ||
{ | ||
auto shape = py::make_tuple(vec.size()); | ||
auto dtype = np::dtype::get_builtin<typename T::value_type>(); | ||
auto strides = py::make_tuple(sizeof(typename T::value_type)); | ||
py::object owner; | ||
return np::from_data(static_cast<const void*>(vec.data()), dtype, shape, strides, owner).copy(); | ||
} | ||
|
||
template <class... TKWArgs> | ||
py::dict to_dict(const std::pair<const char*, TKWArgs>&... kwargs) | ||
{ | ||
py::dict ret; | ||
((ret[kwargs.first] = kwargs.second), ...); | ||
return ret; | ||
} | ||
} // namespace matplotlibcpp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#include <matplotlibcpp.hpp> | ||
|
||
#include <boost/core/demangle.hpp> | ||
#include <iostream> | ||
#include <string> | ||
|
||
|
||
int main() | ||
{ | ||
using namespace Flier; | ||
std::vector<double> x{1, 2, 3}; | ||
std::vector<double> y{1, 2, 3}; | ||
plt.scatter(x, y, std::make_pair("alpha", 0.5)); | ||
plt.show(); | ||
} |
Oops, something went wrong.