| 1114 | |
| 1115 | template<typename NumericX, typename NumericY, typename NumericU, typename NumericW> |
| 1116 | bool quiver(const std::vector<NumericX>& x, const std::vector<NumericY>& y, const std::vector<NumericU>& u, const std::vector<NumericW>& w, const std::map<std::string, std::string>& keywords = {}) |
| 1117 | { |
| 1118 | assert(x.size() == y.size() && x.size() == u.size() && u.size() == w.size()); |
| 1119 | |
| 1120 | detail::_interpreter::get(); |
| 1121 | |
| 1122 | PyObject* xarray = detail::get_array(x); |
| 1123 | PyObject* yarray = detail::get_array(y); |
| 1124 | PyObject* uarray = detail::get_array(u); |
| 1125 | PyObject* warray = detail::get_array(w); |
| 1126 | |
| 1127 | PyObject* plot_args = PyTuple_New(4); |
| 1128 | PyTuple_SetItem(plot_args, 0, xarray); |
| 1129 | PyTuple_SetItem(plot_args, 1, yarray); |
| 1130 | PyTuple_SetItem(plot_args, 2, uarray); |
| 1131 | PyTuple_SetItem(plot_args, 3, warray); |
| 1132 | |
| 1133 | // construct keyword args |
| 1134 | PyObject* kwargs = PyDict_New(); |
| 1135 | for(std::map<std::string, std::string>::const_iterator it = keywords.begin(); it != keywords.end(); ++it) |
| 1136 | { |
| 1137 | PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str())); |
| 1138 | } |
| 1139 | |
| 1140 | PyObject* res = PyObject_Call( |
| 1141 | detail::_interpreter::get().s_python_function_quiver, plot_args, kwargs); |
| 1142 | |
| 1143 | Py_DECREF(kwargs); |
| 1144 | Py_DECREF(plot_args); |
| 1145 | if (res) |
| 1146 | Py_DECREF(res); |
| 1147 | |
| 1148 | return res; |
| 1149 | } |
| 1150 | |
| 1151 | template<typename NumericX, typename NumericY> |
| 1152 | bool stem(const std::vector<NumericX>& x, const std::vector<NumericY>& y, const std::string& s = "") |