Browse Source

Add fill plot with example

Tobias Tschirch 6 năm trước cách đây
mục cha
commit
d89878b950
4 tập tin đã thay đổi với 78 bổ sung4 xóa
  1. 8 2
      Makefile
  2. 35 0
      examples/fill.cpp
  3. BIN
      examples/fill.png
  4. 35 2
      matplotlibcpp.h

+ 8 - 2
Makefile

@@ -1,4 +1,4 @@
-examples: minimal basic modern animation nonblock xkcd quiver bar surface
+examples: minimal basic modern animation nonblock xkcd quiver bar surface fill_inbetween fill
 
 minimal: examples/minimal.cpp matplotlibcpp.h
 	cd examples && g++ -DWITHOUT_NUMPY minimal.cpp -I/usr/include/python2.7 -lpython2.7 -o minimal -std=c++11
@@ -27,5 +27,11 @@ bar: examples/bar.cpp matplotlibcpp.h
 surface: examples/surface.cpp matplotlibcpp.h
 	cd examples && g++ surface.cpp -I/usr/include/python2.7 -lpython2.7 -o surface -std=c++11
 
+fill_inbetween: examples/fill_inbetween.cpp matplotlibcpp.h
+	cd examples && g++ fill_inbetween.cpp -I/usr/include/python2.7 -lpython2.7 -o fill_inbetween -std=c++11
+
+fill: examples/fill.cpp matplotlibcpp.h
+	cd examples && g++ fill.cpp -I/usr/include/python2.7 -lpython2.7 -o fill -std=c++11
+
 clean:
-	rm -f examples/{minimal,basic,modern,animation,nonblock,xkcd,quiver,bar}
+	rm -f examples/{minimal,basic,modern,animation,nonblock,xkcd,quiver,bar,surface,fill_inbetween,fill}

+ 35 - 0
examples/fill.cpp

@@ -0,0 +1,35 @@
+#define _USE_MATH_DEFINES
+#include "../matplotlibcpp.h"
+#include <cmath>
+
+using namespace std;
+namespace plt = matplotlibcpp;
+
+// Example fill plot taken from:
+// https://matplotlib.org/gallery/misc/fill_spiral.html
+int main() {
+    // Prepare data.
+    vector<double> theta;
+    for (double d = 0; d < 8 * M_PI; d += 0.1)
+        theta.push_back(d);
+
+    const int a = 1;
+    const double b = 0.2;
+
+    for (double dt = 0; dt < 2 * M_PI; dt += M_PI/2.0) {
+        vector<double> x1, y1, x2, y2;
+        for (double th : theta) {
+            x1.push_back( a*cos(th + dt) * exp(b*th) );
+            y1.push_back( a*sin(th + dt) * exp(b*th) );
+
+            x2.push_back( a*cos(th + dt + M_PI/4.0) * exp(b*th) );
+            y2.push_back( a*sin(th + dt + M_PI/4.0) * exp(b*th) );
+        }
+
+        x1.insert(x1.end(), x2.rbegin(), x2.rend());
+        y1.insert(y1.end(), y2.rbegin(), y2.rend());
+
+        plt::fill(x1, y1, {});
+    }
+    plt::show();
+}

BIN
examples/fill.png


+ 35 - 2
matplotlibcpp.h

@@ -39,6 +39,7 @@ struct _interpreter {
     PyObject *s_python_function_semilogx;
     PyObject *s_python_function_semilogy;
     PyObject *s_python_function_loglog;
+    PyObject *s_python_function_fill;
     PyObject *s_python_function_fill_between;
     PyObject *s_python_function_hist;
     PyObject *s_python_function_scatter;
@@ -155,6 +156,7 @@ private:
         s_python_function_semilogx = PyObject_GetAttrString(pymod, "semilogx");
         s_python_function_semilogy = PyObject_GetAttrString(pymod, "semilogy");
         s_python_function_loglog = PyObject_GetAttrString(pymod, "loglog");
+        s_python_function_fill = PyObject_GetAttrString(pymod, "fill");
         s_python_function_fill_between = PyObject_GetAttrString(pymod, "fill_between");
         s_python_function_hist = PyObject_GetAttrString(pymod,"hist");
         s_python_function_scatter = PyObject_GetAttrString(pymod,"scatter");
@@ -194,6 +196,7 @@ private:
             || !s_python_function_semilogx
             || !s_python_function_semilogy
             || !s_python_function_loglog
+            || !s_python_function_fill
             || !s_python_function_fill_between
             || !s_python_function_subplot
             || !s_python_function_legend
@@ -231,6 +234,7 @@ private:
             || !PyFunction_Check(s_python_function_semilogx)
             || !PyFunction_Check(s_python_function_semilogy)
             || !PyFunction_Check(s_python_function_loglog)
+            || !PyFunction_Check(s_python_function_fill)
             || !PyFunction_Check(s_python_function_fill_between)
             || !PyFunction_Check(s_python_function_subplot)
             || !PyFunction_Check(s_python_function_legend)
@@ -523,6 +527,36 @@ bool stem(const std::vector<Numeric> &x, const std::vector<Numeric> &y, const st
     return res;
 }
 
+template< typename Numeric >
+bool fill(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);
+
+    // construct positional args
+    PyObject* args = PyTuple_New(2);
+    PyTuple_SetItem(args, 0, xarray);
+    PyTuple_SetItem(args, 1, yarray);
+
+    // construct keyword args
+    PyObject* kwargs = PyDict_New();
+    for (auto it = keywords.begin(); it != keywords.end(); ++it) {
+        PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str()));
+    }
+
+    PyObject* res = PyObject_Call(detail::_interpreter::get().s_python_function_fill, args, kwargs);
+
+    Py_DECREF(args);
+    Py_DECREF(kwargs);
+
+    if (res) Py_DECREF(res);
+
+    return res;
+}
+
 template< typename Numeric >
 bool fill_between(const std::vector<Numeric>& x, const std::vector<Numeric>& y1, const std::vector<Numeric>& y2, const std::map<std::string, std::string>& keywords)
 {
@@ -542,8 +576,7 @@ bool fill_between(const std::vector<Numeric>& x, const std::vector<Numeric>& y1,
 
     // construct keyword args
     PyObject* kwargs = PyDict_New();
-    for(std::map<std::string, std::string>::const_iterator it = keywords.begin(); it != keywords.end(); ++it)
-    {
+    for(std::map<std::string, std::string>::const_iterator it = keywords.begin(); it != keywords.end(); ++it) {
         PyDict_SetItemString(kwargs, it->first.c_str(), PyUnicode_FromString(it->second.c_str()));
     }