@@ -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+
12051291template <typename NumericX, typename NumericY>
12061292bool stem (const std::vector<NumericX>& x, const std::vector<NumericY>& y, const std::string& s = " " )
12071293{
0 commit comments