1
0
Эх сурвалжийг харах

Add experimental documentation target

Add experimental `docs` target to create automated
API documentation.

Also moved all internal things into one unified
namespace `detail`.
Benno Evers 5 жил өмнө
parent
commit
41477fcdb6
2 өөрчлөгдсөн 83 нэмэгдсэн , 65 устгасан
  1. 5 1
      Makefile
  2. 78 64
      matplotlibcpp.h

+ 5 - 1
Makefile

@@ -25,8 +25,12 @@ EXAMPLE_TARGETS := $(patsubst %,examples/build/%,$(EXAMPLES))
 
 examples: $(EXAMPLE_TARGETS)
 
+docs:
+	doxygen
+	moxygen doc/xml --noindex -o doc/api.md
+
 # Assume every *.cpp file is a separate example
-$(EXAMPLE_TARGETS): examples/build/%: examples/%.cpp
+$(EXAMPLE_TARGETS): examples/build/%: examples/%.cpp matplotlibcpp.h
 	mkdir -p examples/build
 	$(CXX) -o $@ $< $(EXTRA_FLAGS) $(CXXFLAGS) $(LDFLAGS)
 

+ 78 - 64
matplotlibcpp.h

@@ -242,7 +242,15 @@ private:
 
 } // end namespace detail
 
-// must be called before the first regular call to matplotlib to have any effect
+/// Select the backend
+///
+/// **NOTE:** This must be called before the first plot command to have
+/// any effect.
+///
+/// Mainly useful to select the non-interactive 'Agg' backend when running
+/// matplotlibcpp in headless mode, for example on a machine with no display.
+///
+/// See also: https://matplotlib.org/2.0.2/api/matplotlib_configuration_api.html#matplotlib.use
 inline void backend(const std::string& name)
 {
     detail::s_backend = name;
@@ -272,6 +280,8 @@ inline bool annotate(std::string annotation, double x, double y)
     return res;
 }
 
