31 #if __cplusplus > 199711L 35 #include <python2.7/Python.h> 69 char name[] =
"plotting";
70 Py_SetProgramName(name);
73 PyObject* pyplotname = PyString_FromString(
"matplotlib.pyplot");
74 PyObject* pylabname = PyString_FromString(
"pylab");
75 if(!pyplotname || !pylabname) {
throw std::runtime_error(
"couldnt create string"); }
77 PyObject* pymod = PyImport_Import(pyplotname);
78 Py_DECREF(pyplotname);
79 if(!pymod) {
throw std::runtime_error(
"Error loading module matplotlib.pyplot!"); }
81 PyObject* pylabmod = PyImport_Import(pylabname);
83 if(!pymod) {
throw std::runtime_error(
"Error loading module pylab!"); }
85 s_python_function_show = PyObject_GetAttrString(pymod,
"show");
86 s_python_function_figure = PyObject_GetAttrString(pymod,
"figure");
87 s_python_function_plot = PyObject_GetAttrString(pymod,
"plot");
88 s_python_function_legend = PyObject_GetAttrString(pymod,
"legend");
89 s_python_function_ylim = PyObject_GetAttrString(pymod,
"ylim");
90 s_python_function_title = PyObject_GetAttrString(pymod,
"title");
91 s_python_function_axis = PyObject_GetAttrString(pymod,
"axis");
92 s_python_function_xlabel = PyObject_GetAttrString(pymod,
"xlabel");
93 s_python_function_ylabel = PyObject_GetAttrString(pymod,
"ylabel");
94 s_python_function_grid = PyObject_GetAttrString(pymod,
"grid");
95 s_python_function_xlim = PyObject_GetAttrString(pymod,
"xlim");
97 s_python_function_save = PyObject_GetAttrString(pylabmod,
"savefig");
99 if(!s_python_function_show
100 || !s_python_function_save
101 || !s_python_function_figure
102 || !s_python_function_plot
103 || !s_python_function_legend
104 || !s_python_function_xlim
105 || !s_python_function_ylim
106 || !s_python_function_title
107 || !s_python_function_axis
108 || !s_python_function_xlabel
109 || !s_python_function_ylabel
110 || !s_python_function_grid
112 {
throw std::runtime_error(
"Couldnt find required function!"); }
114 if(!PyFunction_Check(s_python_function_show)
115 || !PyFunction_Check(s_python_function_save)
116 || !PyFunction_Check(s_python_function_figure)
117 || !PyFunction_Check(s_python_function_plot)
118 || !PyFunction_Check(s_python_function_legend)
119 || !PyFunction_Check(s_python_function_xlim)
120 || !PyFunction_Check(s_python_function_ylim)
121 || !PyFunction_Check(s_python_function_title)
122 || !PyFunction_Check(s_python_function_axis)
123 || !PyFunction_Check(s_python_function_xlabel)
124 || !PyFunction_Check(s_python_function_ylabel)
125 || !PyFunction_Check(s_python_function_grid)
127 {
throw std::runtime_error(
"Python object is unexpectedly not a PyFunction."); }
129 s_python_empty_tuple = PyTuple_New(0);
140 template<
typename Numeric>
141 bool plot(
const std::vector<Numeric> &x,
const std::vector<Numeric> &y,
const std::map<std::string, std::string>& keywords)
143 assert(x.size() == y.size());
146 PyObject* xlist = PyList_New(x.size());
147 PyObject* ylist = PyList_New(y.size());
149 for(
size_t i = 0; i < x.size(); ++i) {
150 PyList_SetItem(xlist, i, PyFloat_FromDouble(x.at(i)));
151 PyList_SetItem(ylist, i, PyFloat_FromDouble(y.at(i)));
155 PyObject* args = PyTuple_New(2);
156 PyTuple_SetItem(args, 0, xlist);
157 PyTuple_SetItem(args, 1, ylist);
163 PyObject* kwargs = PyDict_New();
164 for(std::map<std::string, std::string>::const_iterator it = keywords.begin(); it != keywords.end(); ++it)
166 PyDict_SetItemString(kwargs, it->first.c_str(), PyString_FromString(it->second.c_str()));
173 if(res) Py_DECREF(res);
179 template<
typename NumericX,
typename NumericY>
180 bool plot(
const std::vector<NumericX>& x,
const std::vector<NumericY>& y,
const std::string& s =
"")
182 assert(x.size() == y.size());
184 PyObject* xlist = PyList_New(x.size());
185 PyObject* ylist = PyList_New(y.size());
186 PyObject* pystring = PyString_FromString(s.c_str());
188 for(
size_t i = 0; i < x.size(); ++i) {
189 PyList_SetItem(xlist, i, PyFloat_FromDouble(x.at(i)));
190 PyList_SetItem(ylist, i, PyFloat_FromDouble(y.at(i)));
193 PyObject* plot_args = PyTuple_New(3);
194 PyTuple_SetItem(plot_args, 0, xlist);
195 PyTuple_SetItem(plot_args, 1, ylist);
196 PyTuple_SetItem(plot_args, 2, pystring);
202 Py_DECREF(plot_args);
203 if(res) Py_DECREF(res);
209 template<
typename Numeric>
210 bool named_plot(
const std::string& name,
const std::vector<Numeric>& x,
const std::vector<Numeric>& y,
const std::string& format =
"") {
211 PyObject* kwargs = PyDict_New();
212 PyDict_SetItemString(kwargs,
"label", PyString_FromString(name.c_str()));
214 PyObject* xlist = PyList_New(x.size());
215 PyObject* ylist = PyList_New(y.size());
216 PyObject* pystring = PyString_FromString(format.c_str());
218 for(
size_t i = 0; i < x.size(); ++i) {
219 PyList_SetItem(xlist, i, PyFloat_FromDouble(x.at(i)));
220 PyList_SetItem(ylist, i, PyFloat_FromDouble(y.at(i)));
223 PyObject* plot_args = PyTuple_New(3);
224 PyTuple_SetItem(plot_args, 0, xlist);
225 PyTuple_SetItem(plot_args, 1, ylist);
226 PyTuple_SetItem(plot_args, 2, pystring);
233 Py_DECREF(plot_args);
234 if(res) Py_DECREF(res);
239 template<
typename Numeric>
240 bool plot(
const std::vector<Numeric>& y,
const std::string& format =
"")
242 std::vector<Numeric> x(y.size());
243 for(
size_t i=0; i<x.size(); ++i) x.at(i) = i;
244 return plot(x,y,format);
250 if(!res)
throw std::runtime_error(
"Call to legend() failed.");
255 template<
typename Numeric>
256 void ylim(Numeric left, Numeric right)
258 PyObject* list = PyList_New(2);
259 PyList_SetItem(list, 0, PyFloat_FromDouble(left));
260 PyList_SetItem(list, 1, PyFloat_FromDouble(right));
262 PyObject* args = PyTuple_New(1);
263 PyTuple_SetItem(args, 0, list);
266 if(!res)
throw std::runtime_error(
"Call to ylim() failed.");
273 template<
typename Numeric>
274 void xlim(Numeric left, Numeric right)
276 PyObject* list = PyList_New(2);
277 PyList_SetItem(list, 0, PyFloat_FromDouble(left));
278 PyList_SetItem(list, 1, PyFloat_FromDouble(right));
280 PyObject* args = PyTuple_New(1);
281 PyTuple_SetItem(args, 0, list);
284 if(!res)
throw std::runtime_error(
"Call to xlim() failed.");
292 inline void title(
const std::string &titlestr)
294 PyObject* pytitlestr = PyString_FromString(titlestr.c_str());
295 PyObject* args = PyTuple_New(1);
296 PyTuple_SetItem(args, 0, pytitlestr);
299 if(!res)
throw std::runtime_error(
"Call to title() failed.");
304 inline void axis(
const std::string &axisstr)
306 PyObject* str = PyString_FromString(axisstr.c_str());
307 PyObject* args = PyTuple_New(1);
308 PyTuple_SetItem(args, 0, str);
311 if(!res)
throw std::runtime_error(
"Call to title() failed.");
318 inline void xlabel(
const std::string &str)
320 PyObject* pystr = PyString_FromString(str.c_str());
321 PyObject* args = PyTuple_New(1);
322 PyTuple_SetItem(args, 0, pystr);
325 if(!res)
throw std::runtime_error(
"Call to xlabel() failed.");
330 inline void ylabel(
const std::string &str)
332 PyObject* pystr = PyString_FromString(str.c_str());
333 PyObject* args = PyTuple_New(1);
334 PyTuple_SetItem(args, 0, pystr);
337 if(!res)
throw std::runtime_error(
"Call to ylabel() failed.");
344 PyObject* pyflag = flag ? Py_True : Py_False;
346 PyObject* args = PyTuple_New(1);
347 PyTuple_SetItem(args, 0, pyflag);
350 if(!res)
throw std::runtime_error(
"Call to grid() failed.");
360 if(!res)
throw std::runtime_error(
"Call to show() failed.");
365 inline void save(
const std::string& filename)
367 PyObject* pyfilename = PyString_FromString(filename.c_str());
369 PyObject* args = PyTuple_New(1);
370 PyTuple_SetItem(args, 0, pyfilename);
373 if(!res)
throw std::runtime_error(
"Call to save() failed.");
375 Py_DECREF(pyfilename);
380 #if __cplusplus > 199711L 385 using is_function =
typename std::is_function<std::remove_pointer<std::remove_reference<T>>>::type;
387 template<
bool obj,
typename T>
388 struct is_callable_impl;
391 struct is_callable_impl<false, T>
393 typedef is_function<T> type;
397 struct is_callable_impl<true, T>
399 struct Fallback {
void operator()(); };
400 struct Derived : T, Fallback { };
402 template<
typename U, U>
struct Check;
405 static std::true_type test( ... );
408 static std::false_type test( Check<
void(Fallback::*)(), &U::operator()>* );
411 typedef decltype(test<Derived>(
nullptr)) type;
412 typedef decltype(&Fallback::operator()) dtype;
413 static constexpr
bool value = type::value;
420 typedef typename is_callable_impl<std::is_class<T>::value, T>::type type;
423 template<
typename IsYDataCallable>
424 struct plot_impl { };
427 struct plot_impl<std::false_type>
429 template<
typename IterableX,
typename IterableY>
430 bool operator()(
const IterableX& x,
const IterableY& y,
const std::string& format)
437 auto xs = distance(begin(x), end(x));
438 auto ys = distance(begin(y), end(y));
439 assert(xs == ys &&
"x and y data must have the same number of elements!");
441 PyObject* xlist = PyList_New(xs);
442 PyObject* ylist = PyList_New(ys);
443 PyObject* pystring = PyString_FromString(format.c_str());
445 auto itx = begin(x), ity = begin(y);
446 for(
size_t i = 0; i < xs; ++i) {
447 PyList_SetItem(xlist, i, PyFloat_FromDouble(*itx++));
448 PyList_SetItem(ylist, i, PyFloat_FromDouble(*ity++));
451 PyObject* plot_args = PyTuple_New(3);
452 PyTuple_SetItem(plot_args, 0, xlist);
453 PyTuple_SetItem(plot_args, 1, ylist);
454 PyTuple_SetItem(plot_args, 2, pystring);
460 Py_DECREF(plot_args);
461 if(res) Py_DECREF(res);
468 struct plot_impl<std::true_type>
470 template<
typename Iterable,
typename Callable>
471 bool operator()(
const Iterable& ticks,
const Callable& f,
const std::string& format)
475 if(begin(ticks) == end(ticks))
return true;
479 std::vector<double> y;
480 for(
auto x : ticks) y.push_back(f(x));
481 return plot_impl<std::false_type>()(ticks,y,format);
487 template<
typename... Args>
488 bool plot() {
return true; }
490 template<
typename A,
typename B,
typename... Args>
491 bool plot(
const A& a,
const B& b,
const std::string& format, Args... args)
493 return detail::plot_impl<typename detail::is_callable<B>::type>()(a,b,format) &&
plot(args...);
500 bool plot(
const std::vector<double>& x,
const std::vector<double>& y,
const std::string& format =
"") {
501 return plot<double,double>(x,y,format);
504 bool plot(
const std::vector<double>& y,
const std::string& format =
"") {
505 return plot<double>(y,format);
508 bool plot(
const std::vector<double>& x,
const std::vector<double>& y,
const std::map<std::string, std::string>& keywords) {
509 return plot<double>(x,y,keywords);
512 bool named_plot(
const std::string& name,
const std::vector<double>& x,
const std::vector<double>& y,
const std::string& format =
"") {
513 return named_plot<double>(name,x,y,format);
void ylim(Numeric left, Numeric right)
Definition: matplotlibcpp.h:256
PyObject * s_python_function_show
Definition: matplotlibcpp.h:41
PyObject * s_python_function_ylim
Definition: matplotlibcpp.h:47
void title(const std::string &titlestr)
Definition: matplotlibcpp.h:292
void grid(bool flag)
Definition: matplotlibcpp.h:342
PyObject * s_python_function_xlabel
Definition: matplotlibcpp.h:50
PyObject * s_python_function_grid
Definition: matplotlibcpp.h:52
PyObject * s_python_function_xlim
Definition: matplotlibcpp.h:46
PyObject * s_python_function_title
Definition: matplotlibcpp.h:48
bool plot(const std::vector< Numeric > &x, const std::vector< Numeric > &y, const std::map< std::string, std::string > &keywords)
Definition: matplotlibcpp.h:141
void legend()
Definition: matplotlibcpp.h:248
static _interpreter & get()
Definition: matplotlibcpp.h:62
void ylabel(const std::string &str)
Definition: matplotlibcpp.h:330
PyObject * s_python_function_plot
Definition: matplotlibcpp.h:44
PyObject * s_python_function_save
Definition: matplotlibcpp.h:42
PyObject * s_python_function_figure
Definition: matplotlibcpp.h:43
Definition: matplotlibcpp.h:37
Definition: matplotlibcpp.h:40
PyObject * s_python_function_legend
Definition: matplotlibcpp.h:45
PyObject * s_python_function_axis
Definition: matplotlibcpp.h:49
void xlim(Numeric left, Numeric right)
Definition: matplotlibcpp.h:274
void xlabel(const std::string &str)
Definition: matplotlibcpp.h:318
PyObject * s_python_function_ylabel
Definition: matplotlibcpp.h:51
void save(const std::string &filename)
Definition: matplotlibcpp.h:365
void axis(const std::string &axisstr)
Definition: matplotlibcpp.h:304
bool named_plot(const std::string &name, const std::vector< Numeric > &x, const std::vector< Numeric > &y, const std::string &format="")
Definition: matplotlibcpp.h:210
void show()
Definition: matplotlibcpp.h:357
PyObject * s_python_empty_tuple
Definition: matplotlibcpp.h:53