Skip to content

Commit 52816e2

Browse files
cdbrkfxrptlava
authored andcommitted
Adds boxplot, get_strarray and get_listlist
1 parent 1809d7a commit 52816e2

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed

matplotlibcpp.h

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ struct _interpreter {
6161
PyObject *s_python_function_hist;
6262
PyObject *s_python_function_imshow;
6363
PyObject *s_python_function_scatter;
64+
PyObject *s_python_function_boxplot;
6465
PyObject *s_python_function_subplot;
6566
PyObject *s_python_function_subplot2grid;
6667
PyObject *s_python_function_legend;
@@ -197,6 +198,7 @@ struct _interpreter {
197198
s_python_function_fill_between = safe_import(pymod, "fill_between");
198199
s_python_function_hist = safe_import(pymod,"hist");
199200
s_python_function_scatter = safe_import(pymod,"scatter");
201+
s_python_function_boxplot = safe_import(pymod,"boxplot");
200202
s_python_function_subplot = safe_import(pymod, "subplot");
201203
s_python_function_subplot2grid = safe_import(pymod, "subplot2grid");
202204
s_python_function_legend = safe_import(pymod, "legend");
@@ -326,6 +328,27 @@ PyObject* get_2darray(const std::vector<::std::vector<Numeric>>& v)
326328
return reinterpret_cast<PyObject *>(varray);
327329
}
328330

331+
// sometimes, for labels and such, we need string arrays
332+
PyObject * get_array(const std::vector<std::string>& strings)
333+
{
334+
PyObject* list = PyList_New(strings.size());
335+
for (std::size_t i = 0; i < strings.size(); ++i) {
336+
PyList_SetItem(list, i, PyString_FromString(strings[i].c_str()));
337+
}
338+
return list;
339+
}
340+
341+
// not all matplotlib need 2d arrays, some prefer lists of lists
342+
template<typename Numeric>
343+
PyObject* get_listlist(const std::vector<std::vector<Numeric>>& ll)
344+
{
345+
PyObject* listlist = PyList_New(ll.size());
346+
for (std::size_t i = 0; i < ll.size(); ++i) {
347+
PyList_SetItem(listlist, i, get_array(ll[i]));
348+
}
349+
return listlist;
350+
}
351+
329352
#else // fallback if we don't have numpy: copy every element of the given vector
330353

331354
template<typename Numeric>
@@ -698,6 +721,62 @@ bool scatter(const std::vector<NumericX>& x,
698721
return res;
699722
}
700723

724+
template<typename Numeric>
725+
bool boxplot(const std::vector<std::vector<Numeric>>& data,
726+
const std::vector<std::string>& labels = {},
727+
const std::unordered_map<std::string, std::string> & keywords = {})
728+
{
729+
PyObject* listlist = get_listlist(data);
730+
PyObject* args = PyTuple_New(1);
731+
PyTuple_SetItem(args, 0, listlist);
732+
733+
PyObject* kwargs = PyDict_New();
734+
735+
// kwargs needs the labels, if there are (the correct number of) labels
736+
if (!labels.empty() && labels.size() == data.size()) {
737+
PyDict_SetItemString(kwargs, "labels", get_array(labels));
738+
}
739+
740+
// take care of the remaining keywords
741+
for (const auto& it : keywords)
742+
{
743+
PyDict_SetItemString(kwargs, it.first.c_str(), PyString_FromString(it.second.c_str()));
744+
}
745+
746+
PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_boxplot, args, kwargs);
747+
748+
Py_DECREF(args);
749+
Py_DECREF(kwargs);
750+
751+
if(res) Py_DECREF(res);
752+
753+
return res;
754+
}
755+
756+
template<typename Numeric>
757+
bool boxplot(const std::vector<Numeric>& data,
758+
const std::unordered_map<std::string, std::string> & keywords = {})
759+
{
760+
PyObject* vector = get_array(data);
761+
PyObject* args = PyTuple_New(1);
762+
PyTuple_SetItem(args, 0, vector);
763+
764+
PyObject* kwargs = PyDict_New();
765+
for (const auto& it : keywords)
766+
{
767+
PyDict_SetItemString(kwargs, it.first.c_str(), PyString_FromString(it.second.c_str()));
768+
}
769+
770+
PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_boxplot, args, kwargs);
771+
772+
Py_DECREF(args);
773+
Py_DECREF(kwargs);
774+
775+
if(res) Py_DECREF(res);
776+
777+
return res;
778+
}
779+
701780
template <typename Numeric>
702781
bool bar(const std::vector<Numeric> & x,
703782
const std::vector<Numeric> & y,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy