@@ -31,6 +31,7 @@ namespace matplotlibcpp {
3131 PyObject *s_python_function_ylabel;
3232 PyObject *s_python_function_grid;
3333 PyObject *s_python_function_clf;
34+ PyObject *s_python_function_errorbar;
3435 PyObject *s_python_empty_tuple;
3536 PyObject *s_python_function_annotate;
3637
@@ -79,6 +80,7 @@ namespace matplotlibcpp {
7980 s_python_function_save = PyObject_GetAttrString (pylabmod, " savefig" );
8081 s_python_function_annotate = PyObject_GetAttrString (pymod," annotate" );
8182 s_python_function_clf = PyObject_GetAttrString (pymod, " clf" );
83+ s_python_function_errorbar = PyObject_GetAttrString (pymod, " errorbar" );
8284
8385 if ( !s_python_function_show
8486 || !s_python_function_figure
@@ -95,6 +97,7 @@ namespace matplotlibcpp {
9597 || !s_python_function_save
9698 || !s_python_function_clf
9799 || !s_python_function_annotate
100+ || !s_python_function_errorbar
98101 ) { throw std::runtime_error (" Couldn't find required function!" ); }
99102
100103 if ( !PyFunction_Check (s_python_function_show)
@@ -112,6 +115,7 @@ namespace matplotlibcpp {
112115 || !PyFunction_Check (s_python_function_xlim)
113116 || !PyFunction_Check (s_python_function_save)
114117 || !PyFunction_Check (s_python_function_clf)
118+ || !PyFunction_Check (s_python_function_errorbar)
115119 ) { throw std::runtime_error (" Python object is unexpectedly not a PyFunction." ); }
116120
117121 s_python_empty_tuple = PyTuple_New (0 );
@@ -264,6 +268,44 @@ namespace matplotlibcpp {
264268 return res;
265269 }
266270
271+ template <typename NumericX, typename NumericY>
272+ bool errorbar (const std::vector<NumericX> &x, const std::vector<NumericY> &y, const std::vector<NumericX> &yerr, const std::string &s = " " ) {
273+ assert (x.size () == y.size ());
274+
275+ PyObject *kwargs = PyDict_New ();
276+ PyObject *xlist = PyList_New (x.size ());
277+ PyObject *ylist = PyList_New (y.size ());
278+ PyObject *yerrlist = PyList_New (yerr.size ());
279+
280+ for (size_t i = 0 ; i < yerr.size (); ++i)
281+ PyList_SetItem (yerrlist, i, PyFloat_FromDouble (yerr.at (i)));
282+
283+ PyDict_SetItemString (kwargs, " yerr" , yerrlist);
284+
285+ PyObject *pystring = PyString_FromString (s.c_str ());
286+
287+ for (size_t i = 0 ; i < x.size (); ++i) {
288+ PyList_SetItem (xlist, i, PyFloat_FromDouble (x.at (i)));
289+ PyList_SetItem (ylist, i, PyFloat_FromDouble (y.at (i)));
290+ }
291+
292+ PyObject *plot_args = PyTuple_New (2 );
293+ PyTuple_SetItem (plot_args, 0 , xlist);
294+ PyTuple_SetItem (plot_args, 1 , ylist);
295+
296+ PyObject *res = PyObject_Call (detail::_interpreter::get ().s_python_function_errorbar , plot_args, kwargs);
297+
298+ Py_DECREF (kwargs);
299+ Py_DECREF (plot_args);
300+
301+ if (res)
302+ Py_DECREF (res);
303+ else
304+ throw std::runtime_error (" Call to errorbar() failed." );
305+
306+ return res;
307+ }
308+
267309 template <typename Numeric>
268310 bool named_plot (const std::string& name, const std::vector<Numeric>& y, const std::string& format = " " ) {
269311 PyObject* kwargs = PyDict_New ();
0 commit comments