@@ -20,6 +20,7 @@ namespace matplotlibcpp {
2020 PyObject *s_python_function_save;
2121 PyObject *s_
10BC0
python_function_figure;
2222 PyObject *s_python_function_plot;
23+ PyObject *s_python_function_hist;
2324 PyObject *s_python_function_subplot;
2425 PyObject *s_python_function_legend;
2526 PyObject *s_python_function_xlim;
@@ -30,11 +31,11 @@ namespace matplotlibcpp {
3031 PyObject *s_python_function_ylabel;
3132 PyObject *s_python_function_grid;
3233 PyObject *s_python_empty_tuple;
34+ PyObject *s_python_function_annotate;
3335
3436 /* For now, _interpreter is implemented as a singleton since its currently not possible to have
3537 multiple independent embedded python interpreters without patching the python source code
3638 or starting a separate process for each.
37-
3839 http://bytes.com/topic/python/answers/793370-multiple-independent-python-interpreters-c-c-program
3940 */
4041
@@ -64,6 +65,7 @@ namespace matplotlibcpp {
6465 s_python_function_show = PyObject_GetAttrString (pymod, " show" );
6566 s_python_function_figure = PyObject_GetAttrString (pymod, " figure" );
6667 s_python_function_plot = PyObject_GetAttrString (pymod, " plot" );
68+ s_python_function_hist = PyObject_GetAttrString (pymod," hist" );
6769 s_python_function_subplot = PyObject_GetAttrString (pymod, " subplot" );
6870 s_python_function_legend = PyObject_GetAttrString (pymod, " legend" );
6971 s_python_function_ylim = PyObject_GetAttrString (pymod, " ylim" );
@@ -74,12 +76,13 @@ namespace matplotlibcpp {
7476 s_python_function_grid = PyObject_GetAttrString (pymod, " grid" );
7577 s_python_function_xlim = PyObject_GetAttrString (pymod, " xlim" );
7678 s_python_function_save = PyObject_GetAttrString (pylabmod, " savefig" );
79+ s_python_function_annotate = PyObject_GetAttrString (pymod," annotate" );
7780
7881 if ( !s_python_function_show
7982 || !s_python_function_figure
8083 || !s_python_function_plot
8184 || !s_python_function_subplot
82- || !s_python_function_legend
85+ || !s_python_function_legend
8386 || !s_python_function_ylim
8487 || !s_python_function_title
8588 || !s_python_function_axis
@@ -88,14 +91,16 @@ namespace matplotlibcpp {
8891 || !s_python_function_grid
8992 || !s_python_function_xlim
9093 || !s_python_function_save
94+ || !s_python_function_annotate
9195 )
9296 { throw std::runtime_error (" Couldn't find required function!" ); }
9397
9498 if ( !PyFunction_Check (s_python_function_show)
9599 || !PyFunction_Check (s_python_function_figure)
96100 || !PyFunction_Check (s_python_function_plot)
97101 || !PyFunction_Check (s_python_function_subplot)
98- || !PyFunction_Check (s_python_function_legend)
102+ || !PyFunction_Check (s_python_function_legend)
103+ || !PyFunction_Check (s_python_function_annotate)
99104 || !PyFunction_Check (s_python_function_ylim)
100105 || !PyFunction_Check (s_python_function_title)
101106 || !PyFunction_Check (s_python_function_axis)
@@ -115,6 +120,30 @@ namespace matplotlibcpp {
115120 }
116121 };
117122 }
123+
124+ bool annotate (std::string annotation, double x, double y)
125+ {
126+ PyObject * xy = PyTuple_New (2 );
127+ PyObject * str = PyString_FromString (annotation.c_str ());
128+
129+ PyTuple_SetItem (xy,0 ,PyFloat_FromDouble (x));
130+ PyTuple_SetItem (xy,1 ,PyFloat_FromDouble (y));
131+
132+ PyObject* kwargs = PyDict_New ();
133+ PyDict_SetItemString (kwargs, " xy" , xy);
134+
135+ PyObject* args = PyTuple_New (1 );
136+ PyTuple_SetItem (args, 0 , str);
137+
138+ PyObject* res = PyObject_Call (detail::_interpreter::get ().s_python_function_annotate , args, kwargs);
139+
140+ Py_DECREF (args);
141+ Py_DECREF (kwargs);
142+
143+ if (res) Py_DECREF (res);
144+
145+ return res;
146+ }
118147
119148 template <typename Numeric>
120149 bool plot (const std::vector<Numeric> &x, const std::vector<Numeric> &y, const std::map<std::string, std::string>& keywords)
@@ -154,6 +183,61 @@ namespace matplotlibcpp {
154183 return res;
155184 }
156185
186+ template < typename Numeric>
187+ bool hist (const std::vector<Numeric>& y, long bins=10 ,std::string color=" b" , double alpha=1.0 ){
188+
189+ PyObject* ylist = PyList_New (y.size ());
190+
191+ PyObject* kwargs = PyDict_New ();
192+ PyDict_SetItemString (kwargs, " bins" , PyLong_FromLong (bins));
193+ PyDict_SetItemString (kwargs, " color" , PyString_FromString (color.c_str ()));
194+ PyDict_SetItemString (kwargs, " alpha" , PyFloat_FromDouble (alpha));
195+
196+ for (size_t i = 0 ; i < y.size (); ++i) {
197+ PyList_SetItem (ylist, i, PyFloat_FromDouble (y.at (i)));
198+ }
199+
200+ PyObject* plot_args = PyTuple_New (1 );
201+
202+ PyTuple_SetItem (plot_args, 0 , ylist);
203+
204+
205+ PyObject* res = PyObject_Call (detail::_interpreter::get ().s_python_function_hist , plot_args, kwargs);
206+
207+
208+ Py_DECREF (plot_args);
209+ Py_DECREF (kwargs);
210+ if (res) Py_DECREF (res);
211+
212+ return res;
213+ }
214+ template < typename Numeric>
215+ bool named_hist (std::string label,const std::vector<Numeric>& y, long bins=10 ,std::string color=" b" , double alpha=1.0 ){
216+
217+ PyObject* ylist = PyList_New (y.size ());
218+ PyObject* kwargs = PyDict_New ();
219+ PyDict_SetItemString (kwargs, " label" , PyString_FromString (label.c_str ()));
220+ PyDict_SetItemString (kwargs, " bins" , PyLong_FromLong (bins));
221+ PyDict_SetItemString (kwargs, " color" , PyString_FromString (color.c_str ()));
222+ PyDict_SetItemString (kwargs, " alpha" , PyFloat_FromDouble (alpha));
223+
224+ for (size_t i = 0 ; i < y.size (); ++i) {
225+ PyList_SetItem (ylist, i, PyFloat_FromDouble (y.at (i)));
226+ }
227+
228+ PyObject* plot_args = PyTuple_New (1 );
229+ PyTuple_SetItem (plot_args, 0 , ylist);
230+
231+ PyObject* res = PyObject_Call (detail::_interpreter::get ().s_python_function_hist , plot_args, kwargs);
232+
233+
234+ Py_DECREF (plot_args);
235+ Py_DECREF (kwargs);
236+ if (res) Py_DECREF (res);
237+
238+ return res;
239+ }
240+
157241 template <typename NumericX, typename NumericY>
158242 bool plot (const std::vector<NumericX>& x, const std::vector<NumericY>& y, const std::string& s = " " )
159243 {
@@ -175,8 +259,31 @@ namespace matplotlibcpp {
175259
176260 PyObject* res = PyObject_CallObject (detail::_interpreter::get ().s_python_function_plot , plot_args);
177261
178- Py_DECREF (xlist);
179- Py_DECREF (ylist);
262+ Py_DECREF (plot_args);
263+ if (res) Py_DECREF (res);
264+
265+ return res;
266+ }
267+ template <typename Numeric>
268+ bool named_plot (const std::string& name, const std::vector<Numeric>& y, const std::string& format = " " ) {
269+ PyObject* kwargs = PyDict_New ();
270+ PyDict_SetItemString (kwargs, " label" , PyString_FromString (name.c_str ()));
271+
272+ PyObject* ylist = PyList_New (y.size ());
273+ PyObject* pystring = PyString_FromString (format.c_str ());
274+
275+ for (size_t i = 0 ; i < y.size (); ++i) {
276+ PyList_SetItem (ylist, i, PyFloat_FromDouble (y.at (i)));
277+ }
278+
279+ PyObject* plot_args = PyTuple_New (2 );
280+
281+ PyTuple_SetItem (plot_args, 0 , ylist);
282+ PyTuple_SetItem (plot_args, 1 , pystring);
283+
284+ PyObject* res = PyObject_Call (detail::_interpreter::get ().s_python_function_plot , plot_args, kwargs);
285+
286+ Py_DECREF (kwargs);
180287 Py_DECREF (plot_args);
181288 if (res) Py_DECREF (res);
182289
@@ -205,8 +312,6 @@ namespace matplotlibcpp {
205312 PyObject* res = PyObject_Call (detail::_interpreter::get ().s_python_function_plot , plot_args, kwargs);
206313
207314 Py_DECREF (kwargs);
208- Py_DECREF (xlist);
209- Py_DECREF (ylist);
210315 Py_DECREF (plot_args);
211316 if (res) Py_DECREF (res);
212317
@@ -221,7 +326,13 @@ namespace matplotlibcpp {
221326 return plot (x,y,format);
222327 }
223328
329+ inline void figure (){
330+ PyObject* res = PyObject_CallObject (detail::_interpreter::get ().s_python_function_figure , detail::_interpreter::get ().s_python_empty_tuple );
331+ if (!res) throw std::runtime_error (" Call to figure() failed." );
224332
333+ Py_DECREF (res);
334+
335+ }
225336 inline void legend () {
226337 PyObject* res = PyObject_CallObject (detail::_interpreter::get ().s_python_function_legend , detail::_interpreter::get ().s_python_empty_tuple );
227338 if (!res) throw std::runtime_error (" Call to legend() failed." );
@@ -242,7 +353,6 @@ namespace matplotlibcpp {
242353 PyObject* res = PyObject_CallObject (detail::_interpreter::get ().s_python_function_ylim , args);
243354 if (!res) throw std::runtime_error (" Call to ylim() failed." );
244355
245- Py_DECREF (list);
246356 Py_DECREF (args);
247357 Py_DECREF (res);
248358 }
@@ -260,10 +370,41 @@ namespace matplotlibcpp {
260370 PyObject* res = PyObject_CallObject (detail::_interpreter::get ().s_python_function_xlim , args);
261371 if (!res) throw std::runtime_error (" Call to xlim() failed." );
262372
263- Py_DECREF (list);
264373 Py_DECREF (args);
265374 Py_DECREF (res);
266375 }
376+
377+
378+ double * xlim ()
379+ {
380+ PyObject* args = PyTuple_New (0 );
381+ PyObject* res = PyObject_CallObject (detail::_interpreter::get ().s_python_function_xlim , args);
382+ PyObject * left = PyTuple_GetItem (res,0 );
383+ PyObject * right = PyTuple_GetItem (res,1 );
384+ double * arr = new double [2 ];
385+ arr[0 ] = PyFloat_AsDouble (left);
386+ arr[1 ] = PyFloat_AsDouble (right);
387+
388+ if (!res) throw std::runtime_error (" Call to xlim() failed." );
389+ Py_DECREF (res);
<
5074
code> 390+ return arr;
391+ }
392+
393+
394+ double * ylim ()
395+ {
396+ PyObject* args = PyTuple_New (0 );
397+ PyObject* res = PyObject_CallObject (detail::_interpreter::get ().s_python_function_ylim , args);
398+ PyObject * left = PyTuple_GetItem (res,0 );
399+ PyObject * right = PyTuple_GetItem (res,1 );
400+ double * arr = new double [2 ];
401+ arr[0 ] = PyFloat_AsDouble (left);
402+ arr[1 ] = PyFloat_AsDouble (right);
403+
404+ if (!res) throw std::runtime_error (" Call to ylim() failed." );
405+ Py_DECREF (res);
406+ return arr;
407+ }
267408
268409 inline void subplot (long nrows, long ncols, long plot_number) {
269410 // construct positional args
0 commit comments