Ver Fonte

Add support for ginput() function

Alex Dewar há 6 anos atrás
pai
commit
b1242079bc
1 ficheiros alterados com 38 adições e 0 exclusões
  1. 38 0
      matplotlibcpp.h

+ 38 - 0
matplotlibcpp.h

@@ -47,6 +47,7 @@ struct _interpreter {
     PyObject *s_python_function_legend;
     PyObject *s_python_function_xlim;
     PyObject *s_python_function_ion;
+    PyObject *s_python_function_ginput;
     PyObject *s_python_function_ylim;
     PyObject *s_python_function_title;
     PyObject *s_python_function_axis;
@@ -160,6 +161,7 @@ private:
         s_python_function_grid = PyObject_GetAttrString(pymod, "grid");
         s_python_function_xlim = PyObject_GetAttrString(pymod, "xlim");
         s_python_function_ion = PyObject_GetAttrString(pymod, "ion");
+        s_python_function_ginput = PyObject_GetAttrString(pymod, "ginput");
         s_python_function_save = PyObject_GetAttrString(pylabmod, "savefig");
         s_python_function_annotate = PyObject_GetAttrString(pymod,"annotate");
         s_python_function_clf = PyObject_GetAttrString(pymod, "clf");
@@ -191,6 +193,7 @@ private:
             || !s_python_function_grid
             || !s_python_function_xlim
             || !s_python_function_ion
+            || !s_python_function_ginput
             || !s_python_function_save
             || !s_python_function_clf
             || !s_python_function_annotate
@@ -225,6 +228,7 @@ private:
             || !PyFunction_Check(s_python_function_grid)
             || !PyFunction_Check(s_python_function_xlim)
             || !PyFunction_Check(s_python_function_ion)
+            || !PyFunction_Check(s_python_function_ginput)
             || !PyFunction_Check(s_python_function_save)
             || !PyFunction_Check(s_python_function_clf)
             || !PyFunction_Check(s_python_function_tight_layout)
@@ -1214,6 +1218,40 @@ inline void clf() {
     Py_DECREF(res);
 }
 
+inline std::vector<std::array<double, 2>> ginput(const int numClicks = 1, const std::map<std::string, std::string>& keywords = {})
+{
+    PyObject *args = PyTuple_New(1);
+    PyTuple_SetItem(args, 0, PyLong_FromLong(numClicks));
+
+    // construct keyword args
+    PyObject* kwargs = PyDict_New();
+    for(std::map<std::string, std::string>::const_iterator it = keywords.begin(); it != keywords.end(); ++it)
+    {
+        PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str()));
+    }
+
+    PyObject* res = PyObject_Call(
+        detail::_interpreter::get().s_python_function_ginput, args, kwargs);
+
+    Py_DECREF(kwargs);
+    Py_DECREF(args);
+    if (!res) throw std::runtime_error("Call to ginput() failed.");
+
+    const size_t len = PyList_Size(res);
+    std::vector<std::array<double, 2>> out;
+    out.reserve(len);
+    for (size_t i = 0; i < len; i++) {
+        PyObject *current = PyList_GetItem(res, i);
+        std::array<double, 2> position;
+        position[0] = PyFloat_AsDouble(PyTuple_GetItem(current, 0));
+        position[1] = PyFloat_AsDouble(PyTuple_GetItem(current, 1));
+        out.push_back(position);
+    }
+    Py_DECREF(res);
+
+    return out;
+}
+
 // Actually, is there any reason not to call this automatically for every plot?
 inline void tight_layout() {
     PyObject *res = PyObject_CallObject(