Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 80bc9cd

Browse files
sapphouslava
authored andcommitted
Add 3D quiver support
1 parent 70d508f commit 80bc9cd

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

matplotlibcpp.h

+86
Original file line numberDiff line numberDiff line change
@@ -1202,6 +1202,92 @@ bool quiver(const std::vector<NumericX>& x, const std::vector<NumericY>& y, cons
12021202
return res;
12031203
}
12041204

1205+
template<typename NumericX, typename NumericY, typename NumericZ, typename NumericU, typename NumericW, typename NumericV>
1206+
bool quiver(const std::vector<NumericX>& x, const std::vector<NumericY>& y, const std::vector<NumericZ>& z, const std::vector<NumericU>& u, const std::vector<NumericW>& w, const std::vector<NumericV>& v, const std::map<std::string, std::string>& keywords = {})
1207+
{
1208+
//set up 3d axes stuff
1209+
static PyObject *mpl_toolkitsmod = nullptr, *axis3dmod = nullptr;
1210+
if (!mpl_toolkitsmod) {
1211+
detail::_interpreter::get();
1212+
1213+
PyObject* mpl_toolkits = PyString_FromString("mpl_toolkits");
1214+
PyObject* axis3d = PyString_FromString("mpl_toolkits.mplot3d");
1215+
if (!mpl_toolkits || !axis3d) { throw std::runtime_error("couldnt create string"); }
1216+
1217+
mpl_toolkitsmod = PyImport_Import(mpl_toolkits);
1218+
Py_DECREF(mpl_toolkits);
1219+
if (!mpl_toolkitsmod) { throw std::runtime_error("Error loading module mpl_toolkits!"); }
1220+
1221+
axis3dmod = PyImport_Import(axis3d);
1222+
Py_DECREF(axis3d);
1223+
if (!axis3dmod) { throw std::runtime_error("Error loading module mpl_toolkits.mplot3d!"); }
1224+
}
1225+
1226+
//assert sizes match up
1227+
assert(x.size() == y.size() && x.size() == u.size() && u.size() == w.size() && x.size() == z.size() && x.size() == v.size() && u.size() == v.size());
1228+
1229+
//set up parameters
1230+
detail::_interpreter::get();
1231+
1232+
PyObject* xarray = detail::get_array(x);
1233+
PyObject* yarray = detail::get_array(y);
1234+
PyObject* zarray = detail::get_array(z);
1235+
PyObject* uarray = detail::get_array(u);
1236+
PyObject* warray = detail::get_array(w);
1237+
PyObject* varray = detail::get_array(v);
1238+
1239+
PyObject* plot_args = PyTuple_New(6);
1240+
PyTuple_SetItem(plot_args, 0, xarray);
1241+
PyTuple_SetItem(plot_args, 1, yarray);
1242+
PyTuple_SetItem(plot_args, 2, zarray);
1243+
PyTuple_SetItem(plot_args, 3, uarray);
1244+
PyTuple_SetItem(plot_args, 4, warray);
1245+
PyTuple_SetItem(plot_args, 5, varray);
1246+
1247+
// construct keyword args
1248+
PyObject* kwargs = PyDict_New();
1249+
for(std::map<std::string, std::string>::const_iterator it = keywords.begin(); it != keywords.end(); ++it)
1250+
{
1251+
PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str()));
1252+
}
1253+
1254+
//get figure gca to enable 3d projection
1255+
PyObject *fig =
1256+
PyObject_CallObject(detail::_interpreter::get().s_python_function_figure,
1257+
detail::_interpreter::get().s_python_empty_tuple);
1258+
if (!fig) throw std::runtime_error("Call to figure() failed.");
1259+
1260+
PyObject *gca_kwargs = PyDict_New();
1261+
PyDict_SetItemString(gca_kwargs, "projection", PyString_FromString("3d"));
1262+
1263+
PyObject *gca = PyObject_GetAttrString(fig, "gca");
1264+
if (!gca) throw std::runtime_error("No gca");
1265+
Py_INCREF(gca);
1266+
PyObject *axis = PyObject_Call(
1267+
gca, detail::_interpreter::get().s_python_empty_tuple, gca_kwargs);
1268+
1269+
if (!axis) throw std::runtime_error("No axis");
1270+
Py_INCREF(axis);
1271+
Py_DECREF(gca);
1272+
Py_DECREF(gca_kwargs);
1273+
1274+
//plot our boys bravely, plot them strongly, plot them with a wink and clap
1275+
PyObject *plot3 = PyObject_GetAttrString(axis, "quiver");
1276+
if (!plot3) throw std::runtime_error("No 3D line plot");
1277+
Py_INCREF(plot3);
1278+
PyObject* res = PyObject_Call(
1279+
plot3, plot_args, kwargs);
1280+
if (!res) throw std::runtime_error("Failed 3D plot");
1281+
Py_DECREF(plot3);
1282+
Py_DECREF(axis);
1283+
Py_DECREF(kwargs);
1284+
Py_DECREF(plot_args);
1285+
if (res)
1286+
Py_DECREF(res);
1287+
1288+
return res;
1289+
}
1290+
12051291
template<typename NumericX, typename NumericY>
12061292
bool stem(const std::vector<NumericX>& x, const std::vector<NumericY>& y, const std::string& s = "")
12071293
{

0 commit comments

Comments
 (0)