8000 Add 3D quiver support · wernerpe/matplotlib-cpp@80bc9cd · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

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

Lines changed: 86 additions & 0 deletions
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)
0