@@ -53,6 +53,8 @@ struct _interpreter {
53
53
PyObject *s_python_function_fignum_exists;
54
54
PyObject *s_python_function_plot;
55
55
PyObject *s_python_function_quiver;
56
+ PyObject *s_python_function_contour;
57
+ PyObject *s_python_function_colormap;
56
58
PyObject *s_python_function_axhline;
57
59
PyObject *s_python_function_axvline;
58
60
PyObject *s_python_function_semilogx;
@@ -184,6 +186,7 @@ struct _interpreter {
184
186
PyObject_GetAttrString (pymod, " fignum_exists" );
185
187
s_python_function_plot = PyObject_GetAttrString (pymod, " plot" );
186
188
s_python_function_quiver = PyObject_GetAttrString (pymod, " quiver" );
189
+ s_python_function_contour = PyObject_GetAttrString (pymod, " contour" );
187
190
s_python_function_axhline = PyObject_GetAttrString (pymod, " axhline" );
188
191
s_python_function_axvline = PyObject_GetAttrString (pymod, " axvline" );
189
192
s_python_function_semilogx = PyObject_GetAttrString (pymod, " semilogx" );
@@ -228,6 +231,7 @@ struct _interpreter {
228
231
!s_python_function_draw || !s_python_function_pause ||
229
232
!s_python_function_figure || !s_python_function_fignum_exists ||
230
233
!s_python_function_plot || !s_python_function_quiver ||
234
+ !s_python_function_contour ||
231
235
!s_python_function_semilogx || !s_python_function_semilogy ||
232
236
!s_python_function_loglog || !s_python_function_fill ||
233
237
!s_python_function_fill_between || !s_python_function_subplot ||
@@ -256,6 +260,7 @@ struct _interpreter {
256
260
!PyFunction_Check (s_python_function_fignum_exists) ||
257
261
!PyFunction_Check (s_python_function_plot) ||
258
262
!PyFunction_Check (s_python_function_quiver) ||
263
+ !PyFunction_Check (s_python_function_contour) ||
259
264
!PyFunction_Check (s_python_function_semilogx) ||
260
265
!PyFunction_Check (s_python_function_semilogy) ||
261
266
!PyFunction_Check (s_python_function_loglog) ||
@@ -760,6 +765,53 @@ void plot_surface(const Matrix &x, const Matrix& y, const Matrix& z,
760
765
Py_DECREF (res);
761
766
}
762
767
768
+
769
+ // @brief plot_surface for datapoints (x_ij, y_ij, z_ij) with i,j = 0..n
770
+ // @param x The x values of the datapoints in a matrix
771
+ // @param y The y values of the datapoints in a matrix
772
+ // @param z The function value of the datapoints in a matrix
773
+ // @param keywords Additional keywords
774
+ template <typename Matrix>
775
+ void contour (const Matrix &x, const Matrix& y, const Matrix& z,
776
+ const std::map<std::string, std::string> &keywords = {}) {
777
+ detail::_interpreter::get ();
778
+
779
+ // using numpy arrays
780
+ PyObject *xarray = get_2darray (x);
781
+ PyObject *yarray = get_2darray (y);
782
+ PyObject *zarray = get_2darray (z);
783
+
784
+ // construct positional args
785
+ PyObject *args = PyTuple_New (3 );
786
+ PyTuple_SetItem (args, 0 , xarray);
787
+ PyTuple_SetItem (args, 1 , yarray);
788
+ PyTuple_SetItem (args, 2 , zarray);
789
+
790
+ // Build up the kw args.
791
+ PyObject *kwargs = PyDict_New ();
792
+
793
+ PyObject *python_colormap_coolwarm = PyObject_GetAttrString (
794
+ detail::_interpreter::get ().s_python_colormap , " coolwarm" );
795
+
796
+ PyDict_SetItemString (kwargs, " cmap" , python_colormap_coolwarm);
797
+
798
+ for (std::map<std::string, std::string>::const_iterator it = keywords.begin ();
799
+ it != keywords.end (); ++it) {
800
+ PyDict_SetItemString (kwargs, it->first .c_str (),
801
+ PyString_FromString (it->second .c_str ()));
802
+ }
803
+
804
+ PyObject *res = PyObject_Call (detail::_interpreter::get ().s_python_function_contour ,
805
+ args, kwargs);
806
+ if (!res)
807
+ throw std::runtime_error (" failed surface" );
808
+
809
+ Py_DECREF (args);
810
+ Py_DECREF (kwargs);
811
+ if (res)
812
+ Py_DECREF (res);
813
+ }
814
+
763
815
template <typename Numeric>
764
816
bool stem (const std::vector<Numeric> &x, const std::vector<Numeric> &y,
765
817
const std::map<std::string, std::string> &keywords) {
@@ -893,16 +945,23 @@ bool hist(const VectorY &y, long bins = 10, std::string color = "b",
893
945
// @brief Scatter plot
894
946
// @param x x-coordinates of the 2d points
895
947
// @param y y-coordinates of the 2d points
896
- // @param s the marker size in points**2
948
+ // @param s the marker size in points**2
949
+ // @param keywords Additional keywords
897
950
template <typename VectorX, typename VectorY>
898
- bool scatter (const VectorX &x, const VectorY &y, const double s = 1.0 ) {
951
+ bool scatter (const VectorX &x, const VectorY &y, const double s = 1.0 ,
952
+ const std::map<std::string, std::string> keywords = {}) {
899
953
assert (x.size () == y.size ());
900
954
901
955
PyObject *xarray = get_array (x);
902
956
PyObject *yarray = get_array (y);
903
957
904
958
PyObject *kwargs = PyDict_New ();
905
- PyDict_SetItemString (kwargs, " s" , PyLong_FromLong (s));
959
+ PyDict_SetItemString (kwargs, " s" , PyFloat_FromDouble (s));
960
+ for (std::map<std::string, std::string>::const_iterator it = keywords.begin ();
961
+ it != keywords.end (); ++it) {
962
+ PyDict_SetItemString (kwargs, it->first .c_str (),
963
+ PyUnicode_FromString (it->second .c_str ()));
964
+ }
906
965
907
966
PyObject *plot_args = PyTuple_New (2 );
908
967
PyTuple_SetItem (plot_args, 0 , xarray);
@@ -919,6 +978,13 @@ bool scatter(const VectorX &x, const VectorY &y, const double s = 1.0) {
919
978
return res;
920
979
}
921
980
981
+ template <typename VectorX, typename VectorY>
982
+ bool scatter (const VectorX &x, const VectorY &y,
983
+ const std::map<std::string, std::string>& keywords) {
984
+ return scatter (x, y, 1.0 , keywords);
985
+ }
986
+
987
+
922
988
// @brief Spy plot
923
989
// @param A the matrix
924
990
// @param precision Plot all elements above `|precision|`
0 commit comments