@@ -437,9 +437,19 @@ template <typename Vector> PyObject *get_array(const Vector &v) {
437437
438438#endif // WITHOUT_NUMPY
439439
440+ namespace detail {
441+ // @brief Since most of the plot commands require the exact same usage apart
442+ // from the call to the correct Python function, we encapsulate this
443+ // @param pyfunc The matplotlib function to be called with the given arguments
444+ // @param x The x vector, must support std::vector methods
445+ // @param y The y vector, must support std::vector methods
446+ // @param s The formatting string for colour, marker and linestyle
447+ // @param keywords Additional keywords, such as label
448+ // @return true if plot was successful, false otherwise
440449template <typename VectorX, typename VectorY>
441- bool plot (const VectorX &x, const VectorY &y, const std::string &s = " " ,
442- const std::map<std::string, std::string> &keywords = {}) {
450+ bool plot_base (PyObject *const pyfunc, const VectorX &x, const VectorY &y,
451+ const std::string &s = " " ,
452+ const std::map<std::string, std::string> &keywords = {}) {
443453 assert (x.size () == y.size ());
444454
445455 PyObject *xarray = get_array (x);
@@ -458,8 +468,7 @@ bool plot(const VectorX &x, const VectorY &y, const std::string &s = "",
458468 PyString_FromString (item.second .c_str ()));
459469 }
460470
461- PyObject *res = PyObject_Call (
462- detail::_interpreter::get ().s_python_function_plot , plot_args, kwargs);
471+ PyObject *res = PyObject_Call (pyfunc, plot_args, kwargs);
463472
464473 Py_DECREF (plot_args);
465474 Py_DECREF (kwargs);
@@ -469,6 +478,15 @@ bool plot(const VectorX &x, const VectorY &y, const std::string &s = "",
469478 return res;
470479}
471480
481+ } // namespace detail
482+
483+ template <typename VectorX, typename VectorY>
484+ bool plot (const VectorX &x, const VectorY &y, const std::string &s = " " ,
485+ const std::map<std::string, std::string> &keywords = {}) {
486+ return detail::plot_base (detail::_interpreter::get ().s_python_function_plot ,
487+ x, y, s, keywords);
488+ }
489+
472490template <typename VectorX, typename VectorY>
473491bool plot (const VectorX &x, const VectorY &y,
474492 const std::map<std::string, std::string> &keywords) {
@@ -501,33 +519,8 @@ bool plot(const VectorY &y,
501519template <typename VectorX, typename VectorY>
502520bool loglog (const VectorX &x, const VectorY &y, const std::string &s = " " ,
503521 const std::map<std::string, std::string> &keywords = {}) {
504- assert (x.size () == y.size ());
505-
506- PyObject *xarray = get_array (x);
507- PyObject *yarray = get_array (y);
508-
509- PyObject *pystring = PyString_FromString (s.c_str ());
510-
511- PyObject *plot_args = PyTuple_New (3 );
512- PyTuple_SetItem (plot_args, 0 , xarray);
513- PyTuple_SetItem (plot_args, 1 , yarray);
514- PyTuple_SetItem (plot_args, 2 , pystring);
515-
516- PyObject *kwargs = PyDict_New ();
517- for (auto const &item : keywords) {
518- PyDict_SetItemString (kwargs, item.first .c_str (),
519- PyString_FromString (item.second .c_str ()));
520- }
521-
522- PyObject *res = PyObject_Call (
523- detail::_interpreter::get ().s_python_function_loglog , plot_args, kwargs);
524-
525- Py_DECREF (plot_args);
526- Py_DECREF (kwargs);
527- if (res)
528- Py_DECREF (res);
529-
530- return res;
522+ return detail::plot_base (detail::_interpreter::get ().s_python_function_loglog ,
523+ x, y, s, keywords);
531524}
532525
533526template <typename VectorX, typename VectorY>
0 commit comments