@@ -20,6 +20,7 @@ namespace matplotlibcpp {
20
20
PyObject *s_python_function_save;
21
21
PyObject *s_python_function_figure;
22
22
PyObject *s_python_function_plot;
23
+ PyObject *s_python_function_subplot;
23
24
PyObject *s_python_function_legend;
24
25
PyObject *s_python_function_xlim;
25
26
PyObject *s_python_function_ylim;
@@ -32,8 +33,8 @@ namespace matplotlibcpp {
32
33
33
34
/* For now, _interpreter is implemented as a singleton since its currently not possible to have
34
35
multiple independent embedded python interpreters without patching the python source code
35
- or starting a seperate process for each.
36
-
36
+ or starting a separate process for each.
37
+
37
38
http://bytes.com/topic/python/answers/793370-multiple-independent-python-interpreters-c-c-program
38
39
*/
39
40
@@ -44,12 +45,12 @@ namespace matplotlibcpp {
44
45
45
46
private:
46
47
_interpreter () {
47
- char name[] = " plotting" ; // silence compiler warning abount const strings
48
+ char name[] = " plotting" ; // silence compiler warning about const strings
48
49
Py_SetProgramName (name); // optional but recommended
49
50
Py_Initialize ();
50
51
51
52
PyObject* pyplotname = PyString_FromString (" matplotlib.pyplot" );
52
- PyObject* pylabname = PyString_FromString (" pylab" );
53
+ PyObject* pylabname = PyString_FromString (" pylab" );
53
54
if (!pyplotname || !pylabname) { throw std::runtime_error (" couldnt create string" ); }
54
55
55
56
PyObject* pymod = PyImport_Import (pyplotname);
@@ -63,6 +64,7 @@ namespace matplotlibcpp {
63
64
s_python_function_show = PyObject_GetAttrString (pymod, " show" );
64
65
s_python_function_figure = PyObject_GetAttrString (pymod, " figure" );
65
66
s_python_function_plot = PyObject_GetAttrString (pymod, " plot" );
67
+ s_python_function_subplot = PyObject_GetAttrString (pymod, " subplot" );
66
68
s_python_function_legend = PyObject_GetAttrString (pymod, " legend" );
67
69
s_python_function_ylim = PyObject_GetAttrString (pymod, " ylim" );
68
70
s_python_function_title = PyObject_GetAttrString (pymod, " title" );
@@ -71,36 +73,37 @@ namespace matplotlibcpp {
71
73
s_python_function_ylabel = PyObject_GetAttrString (pymod, " ylabel" );
72
74
s_python_function_grid = PyObject_GetAttrString (pymod, " grid" );
73
75
s_python_function_xlim = PyObject_GetAttrString (pymod, " xlim" );
74
-
75
76
s_python_function_save = PyObject_GetAttrString (pylabmod, " savefig" );
76
77
77
- if (!s_python_function_show
78
- || !s_python_function_save
79
- || !s_python_function_figure
80
- || !s_python_function_plot
81
- || !s_python_function_legend
82
- || !s_python_function_xlim
78
+ if ( !s_python_function_show
79
+ || !s_python_function_figure
80
+ || !s_python_function_plot
81
+ || !s_python_function_subplot
82
+ || !s_python_function_legend
83
83
|| !s_python_function_ylim
84
84
|| !s_python_function_title
85
85
|| !s_python_function_axis
86
86
|| !s_python_function_xlabel
87
87
|| !s_python_function_ylabel
88
88
|| !s_python_function_grid
89
- )
90
- { throw std::runtime_error (" Couldnt find required function!" ); }
89
+ || !s_python_function_xlim
90
+ || !s_python_function_save
91
+ )
92
+ { throw std::runtime_error (" Couldn't find required function!" ); }
91
93
92
- if (!PyFunction_Check (s_python_function_show)
93
- || !PyFunction_Check (s_python_function_save)
94
+ if ( !PyFunction_Check (s_python_function_show)
94
95
|| !PyFunction_Check (s_python_function_figure)
95
96
|| !PyFunction_Check (s_python_function_plot)
96
- || !PyFunction_Check (s_python_function_legend )
97
- || !PyFunction_Check (s_python_function_xlim )
98
- || !PyFunction_Check (s_python_function_ylim)
97
+ || !PyFunction_Check (s_python_function_subplot )
98
+ || !PyFunction_Check (s_python_function_legend )
99
+ || !PyFunction_Check (s_python_function_ylim)
99
100
|| !PyFunction_Check (s_python_function_title)
100
101
|| !PyFunction_Check (s_python_function_axis)
101
102
|| !PyFunction_Check (s_python_function_xlabel)
102
103
|| !PyFunction_Check (s_python_function_ylabel)
103
104
|| !PyFunction_Check (s_python_function_grid)
105
+ || !PyFunction_Check (s_python_function_xlim)
106
+ || !PyFunction_Check (s_python_function_save)
104
107
)
105
108
{ throw std::runtime_error (" Python object is unexpectedly not a PyFunction." ); }
106
109
@@ -113,8 +116,6 @@ namespace matplotlibcpp {
113
116
};
114
117
}
115
118
116
-
117
-
118
119
template <typename Numeric>
119
120
bool plot (const std::vector<Numeric> &x, const std::vector<Numeric> &y, const std::map<std::string, std::string>& keywords)
120
121
{
@@ -153,7 +154,6 @@ namespace matplotlibcpp {
153
154
return res;
154
155
}
155
156
156
-
157
157
template <typename NumericX, typename NumericY>
158
158
bool plot (const std::vector<NumericX>& x, const std::vector<NumericY>& y, const std::string& s = " " )
159
159
{
@@ -183,7 +183,6 @@ namespace matplotlibcpp {
183
183
return res;
184
184
}
185
185
186
-
187
186
template <typename Numeric>
188
187
bool named_plot (const std::string& name, const std::vector<Numeric>& x, const std::vector<Numeric>& y, const std::string& format = " " ) {
189
188
PyObject* kwargs = PyDict_New ();
@@ -223,7 +222,7 @@ namespace matplotlibcpp {
223
222
}
224
223
225
224
226
- inline void legend () {
225
+ inline void legend () {
227
226
PyObject* res = PyObject_CallObject (detail::_interpreter::get ().s_python_function_legend , detail::_interpreter::get ().s_python_empty_tuple );
228
227
if (!res) throw std::runtime_error (" Call to legend() failed." );
229
228
@@ -266,7 +265,20 @@ namespace matplotlibcpp {
266
265
Py_DECREF (res);
267
266
}
268
267
269
-
268
+ inline void subplot (long nrows, long ncols, long plot_number) {
269
+ // construct positional args
270
+ PyObject* args = PyTuple_New (3 );
271
+ PyTuple_SetItem (args, 0 , PyFloat_FromDouble (nrows));
272
+ PyTuple_SetItem (args, 1 , PyFloat_FromDouble (ncols));
273
+ PyTuple_SetItem (args, 2 , PyFloat_FromDouble (plot_number));
274
+
275
+ PyObject* res = PyObject_CallObject (detail::_interpreter::get ().s_python_function_subplot , args);
276
+ if (!res) throw std::runtime_error (" Call to subplot() failed." );
277
+
278
+ Py_DECREF (args);
279
+ Py_DECREF (res);
280
+ }
281
+
270
282
inline void title (const std::string &titlestr)
271
283
{
272
284
PyObject* pytitlestr = PyString_FromString (titlestr.c_str ());
@@ -291,8 +303,6 @@ namespace matplotlibcpp {
291
303
// if PyDeCRFF, the function doesn't work on Mac OS
292
304
}
293
305
294
-
295
-
296
306
inline void xlabel (const std::string &str)
297
307
{
298
308
PyObject* pystr = PyString_FromString (str.c_str ());
@@ -330,8 +340,6 @@ namespace matplotlibcpp {
330
340
// if PyDeCRFF, the function doesn't work on Mac OS
331
341
}
332
342
333
-
334
-
335
343
inline void show ()
336
344
{
337
345
PyObject* res = PyObject_CallObject (detail::_interpreter::get ().s_python_function_show , detail::_interpreter::get ().s_python_empty_tuple );
@@ -368,7 +376,7 @@ namespace matplotlibcpp {
368
376
template <typename T>
369
377
struct is_callable_impl <false , T>
370
378
{
371
- typedef is_function<T> type;
379
+ typedef is_function<T> type;
372
380
}; // a non-object is callable iff it is a function
373
381
374
382
template <typename T>
@@ -452,10 +460,10 @@ namespace matplotlibcpp {
452
460
453
461
if (begin (ticks) == end (ticks)) return true ;
454
462
455
- // We could use additional meta-programming to deduce the correct element type of y,
463
+ // We could use additional meta-programming to deduce the correct element type of y,
456
464
// but all values have to be convertible to double anyways
457
465
std::vector<double > y;
458
- for (auto x : ticks) y.push_back (f (x));
466
+ for (auto x : ticks) y.push_back (f (x));
459
467
return plot_impl<std::false_type>()(ticks,y,format);
460
468
}
461
469
};
@@ -493,7 +501,4 @@ namespace matplotlibcpp {
493
501
494
502
#endif
495
503
496
-
497
-
498
-
499
504
}
0 commit comments