| 355 | |
| 356 | template <typename Numeric> |
| 357 | void plot_surface(const std::vector<::std::vector<Numeric>> &x, |
| 358 | const std::vector<::std::vector<Numeric>> &y, |
| 359 | const std::vector<::std::vector<Numeric>> &z, |
| 360 | const std::map<std::string, std::string> &keywords = |
| 361 | std::map<std::string, std::string>()) |
| 362 | { |
| 363 | // We lazily load the modules here the first time this function is called |
| 364 | // because I'm not sure that we can assume "matplotlib installed" implies |
| 365 | // "mpl_toolkits installed" on all platforms, and we don't want to require |
| 366 | // it for people who don't need 3d plots. |
| 367 | static PyObject *mpl_toolkitsmod = nullptr, *axis3dmod = nullptr; |
| 368 | if (!mpl_toolkitsmod) { |
| 369 | detail::_interpreter::get(); |
| 370 | |
| 371 | PyObject* mpl_toolkits = PyString_FromString("mpl_toolkits"); |
| 372 | PyObject* axis3d = PyString_FromString("mpl_toolkits.mplot3d"); |
| 373 | if (!mpl_toolkits || !axis3d) { throw std::runtime_error("couldnt create string"); } |
| 374 | |
| 375 | mpl_toolkitsmod = PyImport_Import(mpl_toolkits); |
| 376 | Py_DECREF(mpl_toolkits); |
| 377 | if (!mpl_toolkitsmod) { throw std::runtime_error("Error loading module mpl_toolkits!"); } |
| 378 | |
| 379 | axis3dmod = PyImport_Import(axis3d); |
| 380 | Py_DECREF(axis3d); |
| 381 | if (!axis3dmod) { throw std::runtime_error("Error loading module mpl_toolkits.mplot3d!"); } |
| 382 | } |
| 383 | |
| 384 | assert(x.size() == y.size()); |
| 385 | assert(y.size() == z.size()); |
| 386 | |
| 387 | // using numpy arrays |
| 388 | PyObject *xarray = get_2darray(x); |
| 389 | PyObject *yarray = get_2darray(y); |
| 390 | PyObject *zarray = get_2darray(z); |
| 391 | |
| 392 | // construct positional args |
| 393 | PyObject *args = PyTuple_New(3); |
| 394 | PyTuple_SetItem(args, 0, xarray); |
| 395 | PyTuple_SetItem(args, 1, yarray); |
| 396 | PyTuple_SetItem(args, 2, zarray); |
| 397 | |
| 398 | // Build up the kw args. |
| 399 | PyObject *kwargs = PyDict_New(); |
| 400 | PyDict_SetItemString(kwargs, "rstride", PyInt_FromLong(1)); |
| 401 | PyDict_SetItemString(kwargs, "cstride", PyInt_FromLong(1)); |
| 402 | |
| 403 | PyObject *python_colormap_coolwarm = PyObject_GetAttrString( |
| 404 | detail::_interpreter::get().s_python_colormap, "coolwarm"); |
| 405 | |
| 406 | PyDict_SetItemString(kwargs, "cmap", python_colormap_coolwarm); |
| 407 | |
| 408 | for (std::map<std::string, std::string>::const_iterator it = keywords.begin(); |
| 409 | it != keywords.end(); ++it) { |
| 410 | PyDict_SetItemString(kwargs, it->first.c_str(), |
| 411 | PyString_FromString(it->second.c_str())); |
| 412 | } |
| 413 | |
| 414 |
nothing calls this directly
no test coverage detected