| 438 | #ifndef WITHOUT_NUMPY |
| 439 | template <typename Numeric> |
| 440 | void plot_surface(const std::vector<::std::vector<Numeric>> &x, |
| 441 | const std::vector<::std::vector<Numeric>> &y, |
| 442 | const std::vector<::std::vector<Numeric>> &z, |
| 443 | const std::map<std::string, std::string> &keywords = |
| 444 | std::map<std::string, std::string>()) |
| 445 | { |
| 446 | detail::_interpreter::get(); |
| 447 | |
| 448 | // We lazily load the modules here the first time this function is called |
| 449 | // because I'm not sure that we can assume "matplotlib installed" implies |
| 450 | // "mpl_toolkits installed" on all platforms, and we don't want to require |
| 451 | // it for people who don't need 3d plots. |
| 452 | static PyObject *mpl_toolkitsmod = nullptr, *axis3dmod = nullptr; |
| 453 | if (!mpl_toolkitsmod) { |
| 454 | detail::_interpreter::get(); |
| 455 | |
| 456 | PyObject* mpl_toolkits = PyString_FromString("mpl_toolkits"); |
| 457 | PyObject* axis3d = PyString_FromString("mpl_toolkits.mplot3d"); |
| 458 | if (!mpl_toolkits || !axis3d) { throw std::runtime_error("couldnt create string"); } |
| 459 | |
| 460 | mpl_toolkitsmod = PyImport_Import(mpl_toolkits); |
| 461 | Py_DECREF(mpl_toolkits); |
| 462 | if (!mpl_toolkitsmod) { throw std::runtime_error("Error loading module mpl_toolkits!"); } |
| 463 | |
| 464 | axis3dmod = PyImport_Import(axis3d); |
| 465 | Py_DECREF(axis3d); |
| 466 | if (!axis3dmod) { throw std::runtime_error("Error loading module mpl_toolkits.mplot3d!"); } |
| 467 | } |
| 468 | |
| 469 | assert(x.size() == y.size()); |
| 470 | assert(y.size() == z.size()); |
| 471 | |
| 472 | // using numpy arrays |
| 473 | PyObject *xarray = detail::get_2darray(x); |
| 474 | PyObject *yarray = detail::get_2darray(y); |
| 475 | PyObject *zarray = detail::get_2darray(z); |
| 476 | |
| 477 | // construct positional args |
| 478 | PyObject *args = PyTuple_New(3); |
| 479 | PyTuple_SetItem(args, 0, xarray); |
| 480 | PyTuple_SetItem(args, 1, yarray); |
| 481 | PyTuple_SetItem(args, 2, zarray); |
| 482 | |
| 483 | // Build up the kw args. |
| 484 | PyObject *kwargs = PyDict_New(); |
| 485 | PyDict_SetItemString(kwargs, "rstride", PyInt_FromLong(1)); |
| 486 | PyDict_SetItemString(kwargs, "cstride", PyInt_FromLong(1)); |
| 487 | |
| 488 | PyObject *python_colormap_coolwarm = PyObject_GetAttrString( |
| 489 | detail::_interpreter::get().s_python_colormap, "coolwarm"); |
| 490 | |
| 491 | PyDict_SetItemString(kwargs, "cmap", python_colormap_coolwarm); |
| 492 | |
| 493 | for (std::map<std::string, std::string>::const_iterator it = keywords.begin(); |
| 494 | it != keywords.end(); ++it) { |
| 495 | PyDict_SetItemString(kwargs, it->first.c_str(), |
| 496 | PyString_FromString(it->second.c_str())); |
| 497 | } |
nothing calls this directly
no test coverage detected