@@ -93,6 +93,7 @@ struct _interpreter {
9393 PyObject *s_python_function_suptitle;
9494 PyObject *s_python_function_bar;
9595 PyObject *s_python_function_subplots_adjust;
96+ PyObject *s_python_function_imshow;
9697
9798 /* For now, _interpreter is implemented as a singleton since its currently not
9899 possible to have multiple independent embedded python interpreters without
@@ -227,28 +228,30 @@ struct _interpreter {
227228 s_python_function_bar = PyObject_GetAttrString (pymod, " bar" );
228229 s_python_function_subplots_adjust =
229230 PyObject_GetAttrString (pymod, " subplots_adjust" );
231+ s_python_function_imshow = PyObject_GetAttrString (pymod, " imshow" );
230232
231233 if (!s_python_function_show || !s_python_function_close ||
232234 !s_python_function_draw || !s_python_function_pause ||
233235 !s_python_function_figure || !s_python_function_fignum_exists ||
234236 !s_python_function_plot || !s_python_function_quiver ||
235- !s_python_function_contour || !s_python_function_semilogx ||
236- !s_python_function_semilogy || !s_python_function_loglog ||
237- !s_python_function_fill || !s_python_function_fill_between ||
238- !s_python_function_subplot || !s_python_function_legend ||
239- !s_python_function_ylim || !s_python_function_title ||
240- !s_python_function_axis || !s_python_function_xlabel ||
241- !s_python_function_ylabel || !s_python_function_xticks ||
242- !s_python_function_yticks || !s_python_function_xscale ||
243- !s_python_function_yscale || !s_python_function_grid ||
244- !s_python_function_xlim || !s_python_function_ion ||
245- !s_python_function_ginput || !s_python_function_save ||
246- !s_python_function_clf || !s_python_function_annotate ||
247- !s_python_function_errorbar || !s_python_function_errorbar ||
248- !s_python_function_tight_layout || !s_python_function_stem ||
249- !s_python_function_xkcd || !s_python_function_text ||
250- !s_python_function_suptitle || !s_python_function_bar ||
251- !s_python_function_subplots_adjust || !s_python_function_spy) {
237+ !s_python_function_contour ||
238+ !s_python_function_semilogx || !s_python_function_semilogy ||
239+ !s_python_function_loglog || !s_python_function_fill ||
240+ !s_python_function_fill_between || !s_python_function_subplot ||
241+ !s_python_function_legend || !s_python_function_ylim ||
242+ !s_python_function_title || !s_python_function_axis ||
243+ !s_python_function_xlabel || !s_python_function_ylabel ||
244+ !s_python_function_xticks || !s_python_function_yticks ||
245+ !s_python_function_xscale || !s_python_function_yscale ||
246+ !s_python_function_grid || !s_python_function_xlim ||
247+ !s_python_function_ion || !s_python_function_ginput ||
248+ !s_python_function_save || !s_python_function_clf ||
249+ !s_python_function_annotate || !s_python_function_errorbar ||
250+ !s_python_function_errorbar || !s_python_function_tight_layout ||
251+ !s_python_function_stem || !s_python_function_xkcd ||
252+ !s_python_function_text || !s_python_function_suptitle ||
253+ !s_python_function_bar || !s_python_function_subplots_adjust ||
254+ !s_python_function_spy || !s_python_function_imshow) {
252255 throw std::runtime_error (" Couldn't find required function!" );
253256 }
254257
@@ -292,7 +295,9 @@ struct _interpreter {
292295 !PyFunction_Check (s_python_function_text) ||
293296 !PyFunction_Check (s_python_function_suptitle) ||
294297 !PyFunction_Check (s_python_function_bar) ||
295- !PyFunction_Check (s_python_function_subplots_adjust)) {
298+ !PyFunction_Check (s_python_function_subplots_adjust) ||
299+ !PyFunction_Check (s_python_function_imshow)
300+ ) {
296301 throw std::runtime_error (
297302 " Python object is unexpectedly not a PyFunction." );
298303 }
@@ -303,24 +308,6 @@ struct _interpreter {
303308 ~_interpreter () { Py_Finalize (); }
304309};
305310
306- void process_keywords (PyObject *kwargs,
307- const std::map<std::string, std::string> &keywords) {
308- for (auto const &item : keywords) {
309- // check if the keyword is a number
310- try {
311- std::stringstream ss (item.second );
312- double d;
313- ss >> d;
314- PyDict_SetItemString (kwargs, item.first .c_str (), PyFloat_FromDouble (d));
315- }
316- // if its not, then leave it as string
317- catch (std::exception& e) {
318- PyDict_SetItemString (kwargs, item.first .c_str (),
319- PyString_FromString (item.second .c_str ()));
320- }
321- }
322- }
323-
324311} // end namespace detail
325312
326313// must be called before the first regular call to matplotlib to have any effect
@@ -676,6 +663,29 @@ bool semilogy(const VectorY &y,
676663 return semilogy (x, y, " " , keywords);
677664}
678665
666+ template <typename Matrix>
667+ void imshow (const Matrix& X, const std::map<std::string, std::string> &keywords = {}) {
668+ PyObject *Xarray = get_2darray (X);
669+
670+ PyObject *kwargs = PyDict_New ();
671+ for (std::map<std::string, std::string>::const_iterator it = keywords.begin ();
672+ it != keywords.end (); ++it) {
673+ PyDict_SetItemString (kwargs, it->first .c_str (),
674+ PyUnicode_FromString (it->second .c_str ()));
675+ }
676+
677+ PyObject *plot_args = PyTuple_New (1 );
678+ PyTuple_SetItem (plot_args, 0 , Xarray);
679+
680+ PyObject *res = PyObject_Call (
681+ detail::_interpreter::get ().s_python_function_imshow , plot_args, kwargs);
682+
683+ Py_DECREF (plot_args);
684+ Py_DECREF (kwargs);
685+ if (res)
686+ Py_DECREF (res);
687+ }
688+
679689// @brief plot_surface for datapoints (x_ij, y_ij, z_ij) with i,j = 0..n
680690// @param x The x values of the datapoints in a matrix
681691// @param y The y values of the datapoints in a matrix
@@ -1389,7 +1399,11 @@ inline void legend(const std::string &loc = "best",
13891399 }
13901400
13911401 // add other keywords
1392- detail::process_keywords (kwargs, keywords);
1402+ for (std::map<std::string, std::string>::const_iterator it = keywords.begin ();
1403+ it != keywords.end (); ++it) {
1404+ PyDict_SetItemString (kwargs, it->first .c_str (),
1405+ PyString_FromString (it->second .c_str ()));
1406+ }
13931407
13941408 PyObject *res =
13951409 PyObject_Call (detail::_interpreter::get ().s_python_function_legend ,
0 commit comments