@@ -351,9 +351,9 @@ template <> struct select_npy_type<uint64_t> { const static NPY_TYPES type = NPY
351
351
// Sanity checks; comment them out or change the numpy type below if you're compiling on
352
352
// a platform where they don't apply
353
353
static_assert (sizeof (long long ) == 8);
354
- template <> struct select_npy_type <long long > { const static NPY_TYPES type = NPY_INT64; };
354
+ // template <> struct select_npy_type<long long> { const static NPY_TYPES type = NPY_INT64; };
355
355
static_assert (sizeof (unsigned long long ) == 8);
356
- template <> struct select_npy_type <unsigned long long > { const static NPY_TYPES type = NPY_UINT64; };
356
+ // template <> struct select_npy_type<unsigned long long> { const static NPY_TYPES type = NPY_UINT64; };
357
357
358
358
template <typename Numeric>
359
359
PyObject* get_array (const std::vector<Numeric>& v)
@@ -470,6 +470,33 @@ bool plot(const std::vector<Numeric> &x, const std::vector<Numeric> &y, const st
470
470
return res;
471
471
}
472
472
473
+ // FIXME: <https://stackoverflow.com/questions/76077363/why-does-matplotlib-cpp-throw-runtime-exceptions-in-the-3d-examples>
474
+ // Given a figure, create a subplot with a 3d axis and return a pointer to that axis. also calls incref on the axis pointer.
475
+ PyObject* init_3d_axis (PyObject *fig)
476
+ {
477
+ PyObject *asp_kwargs = PyDict_New ();
478
+ PyDict_SetItemString (asp_kwargs, " projection" , PyString_FromString (" 3d" ));
479
+
480
+ PyObject *asp = PyObject_GetAttrString (fig, " add_subplot" );
481
+ Py_INCREF (asp);
482
+ PyObject *tmpax = PyObject_Call (asp, detail::_interpreter::get ().s_python_empty_tuple , asp_kwargs);
483
+ Py_INCREF (tmpax);
484
+
485
+ PyObject *gca = PyObject_GetAttrString (fig, " gca" );
486
+ if (!gca) throw std::runtime_error (" No gca" );
487
+ Py_INCREF (gca);
488
+ PyObject *axis = PyObject_Call (gca, detail::_interpreter::get ().s_python_empty_tuple , detail::_interpreter::get ().s_python_empty_tuple );
489
+
490
+ if (!axis) throw std::runtime_error (" No axis" );
491
+ Py_INCREF (axis);
492
+
493
+ Py_DECREF (gca);
494
+ Py_DECREF (tmpax);
495
+ Py_DECREF (asp);
496
+ return axis;
497
+ }
498
+
499
+
473
500
// TODO - it should be possible to make this work by implementing
474
501
// a non-numpy alternative for `detail::get_2darray()`.
475
502
#ifndef WITHOUT_NUMPY
@@ -555,20 +582,8 @@ void plot_surface(const std::vector<::std::vector<Numeric>> &x,
555
582
Py_DECREF (fig_exists);
556
583
if (!fig) throw std::runtime_error (" Call to figure() failed." );
557
584
558
- PyObject *gca_kwargs = PyDict_New ();
559
- PyDict_SetItemString (gca_kwargs, " projection" , PyString_FromString (" 3d" ));
560
-
561
- PyObject *gca = PyObject_GetAttrString (fig, " gca" );
562
- if (!gca) throw std::runtime_error (" No gca" );
563
- Py_INCREF (gca);
564
- PyObject *axis = PyObject_Call (
565
- gca, detail::_interpreter::get ().s_python_empty_tuple , gca_kwargs);
566
-
567
- if (!axis) throw std::runtime_error (" No axis" );
568
- Py_INCREF (axis);
585
+ PyObject *axis = init_3d_axis (fig);
569
586
570
- Py_DECREF (gca);
571
- Py_DECREF (gca_kwargs);
572
587
573
588
PyObject *plot_surface = PyObject_GetAttrString (axis, " plot_surface" );
574
589
if (!plot_surface) throw std::runtime_error (" No surface" );
@@ -723,20 +738,7 @@ void plot3(const std::vector<Numeric> &x,
723
738
}
724
739
if (!fig) throw std::runtime_error (" Call to figure() failed." );
725
740
726
- PyObject *gca_kwargs = PyDict_New ();
727
- PyDict_SetItemString (gca_kwargs, " projection" , PyString_FromString (" 3d" ));
728
-
729
- PyObject *gca = PyObject_GetAttrString (fig, " gca" );
730
- if (!gca) throw std::runtime_error (" No gca" );
731
- Py_INCREF (gca);
732
- PyObject *axis = PyObject_Call (
733
- gca, detail::_interpreter::get ().s_python_empty_tuple , gca_kwargs);
734
-
735
- if (!axis) throw std::runtime_error (" No axis" );
736
- Py_INCREF (axis);
737
-
738
- Py_DECREF (gca);
739
- Py_DECREF (gca_kwargs);
741
+ PyObject *axis = init_3d_axis (fig);
740
742
741
743
PyObject *plot3 = PyObject_GetAttrString (axis, " plot" );
742
744
if (!plot3) throw std::runtime_error (" No 3D line plot" );
@@ -1126,20 +1128,7 @@ bool scatter(const std::vector<NumericX>& x,
1126
1128
Py_DECREF (fig_exists);
1127
1129
if (!fig) throw std::runtime_error (" Call to figure() failed." );
1128
1130
1129
- PyObject *gca_kwargs = PyDict_New ();
1130
- PyDict_SetItemString (gca_kwargs, " projection" , PyString_FromString (" 3d" ));
1131
-
1132
- PyObject *gca = PyObject_GetAttrString (fig, " gca" );
1133
- if (!gca) throw std::runtime_error (" No gca" );
1134
- Py_INCREF (gca);
1135
- PyObject *axis = PyObject_Call (
1136
- gca, detail::_interpreter::get ().s_python_empty_tuple , gca_kwargs);
1137
-
1138
- if (!axis) throw std::runtime_error (" No axis" );
1139
- Py_INCREF (axis);
1140
-
1141
- Py_DECREF (gca);
1142
- Py_DECREF (gca_kwargs);
1131
+ PyObject *axis = init_3d_axis (fig);
1143
1132
1144
1133
PyObject *plot3 = PyObject_GetAttrString (axis, " scatter" );
1145
1134
if (!plot3) throw std::runtime_error (" No 3D line plot" );
@@ -1496,27 +1485,15 @@ bool quiver(const std::vector<NumericX>& x, const std::vector<NumericY>& y, cons
1496
1485
{
1497
1486
PyDict_SetItemString (kwargs, it->first .c_str (), PyUnicode_FromString (it->second .c_str ()));
1498
1487
}
1499
-
1488
+
1500
1489
// get figure gca to enable 3d projection
1501
1490
PyObject *fig =
1502
1491
PyObject_CallObject (detail::_interpreter::get ().s_python_function_figure ,
1503
1492
detail::_interpreter::get ().s_python_empty_tuple );
1504
1493
if (!fig) throw std::runtime_error (" Call to figure() failed." );
1505
1494
1506
- PyObject *gca_kwargs = PyDict_New ();
1507
- PyDict_SetItemString (gca_kwargs, " projection" , PyString_FromString (" 3d" ));
1495
+ PyObject *axis = init_3d_axis (fig);
1508
1496
1509
- PyObject *gca = PyObject_GetAttrString (fig, " gca" );
1510
- if (!gca) throw std::runtime_error (" No gca" );
1511
- Py_INCREF (gca);
1512
- PyObject *axis = PyObject_Call (
1513
- gca, detail::_interpreter::get ().s_python_empty_tuple , gca_kwargs);
1514
-
1515
- if (!axis) throw std::runtime_error (" No axis" );
1516
- Py_INCREF (axis);
1517
- Py_DECREF (gca);
1518
- Py_DECREF (gca_kwargs);
1519
-
1520
1497
// plot our boys bravely, plot them strongly, plot them with a wink and clap
1521
1498
PyObject *plot3 = PyObject_GetAttrString (axis, " quiver" );
1522
1499
if (!plot3) throw std::runtime_error (" No 3D line plot" );
0 commit comments