Skip to content

Commit 2d214f4

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 77a3660 + b124207 commit 2d214f4

File tree

2 files changed

+107
-0
lines changed

2 files changed

+107
-0
lines changed

examples/subplot.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#define _USE_MATH_DEFINES
2+
#include <cmath>
3+
#include "../matplotlibcpp.h"
4+
5+
using namespace std;
6+
namespace plt = matplotlibcpp;
7+
8+
int main()
9+
{
10+
// Prepare data
11+
int n = 500;
12+
std::vector<double> x(n), y(n), z(n), w(n,2);
13+
for(int i=0; i<n; ++i) {
14+
x.at(i) = i;
15+
y.at(i) = sin(2*M_PI*i/360.0);
16+
z.at(i) = 100.0 / i;
17+
}
18+
19+
// Set the "super title"
20+
plt::suptitle("My plot");
21+
plt::subplot(1, 2, 1);
22+
plt::plot(x, y, "r-");
23+
plt::subplot(1, 2, 2);
24+
plt::plot(x, z, "k-");
25+
// Add some text to the plot
26+
plt::text(100, 90, "Hello!");
27+
28+
29+
// Show plots
30+
plt::show();
31+
}

matplotlibcpp.h

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct _interpreter {
4747
PyObject *s_python_function_legend;
4848
PyObject *s_python_function_xlim;
4949
PyObject *s_python_function_ion;
50+
PyObject *s_python_function_ginput;
5051
PyObject *s_python_function_ylim;
5152
PyObject *s_python_function_title;
5253
PyObject *s_python_function_axis;
@@ -62,6 +63,8 @@ struct _interpreter {
6263
PyObject *s_python_empty_tuple;
6364
PyObject *s_python_function_stem;
6465
PyObject *s_python_function_xkcd;
66+
PyObject *s_python_function_text;
67+
PyObject *s_python_function_suptitle;
6568

6669
/* For now, _interpreter is implemented as a singleton since its currently not possible to have
6770
multiple independent embedded python interpreters without patching the python source code
@@ -158,13 +161,16 @@ struct _interpreter {
158161
s_python_function_grid = PyObject_GetAttrString(pymod, "grid");
159162
s_python_function_xlim = PyObject_GetAttrString(pymod, "xlim");
160163
s_python_function_ion = PyObject_GetAttrString(pymod, "ion");
164+
s_python_function_ginput = PyObject_GetAttrString(pymod, "ginput");
161165
s_python_function_save = PyObject_GetAttrString(pylabmod, "savefig");
162166
s_python_function_annotate = PyObject_GetAttrString(pymod,"annotate");
163167
s_python_function_clf = PyObject_GetAttrString(pymod, "clf");
164168
s_python_function_errorbar = PyObject_GetAttrString(pymod, "errorbar");
165169
s_python_function_tight_layout = PyObject_GetAttrString(pymod, "tight_layout");
166170
s_python_function_stem = PyObject_GetAttrString(pymod, "stem");
167171
s_python_function_xkcd = PyObject_GetAttrString(pymod, "xkcd");
172+
s_python_function_text = PyObject_GetAttrString(pymod, "text");
173+
s_python_function_suptitle = PyObject_GetAttrString(pymod, "suptitle");
168174

169175
if( !s_python_function_show
170176
|| !s_python_function_close
@@ -187,6 +193,7 @@ struct _interpreter {
187193
|| !s_python_function_grid
188194
|| !s_python_function_xlim
189195
|| !s_python_function_ion
196+
|| !s_python_function_ginput
190197
|| !s_python_function_save
191198
|| !s_python_function_clf
192199
|| !s_python_function_annotate
@@ -195,6 +202,8 @@ struct _interpreter {
195202
|| !s_python_function_tight_layout
196203
|| !s_python_function_stem
197204
|| !s_python_function_xkcd
205+
|| !s_python_function_text
206+
|| !s_python_function_suptitle
198207
) { throw std::runtime_error("Couldn't find required function!"); }
199208

200209
if ( !PyFunction_Check(s_python_function_show)
@@ -219,12 +228,15 @@ struct _interpreter {
219228
|| !PyFunction_Check(s_python_function_grid)
220229
|| !PyFunction_Check(s_python_function_xlim)
221230
|| !PyFunction_Check(s_python_function_ion)
231+
|| !PyFunction_Check(s_python_function_ginput)
222232
|| !PyFunction_Check(s_python_function_save)
223233
|| !PyFunction_Check(s_python_function_clf)
224234
|| !PyFunction_Check(s_python_function_tight_layout)
225235
|| !PyFunction_Check(s_python_function_errorbar)
226236
|| !PyFunction_Check(s_python_function_stem)
227237
|| !PyFunction_Check(s_python_function_xkcd)
238+
|| !PyFunction_Check(s_python_function_text)
239+
|| !PyFunction_Check(s_python_function_suptitle)
228240
) { throw std::runtime_error("Python object is unexpectedly not a PyFunction."); }
229241

230242
s_python_empty_tuple = PyTuple_New(0);
@@ -511,6 +523,7 @@ bool quiver(const std::vector<NumericX>& x, const std::vector<NumericY>& y, cons
511523
PyObject* res = PyObject_Call(
512524
detail::_interpreter::get().s_python_function_quiver, plot_args, kwargs);
513525

526+
Py_DECREF(kwargs);
514527
Py_DECREF(plot_args);
515528
if (res)
516529
Py_DECREF(res);
@@ -787,6 +800,22 @@ bool stem(const std::vector<Numeric>& y, const std::string& format = "")
787800
return stem(x, y, format);
788801
}
789802

803+
template<typename Numeric>
804+
void text(Numeric x, Numeric y, const std::string& s = "")
805+
{
806+
PyObject* args = PyTuple_New(3);
807+
PyTuple_SetItem(args, 0, PyFloat_FromDouble(x));
808+
PyTuple_SetItem(args, 1, PyFloat_FromDouble(y));
809+
PyTuple_SetItem(args, 2, PyString_FromString(s.c_str()));
810+
811+
PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_text, args);
812+
if(!res) throw std::runtime_error("Call to text() failed.");
813+
814+
Py_DECREF(args);
815+
Py_DECREF(res);
816+
}
817+
818+
790819
inline void figure()
791820
{
792821
PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_figure, detail::_interpreter::get().s_python_empty_tuple);
@@ -1015,6 +1044,19 @@ inline void title(const std::string &titlestr)
10151044
Py_DECREF(res);
10161045
}
10171046

1047+
inline void suptitle(const std::string &suptitlestr)
1048+
{
1049+
PyObject* pysuptitlestr = PyString_FromString(suptitlestr.c_str());
1050+
PyObject* args = PyTuple_New(1);
1051+
PyTuple_SetItem(args, 0, pysuptitlestr);
1052+
1053+
PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_suptitle, args);
1054+
if(!res) throw std::runtime_error("Call to suptitle() failed.");
1055+
1056+
Py_DECREF(args);
1057+
Py_DECREF(res);
1058+
}
1059+
10181060
inline void axis(const std::string &axisstr)
10191061
{
10201062
PyObject* str = PyString_FromString(axisstr.c_str());
@@ -1176,6 +1218,40 @@ inline void clf() {
11761218
Py_DECREF(res);
11771219
}
11781220

1221+
inline std::vector<std::array<double, 2>> ginput(const int numClicks = 1, const std::map<std::string, std::string>& keywords = {})
1222+
{
1223+
PyObject *args = PyTuple_New(1);
1224+
PyTuple_SetItem(args, 0, PyLong_FromLong(numClicks));
1225+
1226+
// construct keyword args
1227+
PyObject* kwargs = PyDict_New();
1228+
for(std::map<std::string, std::string>::const_iterator it = keywords.begin(); it != keywords.end(); ++it)
1229+
{
1230+
PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str()));
1231+
}
1232+
1233+
PyObject* res = PyObject_Call(
1234+
detail::_interpreter::get().s_python_function_ginput, args, kwargs);
1235+
1236+
Py_DECREF(kwargs);
1237+
Py_DECREF(args);
1238+
if (!res) throw std::runtime_error("Call to ginput() failed.");
1239+
1240+
const size_t len = PyList_Size(res);
1241+
std::vector<std::array<double, 2>> out;
1242+
out.reserve(len);
1243+
for (size_t i = 0; i < len; i++) {
1244+
PyObject *current = PyList_GetItem(res, i);
1245+
std::array<double, 2> position;
1246+
position[0] = PyFloat_AsDouble(PyTuple_GetItem(current, 0));
1247+
position[1] = PyFloat_AsDouble(PyTuple_GetItem(current, 1));
1248+
out.push_back(position);
1249+
}
1250+
Py_DECREF(res);
1251+
1252+
return out;
1253+
}
1254+
11791255
// Actually, is there any reason not to call this automatically for every plot?
11801256
inline void tight_layout() {
11811257
PyObject *res = PyObject_CallObject(

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy