From aa2e1d4922784a04835a2927fb42c3dc49c8fc8c Mon Sep 17 00:00:00 2001 From: Eduardo Eller Behr Date: Tue, 27 Dec 2022 08:45:03 -0300 Subject: [PATCH 1/2] Fixed implicit conversion from long to double --- matplotlibcpp.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/matplotlibcpp.h b/matplotlibcpp.h index d95d46a..b30b87f 100644 --- a/matplotlibcpp.h +++ b/matplotlibcpp.h @@ -2255,9 +2255,9 @@ inline void subplot(long nrows, long ncols, long plot_number) // construct positional args PyObject* args = PyTuple_New(3); - PyTuple_SetItem(args, 0, PyFloat_FromDouble(nrows)); - PyTuple_SetItem(args, 1, PyFloat_FromDouble(ncols)); - PyTuple_SetItem(args, 2, PyFloat_FromDouble(plot_number)); + PyTuple_SetItem(args, 0, PyLong_FromLong(nrows)); + PyTuple_SetItem(args, 1, PyLong_FromLong(ncols)); + PyTuple_SetItem(args, 2, PyLong_FromLong(plot_number)); PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_subplot, args); if(!res) throw std::runtime_error("Call to subplot() failed."); From f4305af2b32246e26427324f3a124222648ccc2f Mon Sep 17 00:00:00 2001 From: Eduardo Eller Behr Date: Tue, 14 Feb 2023 14:02:34 -0300 Subject: [PATCH 2/2] Added binding to matplotlib's `subplots(...)` call --- matplotlibcpp.h | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/matplotlibcpp.h b/matplotlibcpp.h index b30b87f..bad6218 100644 --- a/matplotlibcpp.h +++ b/matplotlibcpp.h @@ -67,6 +67,7 @@ struct _interpreter { PyObject *s_python_function_scatter; PyObject *s_python_function_boxplot; PyObject *s_python_function_subplot; + PyObject *s_python_function_subplots; PyObject *s_python_function_subplot2grid; PyObject *s_python_function_legend; PyObject *s_python_function_xlim; @@ -243,6 +244,7 @@ struct _interpreter { s_python_function_scatter = safe_import(pymod,"scatter"); s_python_function_boxplot = safe_import(pymod,"boxplot"); s_python_function_subplot = safe_import(pymod, "subplot"); + s_python_function_subplots = safe_import(pymod, "subplots"); s_python_function_subplot2grid = safe_import(pymod, "subplot2grid"); s_python_function_legend = safe_import(pymod, "legend"); s_python_function_xlim = safe_import(pymod, "xlim"); @@ -2266,6 +2268,40 @@ inline void subplot(long nrows, long ncols, long plot_number) Py_DECREF(res); } +/** + * @brief This utility wrapper makes it convenient to create common layouts of subplots, including the enclosing figure object, in a single call. + * + * @param nrows Number of rows of the subplot grid. + * @param ncols Number of columns of the subplot grid. + * @param keywords sharex {'none', 'all', 'row', 'col'}, sharey {'none', 'all', 'row', 'col'} + */ +inline void subplots(long nrows, long ncols, const std::map &keywords = {}) +{ + detail::_interpreter::get(); + + // construct positional args + PyObject* args = PyTuple_New(2); + PyTuple_SetItem(args, 0, PyLong_FromLong(nrows)); + PyTuple_SetItem(args, 1, PyLong_FromLong(ncols)); + + // construct keyword arguments + PyObject* kwargs = PyDict_New(); + for (auto it = keywords.begin(); it != keywords.end(); ++it) { + PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str())); + } + + PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_subplots, args, kwargs); + if(!res){ + PyErr_Print(); // TODO: print this error on every exception! + throw std::runtime_error("Call to subplots() failed."); + } + + // free memory + Py_DECREF(args); + Py_DECREF(kwargs); + Py_DECREF(res); +} + inline void subplot2grid(long nrows, long ncols, long rowid=0, long colid=0, long rowspan=1, long colspan=1) { detail::_interpreter::get();