@@ -53,6 +53,8 @@ struct _interpreter {
53
53
PyObject *s_python_function_fignum_exists;
54
54
PyObject *s_python_function_plot;
55
55
PyObject *s_python_function_quiver;
56
+ PyObject *s_python_function_axhline;
57
+ PyObject *s_python_function_axvline;
56
58
PyObject *s_python_function_semilogx;
57
59
PyObject *s_python_function_semilogy;
58
60
PyObject *s_python_function_loglog;
@@ -182,6 +184,8 @@ struct _interpreter {
182
184
PyObject_GetAttrString (pymod, " fignum_exists" );
183
185
s_python_function_plot = PyObject_GetAttrString (pymod, " plot" );
184
186
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" );
185
189
s_python_function_semilogx = PyObject_GetAttrString (pymod, " semilogx" );
186
190
s_python_function_semilogy = PyObject_GetAttrString (pymod, " semilogy" );
187
191
s_python_function_loglog = PyObject_GetAttrString (pymod, " loglog" );
@@ -1063,6 +1067,64 @@ bool quiver(const std::vector<NumericX> &x, const std::vector<NumericY> &y,
1063
1067
return res;
1064
1068
}
1065
1069
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
+
1066
1128
template <typename NumericX, typename NumericY>
1067
1129
bool stem (const std::vector<NumericX> &x, const std::vector<NumericY> &y,
1068
1130
const std::string &s = " " ) {
@@ -1230,17 +1292,29 @@ inline void figure_size(size_t w, size_t h) {
1230
1292
1231
1293
template <typename Vector = std::vector<double >>
1232
1294
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 = {}) {
1234
1297
detail::_interpreter::get ();
1235
1298
1236
1299
PyObject *kwargs = PyDict_New ();
1237
- PyDict_SetItemString (kwargs, " loc" , PyString_FromString (loc.c_str ()));
1238
1300
1301
+ // add location
1302
+ if (loc != " " )
1303
+ PyDict_SetItemString (kwargs, " loc" , PyString_FromString (loc.c_str ()));
1304
+
1305
+ // add bbox to anchor
1239
1306
if (bbox_to_anchor.size () == 2 || bbox_to_anchor.size () == 4 ) {
1240
1307
PyObject *bbox = get_array (bbox_to_anchor);
1241
1308
PyDict_SetItemString (kwargs, " bbox_to_anchor" , bbox);
1242
1309
}
1243
1310
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
+
1244
1318
PyObject *res =
1245
1319
PyObject_Call (detail::_interpreter::get ().s_python_function_legend ,
1246
1320
detail::_interpreter::get ().s_python_empty_tuple , kwargs);
@@ -1253,7 +1327,25 @@ inline void legend(const std::string &loc = "best",
1253
1327
Py_DECREF (res);
1254
1328
}
1255
1329
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) {
1257
1349
detail::_interpreter::get ();
1258
1350
1259
1351
PyObject *list = PyList_New (2 );
@@ -1272,7 +1364,8 @@ template <typename Numeric> void ylim(Numeric bottom, Numeric top) {
1272
1364
Py_DECREF (res);
1273
1365
}
1274
1366
1275
- template <typename Numeric> void xlim (Numeric left, Numeric right) {
1367
+ template <typename Numeric>
1368
+ void xlim (const Numeric left, const Numeric right) {
1276
1369
detail::_interpreter::get ();
1277
1370
1278
1371
PyObject *list = PyList_New (2 );
@@ -1751,11 +1844,8 @@ bool plot(const A &a, const B &b, const std::string &format, Args... args) {
1751
1844
return plot (a, b, format) && plot (args...);
1752
1845
}
1753
1846
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
1759
1849
class Plot {
1760
1850
public:
1761
1851
// default initialization with plot label, some data and format
0 commit comments