@@ -1715,6 +1715,78 @@ bool quiver(const NumericX* x, const NumericY* y, const NumericZ* z, const Numer
17151715 return res;
17161716}
17171717
1718+ bool rectangle2d (const double & x, const double & y, const double & width, const double & height,
1719+ const std::map<std::string, std::string>& keywords = {}) {
1720+ // set up patches
1721+ static PyObject* patchesmod = nullptr ;
1722+ if (!patchesmod) {
1723+ PyObject* patches = PyString_FromString (" matplotlib.patches" );
1724+ if (!patches) {
1725+ throw std::runtime_error (" couldnt create string" );
1726+ }
1727+
1728+ patchesmod = PyImport_Import (patches);
1729+ Py_DECREF (patches);
1730+ if (!patchesmod) {
1731+ throw std::runtime_error (" Error loading module matplotlib.patches!" );
1732+ }
1733+ }
1734+
1735+ // construct plot_args for rectangle
1736+ PyObject* xy = PyTuple_New (2 );
1737+ PyTuple_SetItem (xy, 0 , PyFloat_FromDouble (x));
1738+ PyTuple_SetItem (xy, 1 , PyFloat_FromDouble (y));
1739+ PyObject* rect_plot_args = PyTuple_New (3 );
1740+ PyTuple_SetItem (rect_plot_args, 0 , xy);
1741+ PyTuple_SetItem (rect_plot_args, 1 , PyFloat_FromDouble (width));
1742+ PyTuple_SetItem (rect_plot_args, 2 , PyFloat_FromDouble (height));
1743+
1744+ // construct keyword args for rectangle
1745+ PyObject* rect_kwargs = PyDict_New ();
1746+ for (std::map<std::string, std::string>::const_iterator it = keywords.begin ();
1747+ it != keywords.end (); ++it) {
1748+ PyObject* pobj_second;
1749+ if (isDouble (it->second )) {
1750+ pobj_second = PyFloat_FromDouble (std::stod (it->second ));
1751+ PyDict_SetItemString (rect_kwargs, it->first .c_str (), pobj_second);
1752+ } else {
1753+ pobj_second = PyUnicode_FromString (it->second .c_str ());
1754+ PyDict_SetItemString (rect_kwargs, it->first .c_str (), pobj_second);
1755+ }
1756+ Py_DECREF (pobj_second);
1757+ }
1758+
1759+ // create rectangle
1760+ PyObject* rectangle_func = PyObject_GetAttrString (patchesmod, " Rectangle" );
1761+ if (!rectangle_func) throw std::runtime_error (" No Rectangle" );
1762+ Py_INCREF (rectangle_func);
1763+ PyObject* rect = PyObject_Call (rectangle_func, rect_plot_args, rect_kwargs);
1764+ if (!rect) throw std::runtime_error (" Failed creating rectangle" );
1765+ Py_DECREF (rectangle_func);
1766+ Py_DECREF (rect_kwargs);
1767+ Py_DECREF (rect_plot_args);
1768+
1769+ // construct plot_args
1770+ PyObject* path_plot_args = PyTuple_New (1 );
1771+ PyTuple_SetItem (path_plot_args, 0 , rect);
1772+
1773+ // add patch
1774+ PyObject* axis = PyObject_CallObject (detail::_interpreter::get ().s_python_function_gca ,
1775+ detail::_interpreter::get ().s_python_empty_tuple );
1776+ if (!axis) throw std::runtime_error (" No axis" );
1777+ Py_INCREF (axis);
1778+ PyObject* add_patch_func = PyObject_GetAttrString (axis, " add_patch" );
1779+ if (!add_patch_func) throw std::runtime_error (" No add_patch" );
1780+ Py_INCREF (add_patch_func);
1781+ PyObject* res = PyObject_CallObject (add_patch_func, path_plot_args);
1782+ if (!res) throw std::runtime_error (" Failed add_patch" );
1783+ Py_DECREF (add_patch_func);
1784+ Py_DECREF (axis);
1785+ if (res) Py_DECREF (res);
1786+
1787+ return res;
1788+ }
1789+
17181790bool rectangle3d (const double & x, const double & y, const double & z, const double & width,
17191791 const double & height, const std::map<std::string, std::string>& keywords = {}) {
17201792 // set up 3d axes stuff
0 commit comments