From 99adb9c0e5a22f2671b097c20b5ea7ce7b46ea6f Mon Sep 17 00:00:00 2001 From: Pieter Date: Sun, 25 Nov 2018 18:54:35 +0100 Subject: [PATCH 1/2] Fix xkcd exception message, add 'axhline' & 'axvline' --- matplotlibcpp.h | 61 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/matplotlibcpp.h b/matplotlibcpp.h index c4b2767..3582666 100644 --- a/matplotlibcpp.h +++ b/matplotlibcpp.h @@ -62,6 +62,8 @@ struct _interpreter { PyObject *s_python_empty_tuple; PyObject *s_python_function_stem; PyObject *s_python_function_xkcd; + PyObject *s_python_function_axhline; + PyObject *s_python_function_axvline; /* For now, _interpreter is implemented as a singleton since its currently not possible to have multiple independent embedded python interpreters without patching the python source code @@ -165,6 +167,8 @@ struct _interpreter { s_python_function_tight_layout = PyObject_GetAttrString(pymod, "tight_layout"); s_python_function_stem = PyObject_GetAttrString(pymod, "stem"); s_python_function_xkcd = PyObject_GetAttrString(pymod, "xkcd"); + s_python_function_axhline = PyObject_GetAttrString(pymod, "axhline"); + s_python_function_axvline = PyObject_GetAttrString(pymod, "axvline"); if( !s_python_function_show || !s_python_function_close @@ -195,6 +199,8 @@ struct _interpreter { || !s_python_function_tight_layout || !s_python_function_stem || !s_python_function_xkcd + || !s_python_function_axhline + || !s_python_function_axvline ) { throw std::runtime_error("Couldn't find required function!"); } if ( !PyFunction_Check(s_python_function_show) @@ -225,6 +231,8 @@ struct _interpreter { || !PyFunction_Check(s_python_function_errorbar) || !PyFunction_Check(s_python_function_stem) || !PyFunction_Check(s_python_function_xkcd) + || !PyFunction_Check(s_python_function_axhline) + || !PyFunction_Check(s_python_function_axvline) ) { throw std::runtime_error("Python object is unexpectedly not a PyFunction."); } s_python_empty_tuple = PyTuple_New(0); @@ -1113,7 +1121,58 @@ inline void xkcd() { Py_DECREF(kwargs); if (!res) - throw std::runtime_error("Call to show() failed."); + throw std::runtime_error("Call to xkcd() failed."); + + Py_DECREF(res); +} + +inline void axhline(const double y = 0, const std::string& linestyle = "", const std::string &color = "", const double xmin = 0, const double xmax = 1) { + PyObject *res; + PyObject *args = PyTuple_New(3); + PyObject *kwargs = PyDict_New(); + + PyObject *pylinestyle = PyString_FromString(linestyle.c_str()); + PyObject *pycolor = PyString_FromString(color.c_str()); + + PyDict_SetItemString(kwargs, "linestyle", PyString_FromString(linestyle.c_str())); + PyDict_SetItemString(kwargs, "color", PyString_FromString(color.c_str())); + + PyTuple_SetItem(args, 0, PyFloat_FromDouble(y)); + PyTuple_SetItem(args, 1, PyFloat_FromDouble(xmin)); + PyTuple_SetItem(args, 2, PyFloat_FromDouble(xmax)); + + res = PyObject_Call(detail::_interpreter::get().s_python_function_axhline, + args, kwargs); + + Py_DECREF(args); + Py_DECREF(kwargs); + + if (!res) + throw std::runtime_error("Call to axhline() failed."); + + Py_DECREF(res); +} + +inline void axvline(const double x = 0, const std::string& linestyle = "", const std::string &color = "", const double ymin = 0, const double ymax = 1) { + PyObject *res; + PyObject *args = PyTuple_New(3); + PyObject *kwargs = PyDict_New(); + + PyDict_SetItemString(kwargs, "linestyle", PyString_FromString(linestyle.c_str())); + PyDict_SetItemString(kwargs, "color", PyString_FromString(color.c_str())); + + PyTuple_SetItem(args, 0, PyFloat_FromDouble(x)); + PyTuple_SetItem(args, 1, PyFloat_FromDouble(ymin)); + PyTuple_SetItem(args, 2, PyFloat_FromDouble(ymax)); + + res = PyObject_Call(detail::_interpreter::get().s_python_function_axvline, + args, kwargs); + + Py_DECREF(args); + Py_DECREF(kwargs); + + if (!res) + throw std::runtime_error("Call to axvline() failed."); Py_DECREF(res); } From 3ab7ce215e07cc1189289c06abb0beccb86e1f8f Mon Sep 17 00:00:00 2001 From: Pieter Date: Sun, 16 Dec 2018 15:50:06 +0100 Subject: [PATCH 2/2] Full colors parameters to plot and named_plot --- matplotlibcpp.h | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/matplotlibcpp.h b/matplotlibcpp.h index 3582666..d13300e 100644 --- a/matplotlibcpp.h +++ b/matplotlibcpp.h @@ -49,6 +49,7 @@ struct _interpreter { PyObject *s_python_function_ion; PyObject *s_python_function_ylim; PyObject *s_python_function_title; + PyObject *s_python_function_suptitle; PyObject *s_python_function_axis; PyObject *s_python_function_xlabel; PyObject *s_python_function_ylabel; @@ -152,6 +153,7 @@ struct _interpreter { s_python_function_legend = PyObject_GetAttrString(pymod, "legend"); s_python_function_ylim = PyObject_GetAttrString(pymod, "ylim"); s_python_function_title = PyObject_GetAttrString(pymod, "title"); + s_python_function_suptitle = PyObject_GetAttrString(pymod, "suptitle"); s_python_function_axis = PyObject_GetAttrString(pymod, "axis"); s_python_function_xlabel = PyObject_GetAttrString(pymod, "xlabel"); s_python_function_ylabel = PyObject_GetAttrString(pymod, "ylabel"); @@ -185,6 +187,7 @@ struct _interpreter { || !s_python_function_legend || !s_python_function_ylim || !s_python_function_title + || !s_python_function_suptitle || !s_python_function_axis || !s_python_function_xlabel || !s_python_function_ylabel @@ -219,6 +222,7 @@ struct _interpreter { || !PyFunction_Check(s_python_function_annotate) || !PyFunction_Check(s_python_function_ylim) || !PyFunction_Check(s_python_function_title) + || !PyFunction_Check(s_python_function_suptitle) || !PyFunction_Check(s_python_function_axis) || !PyFunction_Check(s_python_function_xlabel) || !PyFunction_Check(s_python_function_ylabel) @@ -471,23 +475,27 @@ bool named_hist(std::string label,const std::vector& y, long bins=10, s } template -bool plot(const std::vector& x, const std::vector& y, const std::string& s = "") +bool plot(const std::vector& x, const std::vector& y, const std::string& format = "", const std::string& color = "") { assert(x.size() == y.size()); PyObject* xarray = get_array(x); PyObject* yarray = get_array(y); - PyObject* pystring = PyString_FromString(s.c_str()); + PyObject* pyformat = PyString_FromString(format.c_str()); PyObject* plot_args = PyTuple_New(3); PyTuple_SetItem(plot_args, 0, xarray); PyTuple_SetItem(plot_args, 1, yarray); - PyTuple_SetItem(plot_args, 2, pystring); + PyTuple_SetItem(plot_args, 2, pyformat); - PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_plot, plot_args); + PyObject* kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "color", PyString_FromString(color.c_str())); + + PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_plot, plot_args, kwargs); Py_DECREF(plot_args); + Py_DECREF(kwargs); if(res) Py_DECREF(res); return res; @@ -656,10 +664,11 @@ bool errorbar(const std::vector &x, const std::vector &y, co } template -bool named_plot(const std::string& name, const std::vector& y, const std::string& format = "") +bool named_plot(const std::string& name, const std::vector& y, const std::string& format = "", const std::string& color = "") { PyObject* kwargs = PyDict_New(); PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); + PyDict_SetItemString(kwargs, "color", PyString_FromString(color.c_str())); PyObject* yarray = get_array(y); @@ -680,10 +689,11 @@ bool named_plot(const std::string& name, const std::vector& y, const st } template -bool named_plot(const std::string& name, const std::vector& x, const std::vector& y, const std::string& format = "") +bool named_plot(const std::string& name, const std::vector& x, const std::vector& y, const std::string& format = "", const std::string& color = "") { PyObject* kwargs = PyDict_New(); PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str())); + PyDict_SetItemString(kwargs, "color", PyString_FromString(color.c_str())); PyObject* xarray = get_array(x); PyObject* yarray = get_array(y); @@ -1023,6 +1033,19 @@ inline void title(const std::string &titlestr) Py_DECREF(res); } +inline void suptitle(const std::string &suptitlestr) +{ + PyObject* pysuptitlestr = PyString_FromString(suptitlestr.c_str()); + PyObject* args = PyTuple_New(1); + PyTuple_SetItem(args, 0, pysuptitlestr); + + PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_suptitle, args); + if(!res) throw std::runtime_error("Call to suptitle() failed."); + + Py_DECREF(args); + Py_DECREF(res); +} + inline void axis(const std::string &axisstr) { PyObject* str = PyString_FromString(axisstr.c_str()); @@ -1131,9 +1154,6 @@ inline void axhline(const double y = 0, const std::string& linestyle = "", const PyObject *args = PyTuple_New(3); PyObject *kwargs = PyDict_New(); - PyObject *pylinestyle = PyString_FromString(linestyle.c_str()); - PyObject *pycolor = PyString_FromString(color.c_str()); - PyDict_SetItemString(kwargs, "linestyle", PyString_FromString(linestyle.c_str())); PyDict_SetItemString(kwargs, "color", PyString_FromString(color.c_str())); @@ -1225,7 +1245,7 @@ inline void clf() { Py_DECREF(res); } - inline void ion() { +inline void ion() { PyObject *res = PyObject_CallObject( detail::_interpreter::get().s_python_function_ion, detail::_interpreter::get().s_python_empty_tuple);