66#include < algorithm>
77#include < stdexcept>
88#include < iostream>
9+ #include < stdint.h> // <cstdint> requires c++11 support
910
1011#if __cplusplus > 199711L || _MSC_VER > 1800
1112#include < functional>
1213#endif
1314
14- // i.e. g++ -DMATPLOTLIBCPP_PYTHON_HEADER=/usr/include/python3.6/Python.h [...]
15- #ifdef MATPLOTLIBCPP_PYTHON_HEADER
16- #define STRINGIFY_ (x ) #x
17- #define STRINGIFY (x ) STRINGIFY_(x)
18- #include STRINGIFY(MATPLOTLIBCPP_PYTHON_HEADER)
19- #else // This should stay the default for backwards compatibility
20- #include < python2.7/Python.h>
21- #endif
15+ #include < Python.h>
16+
17+ #ifndef WITHOUT_NUMPY
18+ #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
19+ #include < numpy/arrayobject.h>
20+ #endif // WITHOUT_NUMPY
2221
2322#if PY_MAJOR_VERSION >= 3
2423#define PyString_FromString PyUnicode_FromString
2524#endif
2625
27- #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
28- #include < numpy/arrayobject.h>
2926
3027namespace matplotlibcpp {
3128
@@ -68,14 +65,16 @@ namespace matplotlibcpp {
6865
6966 // optional but recommended
7067#if PY_MAJOR_VERSION >= 3
71- wchar_t name[] = L" plotting" ;
68+ wchar_t name[] = L" plotting" ;
7269#else
73- char name[] = " plotting" ;
70+ char name[] = " plotting" ;
7471#endif
7572 Py_SetProgramName (name);
7673 Py_Initialize ();
7774
75+ #ifndef WITHOUT_NUMPY
7876 import_array (); // initialize numpy C-API
77+ #endif
7978
8079 PyObject* pyplotname = PyString_FromString (" matplotlib.pyplot" );
8180 PyObject* pylabname = PyString_FromString (" pylab" );
@@ -182,19 +181,21 @@ namespace matplotlibcpp {
182181
183182 return res;
184183 }
184+
185+ #ifndef WITHOUT_NUMPY
185186 // Type selector for numpy array conversion
186187 template <typename T> struct select_npy_type { const static NPY_TYPES type = NPY_NOTYPE; }; // Default
187188 template <> struct select_npy_type <double > { const static NPY_TYPES type = NPY_DOUBLE; };
188189 template <> struct select_npy_type <float > { const static NPY_TYPES type = NPY_FLOAT; };
189190 template <> struct select_npy_type <bool > { const static NPY_TYPES type = NPY_BOOL; };
190- template <> struct select_npy_type <std:: int8_t > { const static NPY_TYPES type = NPY_INT8; };
191- template <> struct select_npy_type <std:: int16_t > { const static NPY_TYPES type = NPY_SHORT; };
192- template <> struct select_npy_type <std:: int32_t > { const static NPY_TYPES type = NPY_INT; };
193- template <> struct select_npy_type <std:: int64_t > { const static NPY_TYPES type = NPY_INT64; };
194- template <> struct select_npy_type <std:: uint8_t > { const static NPY_TYPES type = NPY_UINT8; };
195- template <> struct select_npy_type <std:: uint16_t > { const static NPY_TYPES type = NPY_USHORT; };
196- template <> struct select_npy_type <std:: uint32_t > { const static NPY_TYPES type = NPY_ULONG; };
197- template <> struct select_npy_type <std:: uint64_t > { const static NPY_TYPES type = NPY_UINT64; };
191+ template <> struct select_npy_type <int8_t > { const static NPY_TYPES type = NPY_INT8; };
192+ template <> struct select_npy_type <int16_t > { const static NPY_TYPES type = NPY_SHORT; };
193+ template <> struct select_npy_type <int32_t > { const static NPY_TYPES type = NPY_INT; };
194+ template <> struct select_npy_type <int64_t > { const static NPY_TYPES type = NPY_INT64; };
195+ template <> struct select_npy_type <uint8_t > { const static NPY_TYPES type = NPY_UINT8; };
196+ template <> struct select_npy_type <uint16_t > { const static NPY_TYPES type = NPY_USHORT; };
197+ template <> struct select_npy_type <uint32_t > { const static NPY_TYPES type = NPY_ULONG; };
198+ template <> struct select_npy_type <uint64_t > { const static NPY_TYPES type = NPY_UINT64; };
198199
199200 template <typename Numeric>
200201 PyObject* get_array (const std::vector<Numeric>& v)
@@ -203,18 +204,32 @@ namespace matplotlibcpp {
203204 NPY_TYPES type = select_npy_type<Numeric>::type;
204205 if (type == NPY_NOTYPE)
205206 {
206- std::vector<double > vd (v.size ());
207- npy_intp vsize = v.size ();
208- std::copy (v.begin (),v.end (),vd.begin ());
209- PyObject* varray = PyArray_SimpleNewFromData (1 , &vsize, NPY_DOUBLE, (void *)(vd.data ()));
210- return varray;
207+ std::vector<double > vd (v.size ());
208+ npy_intp vsize = v.size ();
209+ std::copy (v.begin (),v.end (),vd.begin ());
210+ PyObject* varray = PyArray_SimpleNewFromData (1 , &vsize, NPY_DOUBLE, (void *)(vd.data ()));
211+ return varray;
211212 }
212213
213214 npy_intp vsize = v.size ();
214215 PyObject* varray = PyArray_SimpleNewFromData (1 , &vsize, type, (void *)(v.data ()));
215216 return varray;
216217 }
217218
219+ #else // fallback if we don't have numpy: copy every element of the given vector
220+
221+ template <typename Numeric>
222+ PyObject* get_array (const std::vector<Numeric>& v)
223+ {
224+ PyObject* list = PyList_New (v.size ());
225+ for (size_t i = 0 ; i < v.size (); ++i) {
226+ PyList_SetItem (list, i, PyFloat_FromDouble (v.at (i)));
227+ }
228+ return list;
229+ }
230+
231+ #endif // WITHOUT_NUMPY
232+
218233 template <typename Numeric>
219234 bool plot (const std::vector<Numeric> &x, const std::vector<Numeric> &y, const std::map<std::string, std::string>& keywords)
220235 {
0 commit comments