@@ -57,6 +57,7 @@ struct _interpreter {
57
57
PyObject *s_python_function_plot;
58
58
PyObject *s_python_function_quiver;
59
59
PyObject* s_python_function_contour;
60
+ PyObject* s_python_function_contourf;
60
61
PyObject *s_python_function_semilogx;
61
62
PyObject *s_python_function_semilogy;
62
63
PyObject *s_python_function_loglog;
@@ -234,6 +235,7 @@ struct _interpreter {
234
235
s_python_function_plot = safe_import (pymod, " plot" );
235
236
s_python_function_quiver = safe_import (pymod, " quiver" );
236
237
s_python_function_contour = safe_import (pymod, " contour" );
238
+ s_python_function_contourf = safe_import (pymod, " contourf" );
237
239
s_python_function_semilogx = safe_import (pymod, " semilogx" );
238
240
s_python_function_semilogy = safe_import (pymod, " semilogy" );
239
241
s_python_function_loglog = safe_import (pymod, " loglog" );
@@ -610,10 +612,9 @@ void contour(const std::vector<::std::vector<Numeric>> &x,
610
612
611
613
PyDict_SetItemString (kwargs, " cmap" , python_colormap_coolwarm);
612
614
613
- for (std::map<std::string, std::string>::const_iterator it = keywords.begin ();
614
- it != keywords.end (); ++it) {
615
- PyDict_SetItemString (kwargs, it->first .c_str (),
616
- PyString_FromString (it->second .c_str ()));
615
+ for (const auto & keyword : keywords) {
616
+ PyDict_SetItemString (kwargs, keyword.first .c_str (),
617
+ PyString_FromString (keyword.second .c_str ()));
617
618
}
618
619
619
620
PyObject *res = PyObject_Call (detail::_interpreter::get ().s_python_function_contour , args, kwargs);
@@ -625,6 +626,47 @@ void contour(const std::vector<::std::vector<Numeric>> &x,
625
626
if (res) Py_DECREF (res);
626
627
}
627
628
629
+ template <typename Numeric>
630
+ void contourf (const std::vector<::std::vector<Numeric>> &x,
631
+ const std::vector<::std::vector<Numeric>> &y,
632
+ const std::vector<::std::vector<Numeric>> &z,
633
+ const std::map<std::string, std::string> &keywords = {})
634
+ {
635
+ detail::_interpreter::get ();
636
+
637
+ // using numpy arrays
638
+ PyObject *xarray = detail::get_2darray (x);
639
+ PyObject *yarray = detail::get_2darray (y);
640
+ PyObject *zarray = detail::get_2darray (z);
641
+
642
+ // construct positional args
643
+ PyObject *args = PyTuple_New (3 );
644
+ PyTuple_SetItem (args, 0 , xarray);
645
+ PyTuple_SetItem (args, 1 , yarray);
646
+ PyTuple_SetItem (args, 2 , zarray);
647
+
648
+ // Build up the kw args.
649
+ PyObject *kwargs = PyDict_New ();
650
+
651
+ PyObject *python_colormap_coolwarm = PyObject_GetAttrString (
652
+ detail::_interpreter::get ().s_python_colormap , " coolwarm" );
653
+
654
+ PyDict_SetItemString (kwargs, " cmap" , python_colormap_coolwarm);
655
+
656
+ for (const auto & keyword : keywords) {
657
+ PyDict_SetItemString (kwargs, keyword.first .c_str (),
658
+ PyString_FromString (keyword.second .c_str ()));
659
+ }
660
+
661
+ PyObject *res = PyObject_Call (detail::_interpreter::get ().s_python_function_contourf , args, kwargs);
662
+ if (!res)
663
+ throw std::runtime_error (" failed contourf" );
664
+
665
+ Py_DECREF (args);
666
+ Py_DECREF (kwargs);
667
+ if (res) Py_DECREF (res);
668
+ }
669
+
628
670
template <typename Numeric>
629
671
void spy (const std::vector<::std::vector<Numeric>> &x,
630
672
const double markersize = -1 , // -1 for default matplotlib size
@@ -1396,9 +1438,8 @@ bool contour(const std::vector<NumericX>& x, const std::vector<NumericY>& y,
1396
1438
1397
1439
// construct keyword args
1398
1440
PyObject* kwargs = PyDict_New ();
1399
- for (std::map<std::string, std::string>::const_iterator it = keywords.begin ();
1400
- it != keywords.end (); ++it) {
1401
- PyDict_SetItemString (kwargs, it->first .c_str (), PyUnicode_FromString (it->second .c_str ()));
1441
+ for (const auto & keyword : keywords) {
1442
+ PyDict_SetItemString (kwargs, keyword.first .c_str (), PyUnicode_FromString (keyword.second .c_str ()));
1402
1443
}
1403
1444
1404
1445
PyObject* res =
@@ -1412,6 +1453,38 @@ bool contour(const std::vector<NumericX>& x, const std::vector<NumericY>& y,
1412
1453
return res;
1413
1454
}
1414
1455
1456
+ template <typename NumericX, typename NumericY, typename NumericZ>
1457
+ bool contourf (const std::vector<NumericX>& x, const std::vector<NumericY>& y,
1458
+ const std::vector<NumericZ>& z,
1459
+ const std::map<std::string, std::string>& keywords = {}) {
1460
+ assert (x.size () == y.size () && x.size () == z.size ());
1461
+
1462
+ PyObject* xarray = detail::get_array (x);
1463
+ PyObject* yarray = detail::get_array (y);
1464
+ PyObject* zarray = detail::get_array (z);
1465
+
1466
+ PyObject* plot_args = PyTuple_New (3 );
1467
+ PyTuple_SetItem (plot_args, 0 , xarray);
1468
+ PyTuple_SetItem (plot_args, 1 , yarray);
1469
+ PyTuple_SetItem (plot_args, 2 , zarray);
1470
+
1471
+ // construct keyword args
1472
+ PyObject* kwargs = PyDict_New ();
1473
+ for (const auto & keyword : keywords) {
1474
+ PyDict_SetItemString (kwargs, keyword.first .c_str (), PyUnicode_FromString (keyword.second .c_str ()));
1475
+ }
1476
+
1477
+ PyObject* res =
1478
+ PyObject_Call (detail::_interpreter::get ().s_python_function_contourf , plot_args, kwargs);
1479
+
1480
+ Py_DECREF (kwargs);
1481
+ Py_DECREF (plot_args);
1482
+ if (res)
1483
+ Py_DECREF (res);
1484
+
1485
+ return res;
1486
+ }
1487
+
1415
1488
template <typename NumericX, typename NumericY, typename NumericU, typename NumericW>
1416
1489
bool quiver (const std::vector<NumericX>& x, const std::vector<NumericY>& y, const std::vector<NumericU>& u, const std::vector<NumericW>& w, const std::map<std::string, std::string>& keywords = {})
1417
1490
{
0 commit comments