8000 add axvline & axhline + test for legend · Cryoris/matplotlib-cpp@bd05374 · GitHub
[go: up one dir, main page]

Skip to content

Commit bd05374

Browse files
committed
add axvline & axhline + test for legend
1 parent a4c5589 commit bd05374

File tree

4 files changed

+156
-9
lines changed

4 files changed

+156
-9
lines changed

examples/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ function(add_example basename)
1313
endfunction(add_example)
1414

1515
# add the executables
16+
add_example(axlines)
1617
add_example(bar)
1718
add_example(basic)
1819
add_example(eigen)
1920
add_example(errorbar)
2021
add_example(fill_inbetween)
2122
add_example(fill)
23+
add_example(legend)
2224
add_example(loglog)
2325
add_example(minimal)
2426
add_example(modern)

examples/axlines.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include "../matplotlibcpp.h"
2+
namespace plt = matplotlibcpp;
3+
4+
void horizontal() {
5+
plt::axhline(0.2);
6+
plt::axhline(0.1, {{"color", "red"}});
7+
}
8+
9+
void vertical() {
10+
plt::axvline(0.2);
11+
plt::axvline(0.1, {{"color", "red"}});
12+
}
13+
14+
int main() {
15+
plt::figure();
16+
horizontal();
17+
vertical();
18+
plt::show();
19+
20+
return 0;
21+
}

examples/legend.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#include <vector>
2+
#include "../matplotlibcpp.h"
3+
namespace plt = matplotlibcpp;
4+
5+
void basic() {
6+
plt::figure();
7+
plt::plot({1, 2, 3}, {{"label", "a line"}});
8+
plt::plot({1, 3, 5}, {{"label", "also a line"}});
9+
plt::legend();
10+
plt::show();
11+
}
12+
13+
void bbox() {
14+
plt::figure();
15+
plt::plot({1, 2, 3}, {{"label", "a line"}});
16+
plt::plot({1, 3, 5}, {{"label", "also a line"}});
17+
plt::legend(std::vector<double>{0.5, 0.7});
18+
plt::show();
19+
}
20+
/*
21+
void keywords() {
22+
plt::figure();
23+
plt::plot({1, 2, 3}, {{"label", "a line"}});
24+
plt::plot({1, 3, 5}, {{"label", "also a line"}});
25+
plt::legend("best", {{"borderpad", "0.2"}});
26+
plt::show();
27+
}
28+
*/
29+
int main() {
30+
basic();
31+
bbox();
32+
// keywords();
33+
return 0;
34+
}

matplotlibcpp.h

