| 533 | |
| 534 | template <typename Numeric> |
| 535 | void plot3(const std::vector<Numeric> &x, |
| 536 | const std::vector<Numeric> &y, |
| 537 | const std::vector<Numeric> &z, |
| 538 | const std::map<std::string, std::string> &keywords = |
| 539 | std::map<std::string, std::string>()) |
| 540 | { |
| 541 | detail::_interpreter::get(); |
| 542 | |
| 543 | // Same as with plot_surface: We lazily load the modules here the first time |
| 544 | // this function is called because I'm not sure that we can assume "matplotlib |
| 545 | // installed" implies "mpl_toolkits installed" on all platforms, and we don't |
| 546 | // want to require it for people who don't need 3d plots. |
| 547 | static PyObject *mpl_toolkitsmod = nullptr, *axis3dmod = nullptr; |
| 548 | if (!mpl_toolkitsmod) { |
| 549 | detail::_interpreter::get(); |
| 550 | |
| 551 | PyObject* mpl_toolkits = PyString_FromString("mpl_toolkits"); |
| 552 | PyObject* axis3d = PyString_FromString("mpl_toolkits.mplot3d"); |
| 553 | if (!mpl_toolkits || !axis3d) { throw std::runtime_error("couldnt create string"); } |
| 554 | |
| 555 | mpl_toolkitsmod = PyImport_Import(mpl_toolkits); |
| 556 | Py_DECREF(mpl_toolkits); |
| 557 | if (!mpl_toolkitsmod) { throw std::runtime_error("Error loading module mpl_toolkits!"); } |
| 558 | |
| 559 | axis3dmod = PyImport_Import(axis3d); |
| 560 | Py_DECREF(axis3d); |
| 561 | if (!axis3dmod) { throw std::runtime_error("Error loading module mpl_toolkits.mplot3d!"); } |
| 562 | } |
| 563 | |
| 564 | assert(x.size() == y.size()); |
| 565 | assert(y.size() == z.size()); |
| 566 | |
| 567 | PyObject *xarray = detail::get_array(x); |
| 568 | PyObject *yarray = detail::get_array(y); |
| 569 | PyObject *zarray = detail::get_array(z); |
| 570 | |
| 571 | // construct positional args |
| 572 | PyObject *args = PyTuple_New(3); |
| 573 | PyTuple_SetItem(args, 0, xarray); |
| 574 | PyTuple_SetItem(args, 1, yarray); |
| 575 | PyTuple_SetItem(args, 2, zarray); |
| 576 | |
| 577 | // Build up the kw args. |
| 578 | PyObject *kwargs = PyDict_New(); |
| 579 | |
| 580 | for (std::map<std::string, std::string>::const_iterator it = keywords.begin(); |
| 581 | it != keywords.end(); ++it) { |
| 582 | PyDict_SetItemString(kwargs, it->first.c_str(), |
| 583 | PyString_FromString(it->second.c_str())); |
| 584 | } |
| 585 | |
| 586 | PyObject *fig = |
| 587 | PyObject_CallObject(detail::_interpreter::get().s_python_function_figure, |
| 588 | detail::_interpreter::get().s_python_empty_tuple); |
| 589 | if (!fig) throw std::runtime_error("Call to figure() failed."); |
| 590 | |
| 591 | PyObject *gca_kwargs = PyDict_New(); |
| 592 | PyDict_SetItemString(gca_kwargs, "projection", PyString_FromString("3d")); |
nothing calls this directly
no test coverage detected