Skip to content

Commit aff6f64

Browse files
committed
plot can take format and keywords + add more missing _interpreter::get()
1) the basic implementation of plot takes: VectorX, VectorY, string, map. All other possibilities lead back to calling the basic implementation by providing the missing parameters. Advantage: now we can use the python-style linestyle format "ro--" and additional keywords. By-product: named_plot becomes obsolete, this is now used as: plot(x, y, "ro", {{"label", "f(x)"}}) 2) it was still possible to cause a segfault by calling xlim or ylim or title before any other function, this is fixed by adding detail::_interpreter::get() at the beginning of all these
1 parent a3580cb commit aff6f64

File tree

1 file changed

+54
-49
lines changed

1 file changed

+54
-49
lines changed

matplotlibcpp.h

Lines changed: 54 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -436,38 +436,66 @@ template <typename Vector> PyObject *get_array(const Vector &v) {
436436
#endif // WITHOUT_NUMPY
437437

438438
template <typename VectorX, typename VectorY>
439-
bool plot(const VectorX &x, const VectorY &y,
440-
const std::map<std::string, std::string> &keywords) {
439+
bool plot(const VectorX &x, const VectorY &y, const std::string &s = "",
440+
const std::map<std::string, std::string> &keywords = {}) {
441441
assert(x.size() == y.size());
442442

443-
// using numpy arrays
444443
PyObject *xarray = get_array(x);
445444
PyObject *yarray = get_array(y);
446445

447-
// construct positional args
448-
PyObject *args = PyTuple_New(2);
449-
PyTuple_SetItem(args, 0, xarray);
450-
PyTuple_SetItem(args, 1, yarray);
446+
PyObject *pystring = PyString_FromString(s.c_str());
447+
448+
PyObject *plot_args = PyTuple_New(3);
449+
PyTuple_SetItem(plot_args, 0, xarray);
450+
PyTuple_SetItem(plot_args, 1, yarray);
451+
PyTuple_SetItem(plot_args, 2, pystring);
451452

452-
// construct keyword args
453453
PyObject *kwargs = PyDict_New();
454-
for (std::map<std::string, std::string>::const_iterator it = keywords.begin();
455-
it != keywords.end(); ++it) {
456-
PyDict_SetItemString(kwargs, it->first.c_str(),
457-
PyString_FromString(it->second.c_str()));
454+
for (auto const &item : keywords) {
455+
PyDict_SetItemString(kwargs, item.first.c_str(),
456+
PyString_FromString(item.second.c_str()));
458457
}
459458

460459
PyObject *res = PyObject_Call(
461-
detail::_interpreter::get().s_python_function_plot, args, kwargs);
460+
detail::_interpreter::get().s_python_function_plot, plot_args, kwargs);
462461

463-
Py_DECREF(args);
462+
Py_DECREF(plot_args);
464463
Py_DECREF(kwargs);
465464
if (res)
466465
Py_DECREF(res);
467466

468467
return res;
469468
}
470469

470+
template <typename VectorX, typename VectorY>
471+
bool plot(const VectorX &x, const VectorY &y,
472+
const std::map<std::string, std::string> &keywords) {
473+
return plot(x, y, "", keywords);
474+
}
475+
476+
template <typename VectorY>
477+
bool plot(const VectorY &y, const std::string &format = "",
478+
const std::map<std::string, std::string> &keywords = {}) {
479+
// TODO can this be <size_t> or do we need <typename Vector::value_type>?
480+
// before the conversion of this function from vector<Numeric> to Vector
481+
// the created vector x was of the same type as y
482+
std::vector<std::size_t> x(y.size());
483+
for (std::size_t i = 0; i < x.size(); ++i)
484+
x.at(i) = i;
485+
486+
return plot(x, y, format);
487+
}
488+
489+
template <typename VectorY>
490+
bool plot(const VectorY &y,
491+
const std::map<std::string, std::string> &keywords) {
492+
std::vector<std::size_t> x(y.size());
493+
for (std::size_t i = 0; i < x.size(); ++i)
494+
x.at(i) = i;
495+
496+
return plot(x, y, "", keywords);
497+
}
498+
471499
template <typename Numeric>
472500
void plot_surface(const std::vector<::std::vector<Numeric>> &x,
473501
const std::vector<::std::vector<Numeric>> &y,
@@ -810,30 +838,6 @@ bool named_hist(std::string label, const std::vector<Numeric> &y,
810838
return res;
811839
}
812840

813-
template <typename VectorX, typename VectorY>
814-
bool plot(const VectorX &x, const VectorY &y, const std::string &s = "") {
815-
assert(x.size() == y.size());
816-
817-
PyObject *xarray = get_array(x);
818-
PyObject *yarray = get_array(y);
819-
820-
PyObject *pystring = PyString_FromString(s.c_str());
821-
822-
PyObject *plot_args = PyTuple_New(3);
823-
PyTuple_SetItem(plot_args, 0, xarray);
824-
PyTuple_SetItem(plot_args, 1, yarray);
825-
PyTuple_SetItem(plot_args, 2, pystring);
826-
827-
PyObject *res = PyObject_CallObject(
828-
detail::_interpreter::get().s_python_function_plot, plot_args);
829-
830-
Py_DECREF(plot_args);
831-
if (res)
832-
Py_DECREF(res);
833-
834-
return res;
835-
}
836-
837841
template <typename NumericX, typename NumericY, typename NumericU,
838842
typename NumericW>
839843
bool quiver(const std::vector<NumericX> &x, const std::vector<NumericY> &y,
@@ -1174,17 +1178,6 @@ bool named_loglog(const std::string &name, const std::vector<Numeric> &x,
11741178
return res;
11751179
}
11761180

1177-
template <typename Vector>
1178-
bool plot(const Vector &y, const std::string &format = "") {
1179-
// TODO can this be <size_t> or do we need <typename Vector::value_type>?
1180-
// before the conversion of this function from vector<Numeric> to Vector
1181-
// the created vector x was of the same type as y
1182-
std::vector<size_t> x(y.size());
1183-
for (size_t i = 0; i < x.size(); ++i)
1184-
x.at(i) = i;
1185-
return plot(x, y, format);
1186-
}
1187-
11881181
template <typename Numeric>
11891182
bool stem(const std::vector<Numeric> &y, const std::string &format = "") {
11901183
std::vector<Numeric> x(y.size());
@@ -1287,6 +1280,8 @@ inline void figure_size(size_t w, size_t h) {
12871280
}
12881281

12891282
inline void legend() {
1283+
detail::_interpreter::get();
1284+
12901285
PyObject *res =
12911286
PyObject_CallObject(detail::_interpreter::get().s_python_function_legend,
12921287
detail::_interpreter::get().s_python_empty_tuple);
@@ -1297,6 +1292,8 @@ inline void legend() {
12971292
}
12981293

12991294
template <typename Numeric> void ylim(Numeric left, Numeric right) {
1295+
detail::_interpreter::get();
1296+
13001297
PyObject *list = PyList_New(2);
13011298
PyList_SetItem(list, 0, PyFloat_FromDouble(left));
13021299
PyList_SetItem(list, 1, PyFloat_FromDouble(right));
@@ -1314,6 +1311,8 @@ template <typename Numeric> void ylim(Numeric left, Numeric right) {
13141311
}
13151312

13161313
template <typename Numeric> void xlim(Numeric left, Numeric right) {
1314+
detail::_interpreter::get();
1315+
13171316
PyObject *list = PyList_New(2);
13181317
PyList_SetItem(list, 0, PyFloat_FromDouble(left));
13191318
PyList_SetItem(list, 1, PyFloat_FromDouble(right));
@@ -1331,6 +1330,8 @@ template <typename Numeric> void xlim(Numeric left, Numeric right) {
13311330
}
13321331

13331332
inline double *xlim() {
1333+
detail::_interpreter::get();
1334+
13341335
PyObject *args = PyTuple_New(0);
13351336
PyObject *res = PyObject_CallObject(
13361337
detail::_interpreter::get().s_python_function_xlim, args);
@@ -1349,6 +1350,8 @@ inline double *xlim() {
13491350
}
13501351

13511352
inline double *ylim() {
1353+
detail::_interpreter::get();
1354+
13521355
PyObject *args = PyTuple_New(0);
13531356
PyObject *res = PyObject_CallObject(
13541357
detail::_interpreter::get().s_python_function_ylim, args);
@@ -1488,6 +1491,8 @@ inline void subplot(long nrows, long ncols, long plot_number) {
14881491

14891492
inline void title(const std::string &titlestr,
14901493
const std::map<std::string, std::string> &keywords = {}) {
1494+
detail::_interpreter::get();
1495+
14911496
PyObject *pytitlestr = PyString_FromString(titlestr.c_str());
14921497
PyObject *args = PyTuple_New(1);
14931498
PyTuple_SetItem(args, 0, pytitlestr);

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