Lines changed: 99 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ struct _interpreter {
5353
PyObject *s_python_function_fignum_exists;
5454
PyObject *s_python_function_plot;
5555
PyObject *s_python_function_quiver;
56+
PyObject *s_python_function_axhline;
57+
PyObject *s_python_function_axvline;
5658
PyObject *s_python_function_semilogx;
5759
PyObject *s_python_function_semilogy;
5860
PyObject *s_python_function_loglog;
@@ -182,6 +184,8 @@ struct _interpreter {
182184
PyObject_GetAttrString(pymod, "fignum_exists");
183185
s_python_function_plot = PyObject_GetAttrString(pymod, "plot");
184186
s_python_function_quiver = PyObject_GetAttrString(pymod, "quiver");
187+
s_python_function_axhline = PyObject_GetAttrString(pymod, "axhline");
188+
s_python_function_axvline = PyObject_GetAttrString(pymod, "axvline");
185189
s_python_function_semilogx = PyObject_GetAttrString(pymod, "semilogx");
186190
s_python_function_semilogy = PyObject_GetAttrString(pymod, "semilogy");
187191
s_python_function_loglog = PyObject_GetAttrString(pymod, "loglog");
@@ -1063,6 +1067,64 @@ bool quiver(const std::vector<NumericX> &x, const std::vector<NumericY> &y,
10631067
return res;
10641068
}
10651069

1070+
template <typename NumericY>
1071+
void axhline(const NumericY y,
1072+
const std::map<std::string, std::string> keywords = {}) {
1073+
detail::_interpreter::get();
1074+
1075+
PyObject *kwargs = PyDict_New();
1076+
1077+
// add location
1078+
PyDict_SetItemString(kwargs, "y", PyFloat_FromDouble(y));
1079+
1080+
// add other keywords
1081+
for (std::map<std::string, std::string>::const_iterator it = keywords.begin();
1082+
it != keywords.end(); ++it) {
1083+
PyDict_SetItemString(kwargs, it->first.c_str(),
1084+
PyUnicode_FromString(it->second.c_str()));
1085+
}
1086+
1087+
PyObject *res =
1088+
PyObject_Call(detail::_interpreter::get().s_python_function_axhline,
1089+
detail::_interpreter::get().s_python_empty_tuple, kwargs);
1090+
1091+
Py_DECREF(kwargs);
1092+
1093+
if (!res)
1094+
throw std::runtime_error("Call to axhline() failed.");
1095+
1096+
Py_DECREF(res);
1097+
}
1098+
1099+
template <typename NumericX>
1100+
void axvline(const NumericX x,
1101+
const std::map<std::string, std::string> keywords = {}) {
1102+
detail::_interpreter::get();
1103+
1104+
PyObject *kwargs = PyDict_New();
1105+
1106+
// add location
1107+
PyDict_SetItemString(kwargs, "x", PyFloat_FromDouble(x));
1108+
1109+
// add other keywords
1110+
for (std::map<std::string, std::string>::const_iterator it = keywords.begin();
1111+
it != keywords.end(); ++it) {
1112+
PyDict_SetItemString(kwargs, it->first.c_str(),
1113+
PyUnicode_FromString(it->second.c_str()));
1114+
}
1115+
1116+
PyObject *res =
1117+
PyObject_Call(detail::_interpreter::get().s_python_function_axvline,
1118+
detail::_interpreter::get().s_python_empty_tuple, kwargs);
1119+
1120+
Py_DECREF(kwargs);
1121+
1122+
if (!res)
1123+
throw std::runtime_error("Call to axvline() failed.");
1124+
1125+
Py_DECREF(res);
1126+
}
1127+
10661128
template <typename NumericX, typename NumericY>
10671129
bool stem(const std::vector<NumericX> &x, const std::vector<NumericY> &y,
10681130
const std::string &s = "") {
@@ -1230,17 +1292,29 @@ inline void figure_size(size_t w, size_t h) {
12301292

12311293
template <typename Vector = std::vector<double>>
12321294
inline void legend(const std::string &loc = "best",
1233-
const Vector &bbox_to_anchor = Vector()) {
1295+
const Vector &bbox_to_anchor = Vector(),
1296+
const std::map<std::string, std::string>& keywords = {}) {
12341297
detail::_interpreter::get();
12351298

12361299
PyObject *kwargs = PyDict_New();
1237-
PyDict_SetItemString(kwargs, "loc", PyString_FromString(loc.c_str()));
12381300

1301+
// add location
1302+
if (loc != "")
1303+
PyDict_SetItemString(kwargs, "loc", PyString_FromString(loc.c_str()));
1304+
1305+
// add bbox to anchor
12391306
if (bbox_to_anchor.size() == 2 || bbox_to_anchor.size() == 4) {
12401307
PyObject *bbox = get_array(bbox_to_anchor);
12411308
PyDict_SetItemString(kwargs, "bbox_to_anchor", bbox);
12421309
}
12431310

1311+
// add other keywords
1312+
for (std::map<std::string, std::string>::const_iterator it = keywords.begin();
1313+
it != keywords.end(); ++it) {
1314+
PyDict_SetItemString(kwargs, it->first.c_str(),
1315+
PyUnicode_FromString(it->second.c_str()));
1316+
}
1317+
12441318
PyObject *res =
12451319
PyObject_Call(detail::_interpreter::get().s_python_function_legend,
12461320
detail::_interpreter::get().s_python_empty_tuple, kwargs);
@@ -1253,7 +1327,25 @@ inline void legend(const std::string &loc = "best",
12531327
Py_DECREF(res);
12541328
}
12551329

1256-
template <typename Numeric> void ylim(Numeric bottom, Numeric top) {
1330+
template <typename Vector>
1331+
inline void legend(const Vector& bbox_to_anchor,
1332+
const std::map<std::string, std::string>& keywords = {}) {
1333+
legend("", bbox_to_anchor, keywords);
1334+
}
1335+
1336+
/*
1337+
inline void legend(const std::string& loc,
1338+
const std::map<std::string, std::string>& keywords = {}) {
1339+
legend(loc, std::vector<double>(), keywords);
1340+
}
1341+
1342+
inline void legend(const std::map<std::string, std::string>& keywords) {
1343+
legend("", std::vector<double>(), keywords);
1344+
}
1345+
*/
1346+
1347+
template <typename Numeric>
1348+
void ylim(const Numeric bottom, const Numeric top) {
12571349
detail::_interpreter::get();
12581350

12591351
PyObject *list = PyList_New(2);
@@ -1272,7 +1364,8 @@ template <typename Numeric> void ylim(Numeric bottom, Numeric top) {
12721364
Py_DECREF(res);
12731365
}
12741366

1275-
template <typename Numeric> void xlim(Numeric left, Numeric right) {
1367+
template <typename Numeric>
1368+
void xlim(const Numeric left, const Numeric right) {
12761369
detail::_interpreter::get();
12771370

12781371
PyObject *list = PyList_New(2);
@@ -1751,11 +1844,8 @@ bool plot(const A &a, const B &b, const std::string &format, Args... args) {
17511844
return plot(a, b, format) && plot(args...);
17521845
}
17531846

1754-
/*
1755-
* This class allows dynamic plots, ie changing the plotted data without
1756-
* clearing and re-plotting
1757-
*/
1758-
1847+
// This class allows dynamic plots, ie changing the plotted data without
1848+
// clearing and re-plotting
17591849
class Plot {
17601850
public:
17611851
// default initialization with plot label, some data and format

0 commit comments

Comments
 (0)
0