@@ -102,6 +102,7 @@ struct _interpreter {
102
102
PyObject *s_python_function_colorbar;
103
103
PyObject *s_python_function_subplots_adjust;
104
104
PyObject *s_python_function_rcparams;
105
+ PyObject *s_python_function_spy;
105
106
106
107
/* For now, _interpreter is implemented as a singleton since its currently not possible to have
107
108
multiple independent embedded python interpreters without patching the python source code
@@ -276,6 +277,7 @@ struct _interpreter {
276
277
s_python_function_colorbar = PyObject_GetAttrString(pymod, "colorbar");
277
278
s_python_function_subplots_adjust = safe_import(pymod,"subplots_adjust");
278
279
s_python_function_rcparams = PyObject_GetAttrString(pymod, "rcParams");
280
+ s_python_function_spy = PyObject_GetAttrString(pymod, "spy");
279
281
#ifndef WITHOUT_NUMPY
280
282
s_python_function_imshow = safe_import(pymod, "imshow");
281
283
#endif
@@ -348,11 +350,11 @@ template <> struct select_npy_type<uint64_t> { const static NPY_TYPES type = NPY
348
350
349
351
// Sanity checks; comment them out or change the numpy type below if you're compiling on
350
352
// a platform where they don't apply
351
- // static_assert(sizeof(long long) == 8);
352
- // template <> struct select_npy_type<long long> { const static NPY_TYPES type = NPY_INT64; };
353
- // static_assert(sizeof(unsigned long long) == 8);
354
- // template <> struct select_npy_type<unsigned long long> { const static NPY_TYPES type = NPY_UINT64; };
355
- // TODO: add int, long, etc.
353
+ static_assert(sizeof(long long) == 8);
354
+ template <> struct select_npy_type<long long> { const static NPY_TYPES type = NPY_INT64; };
355
+ static_assert(sizeof(unsigned long long) == 8);
356
+ template <> struct select_npy_type<unsigned long long> { const static NPY_TYPES type = NPY_UINT64; };
357
+ TODO: add int, long, etc.
356
358
357
359
template<typename Numeric>
358
360
PyObject* get_array(const std::vector<Numeric>& v)
@@ -621,8 +623,37 @@ void contour(const std::vector<::std::vector<Numeric>> &x,
621
623
622
624
Py_DECREF(args);
623
625
Py_DECREF(kwargs);
624
- if (res)
625
- Py_DECREF(res);
626
+ if (res) Py_DECREF(res);
627
+ }
628
+
629
+ template <typename Numeric>
630
+ void spy(const std::vector<::std::vector<Numeric>> &x,
631
+ const double markersize = -1, // -1 for default matplotlib size
632
+ const std::map<std::string, std::string> &keywords = {})
633
+ {
634
+ detail::_interpreter::get();
635
+
636
+ PyObject *xarray = detail::get_2darray(x);
637
+
638
+ PyObject *kwargs = PyDict_New();
639
+ if (markersize != -1) {
640
+ PyDict_SetItemString(kwargs, "markersize", PyFloat_FromDouble(markersize));
641
+ }
642
+ for (std::map<std::string, std::string>::const_iterator it = keywords.begin();
643
+ it != keywords.end(); ++it) {
644
+ PyDict_SetItemString(kwargs, it->first.c_str(),
645
+ PyString_FromString(it->second.c_str()));
646
+ }
647
+
648
+ PyObject *plot_args = PyTuple_New(1);
649
+ PyTuple_SetItem(plot_args, 0, xarray);
650
+
651
+ PyObject *res = PyObject_Call(
652
+ detail::_interpreter::get().s_python_function_spy, plot_args, kwargs);
653
+
654
+ Py_DECREF(plot_args);
655
+ Py_DECREF(kwargs);
656
+ if (res) Py_DECREF(res);
626
657
}
627
658
#endif // WITHOUT_NUMPY
628
659
0 commit comments