@@ -17,6 +17,7 @@ namespace matplotlibcpp {
17
17
namespace detail {
18
18
struct _interpreter {
19
19
PyObject *s_python_function_show;
20
+ PyObject *s_python_function_save;
20
21
PyObject *s_python_function_figure;
21
22
PyObject *s_python_function_plot;
22
23
PyObject *s_python_function_legend;
@@ -42,12 +43,17 @@ namespace matplotlibcpp {
42
43
Py_SetProgramName (name); // optional but recommended
43
44
Py_Initialize ();
44
45
45
- PyObject* pyname = PyString_FromString (" matplotlib.pyplot" );
46
- if (!pyname) { throw std::runtime_error (" couldnt create string" ); }
46
+ PyObject* pyplotname = PyString_FromString (" matplotlib.pyplot" );
47
+ PyObject* pylabname = PyString_FromString (" pylab" );
48
+ if (!pyplotname || !pylabname) { throw std::runtime_error (" couldnt create string" ); }
47
49
48
- PyObject* pymod = PyImport_Import (pyname);
49
- Py_DECREF (pyname);
50
- if (!pymod) { throw std::runtime_error (" Error loading module!" ); }
50
+ PyObject* pymod = PyImport_Import (pyplotname);
51
+ Py_DECREF (pyplotname);
52
+ if (!pymod) { throw std::runtime_error (" Error loading module matplotlib.pyplot!" ); }
53
+
54
+ PyObject* pylabmod = PyImport_Import (pylabname);
55
+ Py_DECREF (pylabname);
56
+ if (!pymod) { throw std::runtime_error (" Error loading module pylab!" ); }
51
57
52
58
s_python_function_show = PyObject_GetAttrString (pymod, " show" );
53
59
s_python_function_figure = PyObject_GetAttrString (pymod, " figure" );
@@ -56,7 +62,10 @@ namespace matplotlibcpp {
56
62
s_python_function_ylim = PyObject_GetAttrString (pymod, " ylim" );
57
63
s_python_function_xlim = PyObject_GetAttrString (pymod, " xlim" );
58
64
65
+ s_python_function_save = PyObject_GetAttrString (pylabmod, " savefig" );
66
+
59
67
if (!s_python_function_show
68
+ || !s_python_function_save
60
69
|| !s_python_function_figure
61
70
|| !s_python_function_plot
62
71
|| !s_python_function_legend
@@ -65,6 +74,7 @@ namespace matplotlibcpp {
65
74
{ throw std::runtime_error (" Couldnt find required function!" ); }
66
75
67
76
if (!PyFunction_Check (s_python_function_show)
77
+ || !PyFunction_Check (s_python_function_save)
68
78
|| !PyFunction_Check (s_python_function_figure)
69
79
|| !PyFunction_Check (s_python_function_plot)
70
80
|| !PyFunction_Check (s_python_function_legend)
@@ -127,8 +137,6 @@ namespace matplotlibcpp {
127
137
{
128
138
assert (x.size () == y.size ());
129
139
130
- // std::string format(s);
131
-
132
140
PyObject* xlist = PyList_New (x.size ());
133
141
PyObject* ylist = PyList_New (y.size ());
134
142
PyObject* pystring = PyString_FromString (s.c_str ());
@@ -192,25 +200,6 @@ namespace matplotlibcpp {
192
200
return plot (x,y,format);
193
201
}
194
202
195
- /*
196
- * This group of plot() functions is needed to support initializer lists, i.e. calling
197
- * plot( {1,2,3,4} )
198
- */
199
- bool plot (const std::vector<double >& x, const std::vector<double >& y, const std::string& format = " " ) {
200
- return plot<double ,double >(x,y,format);
201
- }
202
-
203
- bool plot (const std::vector<double >& y, const std::string& format = " " ) {
204
- return plot<double >(y,format);
205
- }
206
-
207
- bool plot (const std::vector<double >& x, const std::vector<double >& y, const std::map<std::string, std::string>& keywords) {
208
- return plot<double >(x,y,keywords);
209
- }
210
-
211
- bool named_plot (const std::string& name, const std::vector<double >& x, const std::vector<double >& y, const std::string& format = " " ) {
212
- return named_plot<double >(name,x,y,format);
213
- }
214
203
215
204
inline void legend () {
216
205
PyObject* res = PyObject_CallObject (detail::_interpreter::get ().s_python_function_legend , detail::_interpreter::get ().s_python_empty_tuple );
@@ -255,15 +244,31 @@ namespace matplotlibcpp {
255
244
Py_DECREF (res);
256
245
}
257
246
258
- inline void show () {
247
+ inline void show ()
248
+ {
259
249
PyObject* res = PyObject_CallObject (detail::_interpreter::get ().s_python_function_show , detail::_interpreter::get ().s_python_empty_tuple );
260
250
if (!res) throw std::runtime_error (" Call to show() failed." );
261
251
262
252
Py_DECREF (res);
263
253
}
264
254
255
+ inline void save (const std::string& filename)
256
+ {
257
+ PyObject* pyfilename = PyString_FromString (filename.c_str ());
258
+
259
+ PyObject* args = PyTuple_New (1 );
260
+ PyTuple_SetItem (args, 0 , pyfilename);
261
+
262
+ PyObject* res = PyObject_CallObject (detail::_interpreter::get ().s_python_function_save , args);
263
+ if (!res) throw std::runtime_error (" Call to save() failed." );
264
+
265
+ Py_DECREF (pyfilename);
266
+ Py_DECREF (args);
267
+ Py_DECREF (res);
268
+ }
269
+
265
270
#if __cplusplus > 199711L
266
- // C++11-exclusive content starts here, in particular the variadic plot()
271
+ // C++11-exclusive content starts here ( variadic plot() and initializer list support )
267
272
268
273
namespace detail {
269
274
template <typename T>
@@ -302,7 +307,7 @@ namespace matplotlibcpp {
302
307
struct is_callable
303
308
{
304
309
// dispatch to is_callable_impl<true, T> or is_callable_impl<false, T> depending on whether T is of class type or not
305
- typedef typename is_callable_impl<std::is_class<T>::value, T>::type type; // todo: restore remove_reference
310
+ typedef typename is_callable_impl<std::is_class<T>::value, T>::type type;
306
311
};
307
312
308
313
template <typename IsYDataCallable>
@@ -314,7 +319,7 @@ namespace matplotlibcpp {
314
319
template <typename IterableX, typename IterableY>
315
320
bool operator ()(const IterableX& x, const IterableY& y, const std::string& format)
316
321
{
317
- // It's annoying that we have to repeat the code of plot() above
322
+ // 2-phase lookup for distance, begin, end
318
323
using std::distance;
319
324
using std::begin;
320
325
using std::end;
@@ -378,6 +383,26 @@ namespace matplotlibcpp {
378
383
return detail::plot_impl<typename detail::is_callable<B>::type>()(a,b,format) && plot (args...);
379
384
}
380
385
386
+ /*
387
+ * This group of plot() functions is needed to support initializer lists, i.e. calling
388
+ * plot( {1,2,3,4} )
389
+ */
390
+ bool plot (const std::vector<double >& x, const std::vector<double >& y, const std::string& format = " " ) {
391
+ return plot<double ,double >(x,y,format);
392
+ }
393
+
394
+ bool plot (const std::vector<double >& y, const std::string& format = " " ) {
395
+ return plot<double >(y,format);
396
+ }
397
+
398
+ bool plot (const std::vector<double >& x, const std::vector<double >& y, const std::map<std::string, std::string>& keywords) {
399
+ return plot<double >(x,y,keywords);
400
+ }
401
+
402
+ bool named_plot (const std::string& name, const std::vector<double >& x, const std::vector<double >& y, const std::string& format = " " ) {
403
+ return named_plot<double >(name,x,y,format);
404
+ }
405
+
381
406
#endif
382
407
383
408
0 commit comments