Skip to content

Commit fe878fa

Browse files
committed
add spy
1 parent 058c716 commit fe878fa

3 files changed

Lines changed: 69 additions & 9 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ EXTRA_FLAGS += $(shell $(PYTHON_BIN) $(CURDIR)/numpy_flags.py)
1616
WITHOUT_NUMPY := $(findstring $(EXTRA_FLAGS), WITHOUT_NUMPY)
1717

1818
# Examples requiring numpy support to compile
19-
EXAMPLES_NUMPY := surface colorbar contour
19+
EXAMPLES_NUMPY := surface colorbar contour spy
2020
EXAMPLES := minimal basic modern animation nonblock xkcd quiver bar \
2121
fill_inbetween fill update subplot2grid lines3d \
2222
$(if $(WITHOUT_NUMPY),,$(EXAMPLES_NUMPY))

examples/spy.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#import <iostream>
2+
#import <vector>
3+
#import "../matplotlibcpp.h"
4+
5+
namespace plt = matplotlibcpp;
6+
7+
int main()
8+
{
9+
const int n = 20;
10+
std::vector<std::vector<double>> matrix;
11+
12+
for (int i = 0; i < n; ++i) {
13+
std::vector<double> row;
14+
for (int j = 0; j < n; ++j) {
15+
if (i == j)
16+
row.push_back(-2);
17+
else if (j == i - 1 || j == i + 1)
18+
row.push_back(1);
19+
else
20+
row.push_back(0);
21+
}
22+
matrix.push_back(row);
23+
}
24+
25+
plt::spy(matrix, 5, {{"marker", "o"}});
26+
plt::show();
27+
28+
return 0;
29+
}

matplotlibcpp.h

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ struct _interpreter {
9595
PyObject *s_python_function_colorbar;
9696
PyObject *s_python_function_subplots_adjust;
9797
PyObject *s_python_function_contour;
98+
PyObject *s_python_function_spy;
9899

99100

100101
/* For now, _interpreter is implemented as a singleton since its currently not possible to have
@@ -233,9 +234,10 @@ struct _interpreter {
233234
s_python_function_bar = safe_import(pymod,"bar");
234235
s_python_function_colorbar = PyObject_GetAttrString(pymod, "colorbar");
235236
s_python_function_subplots_adjust = safe_import(pymod,"subplots_adjust");
236-
s_python_function_contour = safe_import(pymod, "contour");
237237
#ifndef WITHOUT_NUMPY
238+
s_python_function_contour = safe_import(pymod, "contour");
238239
s_python_function_imshow = safe_import(pymod, "imshow");
240+
s_python_function_spy = safe_import(pymod, "spy");
239241
#endif
240242
s_python_empty_tuple = PyTuple_New(0);
241243
}
@@ -306,11 +308,11 @@ template <> struct select_npy_type<uint64_t> { const static NPY_TYPES type = NPY
306308

307309
// Sanity checks; comment them out or change the numpy type below if you're compiling on
308310
// a platform where they don't apply
309-
// static_assert(sizeof(long long) == 8);
310-
// template <> struct select_npy_type<long long> { const static NPY_TYPES type = NPY_INT64; };
311-
// static_assert(sizeof(unsigned long long) == 8);
312-
// template <> struct select_npy_type<unsigned long long> { const static NPY_TYPES type = NPY_UINT64; };
313-
// TODO: add int, long, etc.
311+
static_assert(sizeof(long long) == 8);
312+
template <> struct select_npy_type<long long> { const static NPY_TYPES type = NPY_INT64; };
313+
static_assert(sizeof(unsigned long long) == 8);
314+
template <> struct select_npy_type<unsigned long long> { const static NPY_TYPES type = NPY_UINT64; };
315+
TODO: add int, long, etc.
314316

315317
template<typename Numeric>
316318
PyObject* get_array(const std::vector<Numeric>& v)
@@ -563,8 +565,37 @@ void contour(const std::vector<::std::vector<Numeric>> &x,
563565

564566
Py_DECREF(args);
565567
Py_DECREF(kwargs);
566-
if (res)
567-
Py_DECREF(res);
568+
if (res) Py_DECREF(res);
569+
}
570+
571+
template <typename Numeric>
572+
void spy(const std::vector<::std::vector<Numeric>> &x,
573+
const double markersize = -1, // -1 for default matplotlib size
574+
const std::map<std::string, std::string> &keywords = {})
575+
{
576+
detail::_interpreter::get();
577+
578+
PyObject *xarray = detail::get_2darray(x);
579+
580+
PyObject *kwargs = PyDict_New();
581+
if (markersize != -1) {
582+
PyDict_SetItemString(kwargs, "markersize", PyFloat_FromDouble(markersize));
583+
}
584+
for (std::map<std::string, std::string>::const_iterator it = keywords.begin();
585+
it != keywords.end(); ++it) {
586+
PyDict_SetItemString(kwargs, it->first.c_str(),
587+
PyString_FromString(it->second.c_str()));
588+
}
589+
590+
PyObject *plot_args = PyTuple_New(1);
591+
PyTuple_SetItem(plot_args, 0, xarray);
592+
593+
PyObject *res = PyObject_Call(
594+
detail::_interpreter::get().s_python_function_spy, plot_args, kwargs);
595+
596+
Py_DECREF(plot_args);
597+
Py_DECREF(kwargs);
598+
if (res) Py_DECREF(res);
568599
}
569600
#endif // WITHOUT_NUMPY
570601

0 commit comments

Comments
 (0)