Skip to content

Commit 3d8d850

Browse files
committed
Add rectangle2d
1 parent 577147e commit 3d8d850

1 file changed

Lines changed: 72 additions & 0 deletions

File tree

matplotlibcpp.h

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
17181790
bool 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

Comments
 (0)