@@ -1202,6 +1202,92 @@ bool quiver(const std::vector<NumericX>& x, const std::vector<NumericY>& y, cons
1202
1202
return res;
1203
1203
}
1204
1204
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
+
1205
1291
template <typename NumericX, typename NumericY>
1206
1292
bool stem (const std::vector<NumericX>& x, const std::vector<NumericY>& y, const std::string& s = " " )
1207
1293
{
0 commit comments