@@ -20,6 +20,7 @@ namespace matplotlibcpp {
2020 PyObject *s_python_function_save;
2121 PyObject *s_python_function_figure;
2222 PyObject *s_python_function_plot;
23+ PyObject *s_python_function_subplot;
2324 PyObject *s_python_function_legend;
2425 PyObject *s_python_function_xlim;
2526 PyObject *s_python_function_ylim;
@@ -32,8 +33,8 @@ namespace matplotlibcpp {
3233
3334 /* For now, _interpreter is implemented as a singleton since its currently not possible to have
3435 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+
3738 http://bytes.com/topic/python/answers/793370-multiple-independent-python-interpreters-c-c-program
3839 */
3940
@@ -44,12 +45,12 @@ namespace matplotlibcpp {
4445
4546 private:
4647 _interpreter () {
47- char name[] = " plotting" ; // silence compiler warning abount const strings
48+ char name[] = " plotting" ; // silence compiler warning about const strings
4849 Py_SetProgramName (name); // optional but recommended
4950 Py_Initialize ();
5051
5152 PyObject* pyplotname = PyString_FromString (" matplotlib.pyplot" );
52- PyObject* pylabname = PyString_FromString (" pylab" );
53+ PyObject* pylabname = PyString_FromString (" pylab" );
5354 if (!pyplotname || !pylabname) { throw std::runtime_error (" couldnt create string" ); }
5455
5556 PyObject* pymod = PyImport_Import (pyplotname);
@@ -63,6 +64,7 @@ namespace matplotlibcpp {
6364 s_python_function_show = PyObject_GetAttrString (pymod, " show" );
6465 s_python_function_figure = PyObject_GetAttrString (pymod, " figure" );
6566 s_python_function_plot = PyObject_GetAttrString (pymod, " plot" );
67+ s_python_function_subplot = PyObject_GetAttrString (pymod, " subplot" );
6668 s_python_function_legend = PyObject_GetAttrString (pymod, " legend" );
6769 s_python_function_ylim = PyObject_GetAttrString (pymod, " ylim" );
6870 s_python_function_title = PyObject_GetAttrString (pymod, " title" );
@@ -71,36 +73,37 @@ namespace matplotlibcpp {
7173 s_python_function_ylabel = PyObject_GetAttrString (pymod, " ylabel" );
7274 s_python_function_grid = PyObject_GetAttrString (pymod, " grid" );
7375 s_python_function_xlim = PyObject_GetAttrString (pymod, " xlim" );
74-
7576 s_python_function_save = PyObject_GetAttrString (pylabmod, " savefig" );
7677
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
8383 || !s_python_function_ylim
8484 || !s_python_function_title
8585 || !s_python_function_axis
8686 || !s_python_function_xlabel
8787 || !s_python_function_ylabel
8888 || !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!" ); }
9193
92- if (!PyFunction_Check (s_python_function_show)
93- || !PyFunction_Check (s_python_function_save)
94+ if ( !PyFunction_Check (s_python_function_show)
9495 || !PyFunction_Check (s_python_function_figure)
9596 || !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)
99100 || !PyFunction_Check (s_python_function_title)
100101 || !PyFunction_Check (s_python_function_axis)
101102 || !PyFunction_Check (s_python_function_xlabel)
102103 || !PyFunction_Check (s_python_function_ylabel)
103104 || !PyFunction_Check (s_python_function_grid)
105+ || !PyFunction_Check (s_python_function_xlim)
106+ || !PyFunction_Check (s_python_function_save)
104107 )
105108 { throw std::runtime_error (" Python object is unexpectedly not a PyFunction." ); }
106109
@@ -113,8 +116,6 @@ namespace matplotlibcpp {
113116 };
114117 }
115118
116-
117-
118119 template <typename Numeric>
119120 bool plot (const std::vector<Numeric> &x, const std::vector<Numeric> &y, const std::map<std::string, std::string>& keywords)
120121 {
@@ -153,7 +154,6 @@ namespace matplotlibcpp {
153154 return res;
154155 }
155156
156-
157157 template <typename NumericX, ty
67ED
pename NumericY>
158158 bool plot (const std::vector<NumericX>& x, const std::vector<NumericY>& y, const std::string& s = " " )
159159 {
@@ -183,7 +183,6 @@ namespace matplotlibcpp {
183183 return res;
184184 }
185185
186-
187186 template <typename Numeric>
188187 bool named_plot (const std::string& name, const std::vector<Numeric>& x, const std::vector<Numeric>& y, const std::string& format = " " ) {
189188 PyObject* kwargs = PyDict_New ();
@@ -223,7 +222,7 @@ namespace matplotlibcpp {
223222 }
224223
225224
226- inline void legend () {
225+ inline void legend () {
227226 PyObject* res = PyObject_CallObject (detail::_interpreter::get ().s_python_function_legend , detail::_interpreter::get ().s_python_empty_tuple );
228227 if (!res) throw std::runtime_error (" Call to legend() failed." );
229228
@@ -266,7 +265,20 @@ namespace matplotlibcpp {
266265 Py_DECREF (res);
267266 }
268267
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+
270282 inline void title (const std::string &titlestr)
271283 {
272284 PyObject* pytitlestr = PyString_FromString (titlestr.c_str ());
@@ -291,8 +303,6 @@ namespace matplotlibcpp {
291303 // if PyDeCRFF, the function doesn't work on Mac OS
292304 }
293305
294-
295-
296306 inline void xlabel (const std::string &str)
297307 {
298308 PyObject* pystr = PyString_FromString (str.c_str ());
@@ -330,8 +340,6 @@ namespace matplotlibcpp {
330340 // if PyDeCRFF, the function doesn't work on Mac OS
331341 }
332342
333-
334-
335343 inline void show ()
336344 {
337345 PyObject* res = PyObject_CallObject (detail::_interpreter::get ().s_python_function_show , detail::_interpreter::get ().s_python_empty_tuple );
@@ -368,7 +376,7 @@ namespace matplotlibcpp {
368376 template <typename T>
369377 struct is_callable_impl <false , T>
370378 {
371- typedef is_function<T> type;
379+ typedef is_function<T> type;
372380 }; // a non-object is callable iff it is a function
373381
374382 template <typename T>
@@ -452,10 +460,10 @@ namespace matplotlibcpp {
452460
453461 if (begin (ticks) == end (ticks)) return true ;
454462
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,
456464 // but all values have to be convertible to double anyways
457465 std::vector<double > y;
458- for (auto x : ticks) y.push_back (f (x));
466+ for (auto x : ticks) y.push_back (f (x));
459467 return plot_impl<std::false_type>()(ticks,y,format);
460468 }
461469 };
@@ -493,7 +501,4 @@ namespace matplotlibcpp {
493501
494502#endif
495503
496-
497-
498-
499504}
0 commit comments