+namespace detail {
+
 #ifndef WITHOUT_NUMPY
 // Type selector for numpy array conversion
 template <typename T> struct select_npy_type { const static NPY_TYPES type = NPY_NOTYPE; }; //Default
@@ -365,14 +375,19 @@ PyObject* get_array(const std::vector<Numeric>& v)
 
 #endif // WITHOUT_NUMPY
 
+} // namespace detail
+
+/// Plot a line through the given x and y data points..
+/// 
+/// See: https://matplotlib.org/3.2.1/api/_as_gen/matplotlib.pyplot.plot.html
 template<typename Numeric>
 bool plot(const std::vector<Numeric> &x, const std::vector<Numeric> &y, const std::map<std::string, std::string>& keywords)
 {
     assert(x.size() == y.size());
 
     // using numpy arrays
-    PyObject* xarray = get_array(x);
-    PyObject* yarray = get_array(y);
+    PyObject* xarray = detail::get_array(x);
+    PyObject* yarray = detail::get_array(y);
 
     // construct positional args
     PyObject* args = PyTuple_New(2);
@@ -396,7 +411,7 @@ bool plot(const std::vector<Numeric> &x, const std::vector<Numeric> &y, const st
 }
 
 // TODO - it should be possible to make this work by implementing
-// a non-numpy alternative for `get_2darray()`.
+// a non-numpy alternative for `detail::get_2darray()`.
 #ifndef WITHOUT_NUMPY
 template <typename Numeric>
 void plot_surface(const std::vector<::std::vector<Numeric>> &x,
@@ -430,9 +445,9 @@ void plot_surface(const std::vector<::std::vector<Numeric>> &x,
   assert(y.size() == z.size());
 
   // using numpy arrays
-  PyObject *xarray = get_2darray(x);
-  PyObject *yarray = get_2darray(y);
-  PyObject *zarray = get_2darray(z);
+  PyObject *xarray = detail::get_2darray(x);
+  PyObject *yarray = detail::get_2darray(y);
+  PyObject *zarray = detail::get_2darray(z);
 
   // construct positional args
   PyObject *args = PyTuple_New(3);
@@ -522,9 +537,9 @@ void plot3(const std::vector<Numeric> &x,
   assert(x.size() == y.size());
   assert(y.size() == z.size());
 
-  PyObject *xarray = get_array(x);
-  PyObject *yarray = get_array(y);
-  PyObject *zarray = get_array(z);
+  PyObject *xarray = detail::get_array(x);
+  PyObject *yarray = detail::get_array(y);
+  PyObject *zarray = detail::get_array(z);
 
   // construct positional args
   PyObject *args = PyTuple_New(3);
@@ -580,8 +595,8 @@ bool stem(const std::vector<Numeric> &x, const std::vector<Numeric> &y, const st
     assert(x.size() == y.size());
 
     // using numpy arrays
-    PyObject* xarray = get_array(x);
-    PyObject* yarray = get_array(y);
+    PyObject* xarray = detail::get_array(x);
+    PyObject* yarray = detail::get_array(y);
 
     // construct positional args
     PyObject* args = PyTuple_New(2);
@@ -613,8 +628,8 @@ bool fill(const std::vector<Numeric>& x, const std::vector<Numeric>& y, const st
     assert(x.size() == y.size());
 
     // using numpy arrays
-    PyObject* xarray = get_array(x);
-    PyObject* yarray = get_array(y);
+    PyObject* xarray = detail::get_array(x);
+    PyObject* yarray = detail::get_array(y);
 
     // construct positional args
     PyObject* args = PyTuple_New(2);
@@ -644,9 +659,9 @@ bool fill_between(const std::vector<Numeric>& x, const std::vector<Numeric>& y1,
     assert(x.size() == y2.size());
 
     // using numpy arrays
-    PyObject* xarray = get_array(x);
-    PyObject* y1array = get_array(y1);
-    PyObject* y2array = get_array(y2);
+    PyObject* xarray = detail::get_array(x);
+    PyObject* y1array = detail::get_array(y1);
+    PyObject* y2array = detail::get_array(y2);
 
     // construct positional args
     PyObject* args = PyTuple_New(3);
@@ -674,7 +689,7 @@ bool hist(const std::vector<Numeric>& y, long bins=10,std::string color="b",
           double alpha=1.0, bool cumulative=false)
 {
 
-    PyObject* yarray = get_array(y);
+    PyObject* yarray = detail::get_array(y);
 
     PyObject* kwargs = PyDict_New();
     PyDict_SetItemString(kwargs, "bins", PyLong_FromLong(bins));
@@ -698,7 +713,7 @@ bool hist(const std::vector<Numeric>& y, long bins=10,std::string color="b",
 }
 
 #ifndef WITHOUT_NUMPY
-namespace internal {
+namespace detail {
 
 inline void imshow(void *ptr, const NPY_TYPES type, const int rows, const int columns, const int colors, const std::map<std::string, std::string> &keywords, PyObject** out)
 {
@@ -730,16 +745,16 @@ inline void imshow(void *ptr, const NPY_TYPES type, const int rows, const int co
         Py_DECREF(res);
 }
 
-} // namespace internal
+} // namespace detail
 
 inline void imshow(const unsigned char *ptr, const int rows, const int columns, const int colors, const std::map<std::string, std::string> &keywords = {}, PyObject** out = nullptr)
 {
-    internal::imshow((void *) ptr, NPY_UINT8, rows, columns, colors, keywords, out);
+    detail::imshow((void *) ptr, NPY_UINT8, rows, columns, colors, keywords, out);
 }
 
 inline void imshow(const float *ptr, const int rows, const int columns, const int colors, const std::map<std::string, std::string> &keywords = {}, PyObject** out = nullptr)
 {
-    internal::imshow((void *) ptr, NPY_FLOAT, rows, columns, colors, keywords, out);
+    detail::imshow((void *) ptr, NPY_FLOAT, rows, columns, colors, keywords, out);
 }
 
 #ifdef WITH_OPENCV
@@ -769,7 +784,7 @@ void imshow(const cv::Mat &image, const std::map<std::string, std::string> &keyw
         cv::cvtColor(image2, image2, CV_BGRA2RGBA);
     }
 
-    internal::imshow(image2.data, npy_type, image2.rows, image2.cols, image2.channels(), keywords);
+    detail::imshow(image2.data, npy_type, image2.rows, image2.cols, image2.channels(), keywords);
 }
 #endif // WITH_OPENCV
 #endif // WITHOUT_NUMPY
@@ -782,8 +797,8 @@ bool scatter(const std::vector<NumericX>& x,
 {
     assert(x.size() == y.size());
 
-    PyObject* xarray = get_array(x);
-    PyObject* yarray = get_array(y);
+    PyObject* xarray = detail::get_array(x);
+    PyObject* yarray = detail::get_array(y);
 
     PyObject* kwargs = PyDict_New();
     PyDict_SetItemString(kwargs, "s", PyLong_FromLong(s));
@@ -810,7 +825,7 @@ bool boxplot(const std::vector<std::vector<Numeric>>& data,
              const std::vector<std::string>& labels = {},
              const std::unordered_map<std::string, std::string> & keywords = {})
 {
-    PyObject* listlist = get_listlist(data);
+    PyObject* listlist = detail::get_listlist(data);
     PyObject* args = PyTuple_New(1);
     PyTuple_SetItem(args, 0, listlist);
 
@@ -818,7 +833,7 @@ bool boxplot(const std::vector<std::vector<Numeric>>& data,
 
     // kwargs needs the labels, if there are (the correct number of) labels
     if (!labels.empty() && labels.size() == data.size()) {
-        PyDict_SetItemString(kwargs, "labels", get_array(labels));
+        PyDict_SetItemString(kwargs, "labels", detail::get_array(labels));
     }
 
     // take care of the remaining keywords
@@ -841,7 +856,7 @@ template<typename Numeric>
 bool boxplot(const std::vector<Numeric>& data,
              const std::unordered_map<std::string, std::string> & keywords = {})
 {
-    PyObject* vector = get_array(data);
+    PyObject* vector = detail::get_array(data);
     PyObject* args = PyTuple_New(1);
     PyTuple_SetItem(args, 0, vector);
 
@@ -868,8 +883,8 @@ bool bar(const std::vector<Numeric> &               x,
          std::string                                ls       = "-",
          double                                     lw       = 1.0,
          const std::map<std::string, std::string> & keywords = {}) {
-  PyObject * xarray = get_array(x);
-  PyObject * yarray = get_array(y);
+  PyObject * xarray = detail::get_array(x);
+  PyObject * yarray = detail::get_array(y);
 
   PyObject * kwargs = PyDict_New();
 
@@ -938,7 +953,7 @@ inline bool subplots_adjust(const std::map<std::string, double>& keywords = {})
 template< typename Numeric>
 bool named_hist(std::string label,const std::vector<Numeric>& y, long bins=10, std::string color="b", double alpha=1.0)
 {
-    PyObject* yarray = get_array(y);
+    PyObject* yarray = detail::get_array(y);
 
     PyObject* kwargs = PyDict_New();
     PyDict_SetItemString(kwargs, "label", PyString_FromString(label.c_str()));
@@ -964,8 +979,8 @@ bool plot(const std::vector<NumericX>& x, const std::vector<NumericY>& y, const
 {
     assert(x.size() == y.size());
 
-    PyObject* xarray = get_array(x);
-    PyObject* yarray = get_array(y);
+    PyObject* xarray = detail::get_array(x);
+    PyObject* yarray = detail::get_array(y);
 
     PyObject* pystring = PyString_FromString(s.c_str());
 
@@ -987,10 +1002,10 @@ bool quiver(const std::vector<NumericX>& x, const std::vector<NumericY>& y, cons
 {
     assert(x.size() == y.size() && x.size() == u.size() && u.size() == w.size());
 
-    PyObject* xarray = get_array(x);
-    PyObject* yarray = get_array(y);
-    PyObject* uarray = get_array(u);
-    PyObject* warray = get_array(w);
+    PyObject* xarray = detail::get_array(x);
+    PyObject* yarray = detail::get_array(y);
+    PyObject* uarray = detail::get_array(u);
+    PyObject* warray = detail::get_array(w);
 
     PyObject* plot_args = PyTuple_New(4);
     PyTuple_SetItem(plot_args, 0, xarray);
@@ -1021,8 +1036,8 @@ bool stem(const std::vector<NumericX>& x, const std::vector<NumericY>& y, const
 {
     assert(x.size() == y.size());
 
-    PyObject* xarray = get_array(x);
-    PyObject* yarray = get_array(y);
+    PyObject* xarray = detail::get_array(x);
+    PyObject* yarray = detail::get_array(y);
 
     PyObject* pystring = PyString_FromString(s.c_str());
 
@@ -1046,8 +1061,8 @@ bool semilogx(const std::vector<NumericX>& x, const std::vector<NumericY>& y, co
 {
     assert(x.size() == y.size());
 
-    PyObject* xarray = get_array(x);
-    PyObject* yarray = get_array(y);
+    PyObject* xarray = detail::get_array(x);
+    PyObject* yarray = detail::get_array(y);
 
     PyObject* pystring = PyString_FromString(s.c_str());
 
@@ -1069,8 +1084,8 @@ bool semilogy(const std::vector<NumericX>& x, const std::vector<NumericY>& y, co
 {
     assert(x.size() == y.size());
 
-    PyObject* xarray = get_array(x);
-    PyObject* yarray = get_array(y);
+    PyObject* xarray = detail::get_array(x);
+    PyObject* yarray = detail::get_array(y);
 
     PyObject* pystring = PyString_FromString(s.c_str());
 
@@ -1092,8 +1107,8 @@ bool loglog(const std::vector<NumericX>& x, const std::vector<NumericY>& y, cons
 {
     assert(x.size() == y.size());
 
-    PyObject* xarray = get_array(x);
-    PyObject* yarray = get_array(y);
+    PyObject* xarray = detail::get_array(x);
+    PyObject* yarray = detail::get_array(y);
 
     PyObject* pystring = PyString_FromString(s.c_str());
 
@@ -1115,9 +1130,9 @@ bool errorbar(const std::vector<NumericX> &x, const std::vector<NumericY> &y, co
 {
     assert(x.size() == y.size());
 
-    PyObject* xarray = get_array(x);
-    PyObject* yarray = get_array(y);
-    PyObject* yerrarray = get_array(yerr);
+    PyObject* xarray = detail::get_array(x);
+    PyObject* yarray = detail::get_array(y);
+    PyObject* yerrarray = detail::get_array(yerr);
 
     // construct keyword args
     PyObject* kwargs = PyDict_New();
@@ -1151,7 +1166,7 @@ bool named_plot(const std::string& name, const std::vector<Numeric>& y, const st
     PyObject* kwargs = PyDict_New();
     PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str()));
 
-    PyObject* yarray = get_array(y);
+    PyObject* yarray = detail::get_array(y);
 
     PyObject* pystring = PyString_FromString(format.c_str());
 
@@ -1175,8 +1190,8 @@ bool named_plot(const std::string& name, const std::vector<Numeric>& x, const st
     PyObject* kwargs = PyDict_New();
     PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str()));
 
-    PyObject* xarray = get_array(x);
-    PyObject* yarray = get_array(y);
+    PyObject* xarray = detail::get_array(x);
+    PyObject* yarray = detail::get_array(y);
 
     PyObject* pystring = PyString_FromString(format.c_str());
 
@@ -1200,8 +1215,8 @@ bool named_semilogx(const std::string& name, const std::vector<Numeric>& x, cons
     PyObject* kwargs = PyDict_New();
     PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str()));
 
-    PyObject* xarray = get_array(x);
-    PyObject* yarray = get_array(y);
+    PyObject* xarray = detail::get_array(x);
+    PyObject* yarray = detail::get_array(y);
 
     PyObject* pystring = PyString_FromString(format.c_str());
 
@@ -1225,8 +1240,8 @@ bool named_semilogy(const std::string& name, const std::vector<Numeric>& x, cons
     PyObject* kwargs = PyDict_New();
     PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str()));
 
-    PyObject* xarray = get_array(x);
-    PyObject* yarray = get_array(y);
+    PyObject* xarray = detail::get_array(x);
+    PyObject* yarray = detail::get_array(y);
 
     PyObject* pystring = PyString_FromString(format.c_str());
 
@@ -1250,8 +1265,8 @@ bool named_loglog(const std::string& name, const std::vector<Numeric>& x, const
     PyObject* kwargs = PyDict_New();
     PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str()));
 
-    PyObject* xarray = get_array(x);
-    PyObject* yarray = get_array(y);
+    PyObject* xarray = detail::get_array(x);
+    PyObject* yarray = detail::get_array(y);
 
     PyObject* pystring = PyString_FromString(format.c_str());
 
@@ -1482,7 +1497,7 @@ inline void xticks(const std::vector<Numeric> &ticks, const std::vector<std::str
     assert(labels.size() == 0 || ticks.size() == labels.size());
 
     // using numpy array
-    PyObject* ticksarray = get_array(ticks);
+    PyObject* ticksarray = detail::get_array(ticks);
 
     PyObject* args;
     if(labels.size() == 0) {
@@ -1529,7 +1544,7 @@ inline void yticks(const std::vector<Numeric> &ticks, const std::vector<std::str
     assert(labels.size() == 0 || ticks.size() == labels.size());
 
     // using numpy array
-    PyObject* ticksarray = get_array(ticks);
+    PyObject* ticksarray = detail::get_array(ticks);
 
     PyObject* args;
     if(labels.size() == 0) {
@@ -2096,7 +2111,6 @@ inline bool plot(const std::vector<double>& x, const std::vector<double>& y, con
 /*
  * This class allows dynamic plots, ie changing the plotted data without clearing and re-plotting
  */
-
 class Plot
 {
 public:
@@ -2110,8 +2124,8 @@ public:
         if(name != "")
             PyDict_SetItemString(kwargs, "label", PyString_FromString(name.c_str()));
 
-        PyObject* xarray = get_array(x);
-        PyObject* yarray = get_array(y);
+        PyObject* xarray = detail::get_array(x);
+        PyObject* yarray = detail::get_array(y);
 
         PyObject* pystring = PyString_FromString(format.c_str());
 
@@ -2147,8 +2161,8 @@ public:
         assert(x.size() == y.size());
         if(set_data_fct)
         {
-            PyObject* xarray = get_array(x);
-            PyObject* yarray = get_array(y);
+            PyObject* xarray = detail::get_array(x);
+            PyObject* yarray = detail::get_array(y);
 
             PyObject* plot_args = PyTuple_New(2);
             PyTuple_SetItem(plot_args, 0, xarray);