From 3d1976bdd18350ca0a793b99a87da8d95c539931 Mon Sep 17 00:00:00 2001 From: Doodle1106 Date: Thu, 6 Jun 2019 17:39:41 +0800 Subject: [PATCH 1/2] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 338bea7..745b83e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,11 @@ +1. add 3D scatter plot; +2. add 3D line plot + + + + + + matplotlib-cpp ============== From 62623c64bf6b53636fce268d78a30b929b6bbba6 Mon Sep 17 00:00:00 2001 From: Doodle1106 Date: Thu, 6 Jun 2019 17:41:06 +0800 Subject: [PATCH 2/2] Update matplotlibcpp.h --- matplotlibcpp.h | 148 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/matplotlibcpp.h b/matplotlibcpp.h index 2797295..6e34d9f 100644 --- a/matplotlibcpp.h +++ b/matplotlibcpp.h @@ -500,6 +500,154 @@ void plot_surface(const std::vector<::std::vector> &x, if (res) Py_DECREF(res); } + +template +void scatter(const std::vector &x, + const std::vector &y, + const std::vector &z, + const int& size, const string& color) +{ + static PyObject *mpl_toolkitsmod = nullptr, *axis3dmod = nullptr; + if (!mpl_toolkitsmod) { + detail::_interpreter::get(); + + PyObject* mpl_toolkits = PyString_FromString("mpl_toolkits"); + PyObject* axis3d = PyString_FromString("mpl_toolkits.mplot3d"); + if (!mpl_toolkits || !axis3d) { throw std::runtime_error("couldnt create string"); } + + mpl_toolkitsmod = PyImport_Import(mpl_toolkits); + Py_DECREF(mpl_toolkits); + if (!mpl_toolkitsmod) { throw std::runtime_error("Error loading module mpl_toolkits!"); } + + axis3dmod = PyImport_Import(axis3d); + Py_DECREF(axis3d); + if (!axis3dmod) { throw std::runtime_error("Error loading module mpl_toolkits.mplot3d!"); } + } + + assert(x.size() == y.size()); + assert(y.size() == z.size()); + + // using numpy arrays + PyObject *xarray = get_array(x); + PyObject *yarray = get_array(y); + PyObject *zarray = get_array(z); + + // construct positional args + PyObject *args = PyTuple_New(3); + PyTuple_SetItem(args, 0, xarray); + PyTuple_SetItem(args, 1, yarray); + PyTuple_SetItem(args, 2, zarray); + + // Build up the kw args. + PyObject *kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "s", PyInt_FromLong(size)); + PyDict_SetItemString(kwargs, "c", PyString_FromString(color.c_str())); + + PyObject *fig = + PyObject_CallObject(detail::_interpreter::get().s_python_function_figure, + detail::_interpreter::get().s_python_empty_tuple); + if (!fig) throw std::runtime_error("Call to figure() failed."); + + PyObject *gca_kwargs = PyDict_New(); + PyDict_SetItemString(gca_kwargs, "projection", PyString_FromString("3d")); + + PyObject *gca = PyObject_GetAttrString(fig, "gca"); + if (!gca) throw std::runtime_error("No gca"); + Py_INCREF(gca); + PyObject *axis = PyObject_Call( + gca, detail::_interpreter::get().s_python_empty_tuple, gca_kwargs); + + if (!axis) throw std::runtime_error("No axis"); + Py_INCREF(axis); + + Py_DECREF(gca); + Py_DECREF(gca_kwargs); + + PyObject *scatter = PyObject_GetAttrString(axis, "scatter"); + Py_INCREF(scatter); + PyObject *res = PyObject_Call(scatter, args, kwargs); + Py_DECREF(scatter); + + Py_DECREF(axis); + Py_DECREF(args); + Py_DECREF(kwargs); + if (res) Py_DECREF(res); +} + +template +void plot(const std::vector &x, + const std::vector &y, + const std::vector &z, + const int& size, const string& color) +{ + static PyObject *mpl_toolkitsmod = nullptr, *axis3dmod = nullptr; + if (!mpl_toolkitsmod) { + detail::_interpreter::get(); + + PyObject* mpl_toolkits = PyString_FromString("mpl_toolkits"); + PyObject* axis3d = PyString_FromString("mpl_toolkits.mplot3d"); + if (!mpl_toolkits || !axis3d) { throw std::runtime_error("couldnt create string"); } + + mpl_toolkitsmod = PyImport_Import(mpl_toolkits); + Py_DECREF(mpl_toolkits); + if (!mpl_toolkitsmod) { throw std::runtime_error("Error loading module mpl_toolkits!"); } + + axis3dmod = PyImport_Import(axis3d); + Py_DECREF(axis3d); + if (!axis3dmod) { throw std::runtime_error("Error loading module mpl_toolkits.mplot3d!"); } + } + + assert(x.size() == y.size()); + assert(y.size() == z.size()); + + // using numpy arrays + PyObject *xarray = get_array(x); + PyObject *yarray = get_array(y); + PyObject *zarray = get_array(z); + + // construct positional args + PyObject *args = PyTuple_New(3); + PyTuple_SetItem(args, 0, xarray); + PyTuple_SetItem(args, 1, yarray); + PyTuple_SetItem(args, 2, zarray); + + // Build up the kw args. + PyObject *kwargs = PyDict_New(); + PyDict_SetItemString(kwargs, "s", PyInt_FromLong(size)); + PyDict_SetItemString(kwargs, "c", PyString_FromString(color.c_str())); + + PyObject *fig = + PyObject_CallObject(detail::_interpreter::get().s_python_function_figure, + detail::_interpreter::get().s_python_empty_tuple); + if (!fig) throw std::runtime_error("Call to figure() failed."); + + PyObject *gca_kwargs = PyDict_New(); + PyDict_SetItemString(gca_kwargs, "projection", PyString_FromString("3d")); + + PyObject *gca = PyObject_GetAttrString(fig, "gca"); + if (!gca) throw std::runtime_error("No gca"); + Py_INCREF(gca); + PyObject *axis = PyObject_Call( + gca, detail::_interpreter::get().s_python_empty_tuple, gca_kwargs); + + if (!axis) throw std::runtime_error("No axis"); + Py_INCREF(axis); + + Py_DECREF(gca); + Py_DECREF(gca_kwargs); + + PyObject *plot = PyObject_GetAttrString(axis, "plot"); + Py_INCREF(plot); + PyObject *res = PyObject_Call(plot, args, kwargs); + Py_DECREF(plot); + + Py_DECREF(axis); + Py_DECREF(args); + Py_DECREF(kwargs); + if (res) Py_DECREF(res); +} + + template bool stem(const std::vector &x, const std::vector &y, const std::map& keywords) {