From: <md...@us...> - 2008-01-09 21:27:49
|
Revision: 4833 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4833&view=rev Author: mdboom Date: 2008-01-09 13:27:48 -0800 (Wed, 09 Jan 2008) Log Message: ----------- Handle NaNs in the data (on-the-fly as it's drawn). Add a nan_test.py example to help ensure this stays working. Modified Paths: -------------- trunk/matplotlib/examples/backend_driver.py trunk/matplotlib/lib/matplotlib/path.py trunk/matplotlib/src/agg_py_path_iterator.h Added Paths: ----------- trunk/matplotlib/examples/nan_test.py Modified: trunk/matplotlib/examples/backend_driver.py =================================================================== --- trunk/matplotlib/examples/backend_driver.py 2008-01-09 19:35:54 UTC (rev 4832) +++ trunk/matplotlib/examples/backend_driver.py 2008-01-09 21:27:48 UTC (rev 4833) @@ -71,6 +71,7 @@ 'mathtext_demo.py', 'mri_with_eeg.py', 'multiple_figs_demo.py', + 'nan_test.py', 'pcolor_demo.py', 'pcolor_demo2.py', 'pcolor_small.py', Added: trunk/matplotlib/examples/nan_test.py =================================================================== --- trunk/matplotlib/examples/nan_test.py (rev 0) +++ trunk/matplotlib/examples/nan_test.py 2008-01-09 21:27:48 UTC (rev 4833) @@ -0,0 +1,20 @@ +#!/usr/bin/env python +""" +Example: simple line plot with NaNs inserted. +""" +from pylab import * + +t = arange(0.0, 1.0+0.01, 0.01) +s = cos(2*2*pi*t) +t[41:60] = NaN +plot(t, s, '-', lw=2) + +xlabel('time (s)') +ylabel('voltage (mV)') +title('A sine wave with a gap of NaN\'s between 0.4 and 0.6') +grid(True) + +#savefig('simple_plot.png') +savefig('nan_test') + +show() Property changes on: trunk/matplotlib/examples/nan_test.py ___________________________________________________________________ Name: svn:executable + * Modified: trunk/matplotlib/lib/matplotlib/path.py =================================================================== --- trunk/matplotlib/lib/matplotlib/path.py 2008-01-09 19:35:54 UTC (rev 4832) +++ trunk/matplotlib/lib/matplotlib/path.py 2008-01-09 21:27:48 UTC (rev 4833) @@ -93,8 +93,10 @@ correct places to jump over the masked regions. """ if ma.isMaskedArray(vertices): + is_mask = True mask = ma.getmask(vertices) else: + is_mask = False vertices = npy.asarray(vertices, npy.float_) mask = ma.nomask @@ -108,17 +110,21 @@ # itself), are not expected to deal with masked arrays, so we # must remove them from the array (using compressed), and add # MOVETO commands to the codes array accordingly. - if mask is not ma.nomask: - mask1d = ma.mask_or(mask[:, 0], mask[:, 1]) - if codes is None: - codes = self.LINETO * npy.ones( - len(vertices), self.code_type) - codes[0] = self.MOVETO - vertices = ma.compress(npy.invert(mask1d), vertices, 0) - codes = npy.where(npy.concatenate((mask1d[-1:], mask1d[:-1])), - self.MOVETO, codes) - codes = ma.masked_array(codes, mask=mask1d).compressed() - codes = npy.asarray(codes, self.code_type) + if is_mask: + if mask is not ma.nomask: + mask1d = ma.mask_or(mask[:, 0], mask[:, 1]) + if codes is None: + codes = self.LINETO * npy.ones( + len(vertices), self.code_type) + codes[0] = self.MOVETO + vertices = ma.compress(npy.invert(mask1d), vertices, 0) + vertices = npy.asarray(vertices) + codes = npy.where(npy.concatenate((mask1d[-1:], mask1d[:-1])), + self.MOVETO, codes) + codes = ma.masked_array(codes, mask=mask1d).compressed() + codes = npy.asarray(codes, self.code_type) + else: + vertices = npy.asarray(vertices, npy.float_) assert vertices.ndim == 2 assert vertices.shape[1] == 2 @@ -161,8 +167,13 @@ Iterates over all of the curve segments in the path. """ vertices = self.vertices + if not len(vertices): + return + codes = self.codes len_vertices = len(vertices) + isnan = npy.isnan + any = npy.any NUM_VERTICES = self.NUM_VERTICES MOVETO = self.MOVETO @@ -170,15 +181,17 @@ CLOSEPOLY = self.CLOSEPOLY STOP = self.STOP - if not len(vertices): - return - if codes is None: - yield vertices[0], MOVETO - for v in vertices[1:]: - yield v, LINETO + next_code = MOVETO + for v in vertices: + if any(isnan(v)): + next_code = MOVETO + else: + yield v, next_code + next_code = LINETO else: i = 0 + was_nan = False while i < len_vertices: code = codes[i] if code == CLOSEPOLY: @@ -188,7 +201,14 @@ return else: num_vertices = NUM_VERTICES[code] - yield vertices[i:i+num_vertices].flatten(), code + curr_vertices = vertices[i:i+num_vertices].flatten() + if any(isnan(curr_vertices)): + was_nan = True + elif was_nan: + yield curr_vertices[-2:], MOVETO + was_nan = False + else: + yield curr_vertices, code i += num_vertices def transformed(self, transform): Modified: trunk/matplotlib/src/agg_py_path_iterator.h =================================================================== --- trunk/matplotlib/src/agg_py_path_iterator.h 2008-01-09 19:35:54 UTC (rev 4832) +++ trunk/matplotlib/src/agg_py_path_iterator.h 2008-01-09 21:27:48 UTC (rev 4833) @@ -5,6 +5,7 @@ #define PY_ARRAY_TYPES_PREFIX NumPy #include "numpy/arrayobject.h" #include "agg_path_storage.h" +#include "MPL_isnan.h" class PathIterator { @@ -64,7 +65,12 @@ inline unsigned vertex(double* x, double* y) { if (m_iterator >= m_total_vertices) return agg::path_cmd_stop; - return vertex(m_iterator++, x, y); + unsigned code = vertex(m_iterator++, x, y); + while (MPL_isnan64(*x) || MPL_isnan64(*y)) { + vertex(m_iterator++, x, y); + code = agg::path_cmd_move_to; + } + return code; } inline void rewind(unsigned path_id) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |