41 using namespace Nsound;
48 #define PRINT_LINE __FILE__ << ":" << __LINE__ << ": "
50 #define MIN(a,b) ((a) < (b) ? (a) : (b))
51 #define MAX(a,b) ((a) > (b) ? (a) : (b))
67 #ifndef NSOUND_PLATFORM_OS_WINDOWS
68 #pragma GCC diagnostic ignored "-Wold-style-cast"
80 : axes_ptr_(rhs.axes_ptr_)
97 #define M_CHECK_PY_PTR_RETURN( a, msg ) \
98 if( PyErr_Occurred() || (a) == NULL) \
105 #define M_CHECK_PY_PTR( a, msg ) \
106 if( PyErr_Occurred() || (a) == NULL) \
116 #ifdef NSOUND_C_PYLAB
125 #ifndef NSOUND_IN_PYTHON_MODULE
135 M_THROW(
"Py_Initialize() failed");
144 PyObject * matplotlib = PyImport_ImportModule(
"matplotlib");
148 PyObject * pylab = PyImport_ImportModule(
"matplotlib.pylab");
152 Py_DECREF(matplotlib);
157 PyObject * pylab_dict = PyModule_GetDict(pylab);
165 std::vector< std::string > functions;
167 functions.push_back(
"axhline");
168 functions.push_back(
"axis");
169 functions.push_back(
"axvline");
170 functions.push_back(
"close");
171 functions.push_back(
"detrend");
172 functions.push_back(
"figure");
173 functions.push_back(
"gca");
174 functions.push_back(
"hold");
175 functions.push_back(
"imshow");
176 functions.push_back(
"legend");
177 functions.push_back(
"plot");
178 functions.push_back(
"show");
179 functions.push_back(
"subplot");
180 functions.push_back(
"text");
181 functions.push_back(
"title");
182 functions.push_back(
"window_hanning");
183 functions.push_back(
"xlabel");
184 functions.push_back(
"xlim");
185 functions.push_back(
"ylabel");
186 functions.push_back(
"ylim");
188 const uint32 N_FUNCTIONS =
static_cast<uint32>(functions.size());
190 for(
uint32 i = 0; i < N_FUNCTIONS; ++i)
192 PyObject * func = PyDict_GetItemString(
193 pylab_dict, functions[i].c_str());
196 func,
"PyDict_GetItemString('" << functions[i] <<
"') failed");
198 if(! PyCallable_Check(func))
200 M_THROW(
"pylab." << functions[i] <<
" isn't callable?!");
209 PyObject * __main__ = PyImport_ImportModule(
"__main__");
213 PyObject * globals = PyModule_GetDict(__main__);
221 run_string(
"import matplotlib.pylab as _pylab_nsound_");
232 #ifdef NSOUND_C_PYLAB
238 #ifndef NSOUND_IN_PYTHON_MODULE
254 #ifdef NSOUND_C_PYLAB
273 #ifndef NSOUND_IN_PYTHON_MODULE
275 static bool once =
true;
281 <<
"WARNING: Nsound::Plotter::show(): Nsound wasn't "
282 "compiled with matplotlib" << std::endl;
294 #ifdef NSOUND_C_PYLAB
296 if(kwargs ==
"")
return PyDict_New();
298 std::stringstream ss;
300 ss <<
"dict(" << kwargs <<
")\n";
302 PyCodeObject * code = (PyCodeObject*) Py_CompileString(
303 ss.str().c_str(),
"Plotter.cc", Py_eval_input);
313 PyObject * kwdict = PyEval_EvalCode(code, globals, locals);
329 const std::string & kwargs)
331 #ifdef NSOUND_C_PYLAB
338 PyObject * args = Py_BuildValue(
"(d)", y_pos);
344 PyObject * ret = PyObject_Call(
table_[
"pylab.axhline"], args, kw_args);
360 const std::string & kwargs)
362 #ifdef NSOUND_C_PYLAB
369 PyObject * args = Py_BuildValue(
"(d)", x_pos);
375 PyObject * ret = PyObject_Call(
table_[
"pylab.axvline"], args, kw_args);
393 #ifdef NSOUND_C_PYLAB
402 PyObject * args = Py_BuildValue(
"(d, d)", xmin, xmax);
408 PyObject * ret = PyObject_Call(
table_[
"pylab.xlim"], args, kw_args);
426 #ifdef NSOUND_C_PYLAB
435 PyObject * args = Py_BuildValue(
"(d, d)", ymin, ymax);
441 PyObject * ret = PyObject_Call(
table_[
"pylab.ylim"], args, kw_args);
457 #ifdef NSOUND_C_PYLAB
470 PyObject * args = Py_BuildValue(
"()");
476 PyObject * ret = PyObject_Call(
table_[
"pylab.figure"], args, kw_args);
504 " ax__ = _pylab_nsound_.gca();\n"
505 " ax__.grid(True);\n"
514 " ax__ = _pylab_nsound_.gca();\n"
515 " ax__.grid(False);\n"
527 #ifdef NSOUND_C_PYLAB
534 PyObject * args = Py_BuildValue(
"(s)",
"all");
540 PyObject * ret = PyObject_Call(
table_[
"pylab.close"], args, kw_args);
556 #ifdef NSOUND_C_PYLAB
570 args = PyTuple_Pack(1, Py_True);
574 args = PyTuple_Pack(1, Py_False);
604 const std::string & kwargs)
606 #ifdef NSOUND_C_PYLAB
620 M_THROW(
"Nsound::Plotter::imagesc(): "
621 <<
"Z has zero columns! ("
629 if(x_size > 0 && x_size != N)
631 M_THROW(
"Nsound::Plotter::imagesc(): "
632 <<
"shape mismatch between x_axis and Z ("
640 if(y_size > 0 && y_size != M)
642 M_THROW(
"Nsound::Plotter::imagesc(): "
643 <<
"shape mismatch between y_axis and Z ("
656 if(x_size == 0 && y_size == 0)
659 xmax =
static_cast<float64>(N - 1) + 0.5;
661 ymax =
static_cast<float64>(M - 1) + 0.5;
663 else if(x_size > 0 && y_size > 0)
665 float64 dx = x_axis[1] - x_axis[0];
666 float64 dy = y_axis[1] - y_axis[0];
668 xmin = x_axis[0] - 0.5 * dx;
669 xmax = x_axis[N - 1] + 0.5 * dx;
670 ymin = y_axis[0] - 0.5 * dy;
671 ymax = y_axis[M - 1] + 0.5 * dy;
676 PyObject * matrix_list = PyList_New(M);
680 for(
uint32 m = 0; m < M; ++m)
686 PyList_SET_ITEM(matrix_list, m, array);
691 PyObject * args = Py_BuildValue(
"(O)", matrix_list);
696 std::stringstream ss;
699 << xmin <<
"," << xmax <<
"," << ymin <<
"," << ymax <<
"],"
700 <<
"interpolation='nearest',"
711 PyObject * ret = PyObject_Call(
table_[
"pylab.imshow"], args, kw_args);
725 " ax__ = _pylab_nsound_.gca();\n"
726 " trash__ = ax__.axis('tight');\n"
734 " ax__ = _pylab_nsound_.gca();\n"
735 " ax__.grid(True);\n"
747 #ifdef NSOUND_C_PYLAB
750 PyObject * args = Py_BuildValue(
"()");
753 PyObject * ret = PyObject_Call(
table_[
"pylab.legend"], args, kw_args);
767 const std::string & fmt,
768 const std::string & kwargs)
778 const std::string & fmt,
779 const std::string & kwargs)
781 #ifdef NSOUND_C_PYLAB
808 if(x_list != NULL) ++n_args;
809 if(fmt !=
"") ++n_args;
811 args = PyTuple_New(n_args);
819 PyTuple_SetItem(args, pos, x_list);
823 PyTuple_SetItem(args, pos, y_list);
830 fmt_str = PyString_FromString(fmt.c_str());
832 fmt_str,
"PyString_FromString('" << fmt <<
"') failed");
833 PyTuple_SetItem(args, pos, fmt_str);
839 PyObject * ret = PyObject_Call(
table_[
"pylab.plot"], args, kw_args);
904 " ax__ = _pylab_nsound_.gca();\n"
905 " ax__.grid(True);\n"
918 const std::string & fmt,
919 const std::string & kwargs)
921 #ifdef NSOUND_C_PYLAB
926 plot(xx, yy, fmt, kwargs);
935 #ifdef NSOUND_C_PYLAB
937 std::string str = command +
"\n";
940 str.c_str(), Py_file_input,
table_[
"globals"], NULL);
951 savefig(
const std::string & filename,
const std::string & kwargs)
953 #ifdef NSOUND_C_PYLAB
960 std::stringstream ss;
966 if(kwargs.length() > 0)
968 ss <<
", " << kwargs;
997 if(s !=
"log" && s !=
"linear")
return;
999 std::stringstream ss;
1003 <<
" ax = _pylab_nsound_.gca();\n"
1004 <<
" ax.set_xscale('" << s <<
"')\n"
1015 if(s !=
"log" && s !=
"linear")
return;
1017 std::stringstream ss;
1021 <<
" ax = _pylab_nsound_.gca();\n"
1022 <<
" ax.set_yscale('" << s <<
"')\n"
1035 const std::string & kwargs,
1039 #ifdef NSOUND_C_PYLAB
1047 PyObject * args = Py_BuildValue(
"(iii)", n_rows, n_columns, n);
1055 PyObject * key = PyString_FromString(
"sharex");
1056 PyDict_SetItem(kw_args, key, sharex->
get_axes());
1061 PyObject * key = PyString_FromString(
"sharey");
1062 PyDict_SetItem(kw_args, key, sharey->
get_axes());
1066 PyObject * ret = PyObject_Call(
table_[
"pylab.subplot"], args, kw_args);
1077 " ax = _pylab_nsound_.gca();\n"
1095 const std::string & text,
1096 const std::string & kwargs)
1098 #ifdef NSOUND_C_PYLAB
1107 PyObject * args = Py_BuildValue(
"(dds)",
1108 x, y, text.c_str());
1113 PyObject * ret = PyObject_Call(
table_[
"pylab.text"], args, kw_args);
1127 title(
const std::string & title,
const std::string & kwargs)
1129 #ifdef NSOUND_C_PYLAB
1136 PyObject * args = Py_BuildValue(
"(s)", title.c_str());
1140 PyObject * ret = PyObject_Call(
table_[
"pylab.title"], args, kw_args);
1154 xlabel(
const std::string & label,
const std::string & kwargs)
1156 #ifdef NSOUND_C_PYLAB
1163 PyObject * args = Py_BuildValue(
"(s)", label.c_str());
1166 PyObject * ret = PyObject_Call(
table_[
"pylab.xlabel"], args, kw_args);
1180 ylabel(
const std::string & label,
const std::string & kwargs)
1182 #ifdef NSOUND_C_PYLAB
1189 PyObject * args = Py_BuildValue(
"(s)", label.c_str());
1192 PyObject * ret = PyObject_Call(
table_[
"pylab.ylabel"], args, kw_args);
1204 #ifdef NSOUND_C_PYLAB
1211 PyObject * py_list = PyList_New(n_samples);
1215 for(
uint32 i = 0; i < n_samples; ++i)
1217 PyList_SET_ITEM(py_list, i,
1218 PyFloat_FromDouble(static_cast<float64>(buffer[i])));
1228 PyObject * py_int = PyInt_FromLong(i);
PyObject * makePyIntFromUint32(const uint32 &i) const
Create a PyInt.
void xlabel(const std::string &label, const std::string &kwargs="")
Add a label x axis.
void grid(boolean flag)
Sets the grid state.
#define M_ASSERT_VALUE(a, op, value)
PyObject * _make_kwargs(const std::string &kwargs) const
static void show()
Acutally draw the plots to the screen.
void savefig(const std::string &filename, const std::string &kwargs="")
Saves the last figure drawn to filename.
static boolean grid_is_on_
void plot(const Buffer &y, const std::string &fmt="", const std::string &kwargs="")
Plots the Buffer on the current figure.
void axvline(const float64 &x_pos=0.0, const std::string &kwargs="")
Draws a vertical line at x and spans ymin to ymax (ralitive).
#define M_CHECK_PY_PTR(a, msg)
uint32 getLength() const
Returns the number of samples of audio data in the stream.
void hide()
Hides all plots, prevents any plot window being rendered to the screen. Usefull if only saveing plots...
void figure(const std::string &kwargs="") const
Creates a new figure window to plot in.
A wrapper around a Matplotlib Axes object.
void title(const std::string &title, const std::string &kwargs="")
Add a title to the plot at the top and centered.
std::pair< std::string, PyObject * > StringPyObjectPair
void legend(const std::string &kwargs="")
Shows the legend on the current axes.
void xlim(const float64 &xmin, const float64 &xmax)
Sets the limit for the x & y axis.
PyObject * makePyListFromBuffer(const Buffer &buffer) const
Create a PyList object from a buffer!
static boolean hold_is_on_
void set_yscale(const std::string &s)
Sets the y axis scaling: log or linear.
void set_xscale(const std::string &s)
Sets the x axis scaling: log or linear.
uint32 getLength() const
Returns the number of samples in the Buffer.
Plotter()
Construct the Plotter.
Axes subplot(const uint32 n_rows, const uint32 n_cols, const uint32 n, const std::string &kwargs="", Axes *sharex=NULL, Axes *sharey=NULL)
Creates a figure in a subplot, subplot(A, B, C, **kwargs)
void ylim(const float64 &ymin, const float64 &ymax)
uint32 getNChannels(void) const
Returns the number of audio channels in the stream.
void imagesc(const AudioStream &Z, const std::string &kwargs="")
Plots the AudioStream like a 2D matrix.
void text(const float64 &x, const float64 &y, const std::string &text, const std::string &kwargs="")
Adds text at the x, y data point.
void hold(boolean flag)
Sets the hold state.
Axes & operator=(const Axes &rhs)
static PlotterState state_
void ylabel(const std::string &label, const std::string &kwargs="")
Add a label y axis.
A Buffer for storing audio samples.
#define M_CHECK_PY_PTR_RETURN(a, msg)
void axhline(const float64 &y_pos=0.0, const std::string &kwargs="")
Draws a horizontal line at y and spans xmin to xmax (ralitive).
std::map< std::string, PyObject * > PylabTable
void run_string(const std::string &command) const
executes the python string
virtual ~Plotter()
Deconstruct the Plotter.