|
From: <md...@us...> - 2008-08-11 12:48:59
|
Revision: 6018
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6018&view=rev
Author: mdboom
Date: 2008-08-11 12:48:50 +0000 (Mon, 11 Aug 2008)
Log Message:
-----------
Does simplify paths when NaN/inf is present.
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/path.py
trunk/matplotlib/src/_backend_agg.cpp
trunk/matplotlib/src/_path.cpp
trunk/matplotlib/src/agg_py_path_iterator.h
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2008-08-11 07:09:16 UTC (rev 6017)
+++ trunk/matplotlib/CHANGELOG 2008-08-11 12:48:50 UTC (rev 6018)
@@ -1,3 +1,9 @@
+2008-08-11 Fix more bugs in NaN/inf handling. In particular, path simplification
+ (which does not handle NaNs or infs) will be turned off automatically
+ when infs or NaNs are present. Also masked arrays are now converted
+ to arrays with NaNs for consistent handling of masks and NaNs
+ - MGD and EF
+
=================================================================
2008-08-03 Released 0.98.3 at svn r5947
Modified: trunk/matplotlib/lib/matplotlib/path.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/path.py 2008-08-11 07:09:16 UTC (rev 6017)
+++ trunk/matplotlib/lib/matplotlib/path.py 2008-08-11 12:48:50 UTC (rev 6018)
@@ -56,6 +56,11 @@
:class:`Path` objects, as an optimization, do not store a *codes*
at all, but have a default one provided for them by
:meth:`iter_segments`.
+
+ Note also that the vertices and codes arrays should be treated as
+ immutable -- there are a number of optimizations and assumptions
+ made up front in the constructor that will not change when the
+ data changes.
"""
# Path codes
@@ -84,46 +89,29 @@
dimension.
If *codes* is None, *vertices* will be treated as a series of
- line segments. If *vertices* contains masked values, the
- resulting path will be compressed, with ``MOVETO`` codes
- inserted in the correct places to jump over the masked
- regions.
+ line segments.
+
+ If *vertices* contains masked values, they will be converted
+ to NaNs which are then handled correctly by the Agg
+ PathIterator and other consumers of path data, such as
+ :meth:`iter_segments`.
"""
if ma.isMaskedArray(vertices):
- is_mask = True
- mask = ma.getmask(vertices)
+ vertices = vertices.astype(np.float_).filled(np.nan)
else:
- is_mask = False
vertices = np.asarray(vertices, np.float_)
- mask = ma.nomask
if codes is not None:
codes = np.asarray(codes, self.code_type)
assert codes.ndim == 1
assert len(codes) == len(vertices)
- # The path being passed in may have masked values. However,
- # the backends (and any affine transformations in matplotlib
- # 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 is_mask:
- if mask is not ma.nomask:
- mask1d = np.logical_or.reduce(mask, axis=1)
- gmask1d = np.invert(mask1d)
- if codes is None:
- codes = np.empty((len(vertices)), self.code_type)
- codes.fill(self.LINETO)
- codes[0] = self.MOVETO
- vertices = vertices[gmask1d].filled() # ndarray
- codes[np.roll(mask1d, 1)] = self.MOVETO
- codes = codes[gmask1d] # np.compress is much slower
- else:
- vertices = np.asarray(vertices, np.float_)
-
assert vertices.ndim == 2
assert vertices.shape[1] == 2
+ self.should_simplify = (codes is None and
+ np.all(np.isfinite(vertices)) and
+ len(vertices) >= 128)
self.codes = codes
self.vertices = vertices
Modified: trunk/matplotlib/src/_backend_agg.cpp
===================================================================
--- trunk/matplotlib/src/_backend_agg.cpp 2008-08-11 07:09:16 UTC (rev 6017)
+++ trunk/matplotlib/src/_backend_agg.cpp 2008-08-11 12:48:50 UTC (rev 6018)
@@ -387,7 +387,7 @@
double x0, y0, x1, y1;
unsigned code;
- if (path.total_vertices() > 15)
+ if (!path.should_simplify() || path.total_vertices() > 15)
return false;
code = path.vertex(&x0, &y0);
@@ -420,11 +420,6 @@
return true;
}
-template<class Path>
-bool should_simplify(Path& path) {
- return !path.has_curves() && path.total_vertices() >= 128;
-}
-
Py::Object
RendererAgg::copy_from_bbox(const Py::Tuple& args) {
//copy region in bbox to buffer and return swig/agg buffer object
@@ -938,7 +933,7 @@
trans *= agg::trans_affine_scaling(1.0, -1.0);
trans *= agg::trans_affine_translation(0.0, (double)height);
bool snap = should_snap(path, trans);
- bool simplify = should_simplify(path) && !face.first;
+ bool simplify = path.should_simplify() && !face.first;
transformed_path_t tpath(path, trans);
simplify_t simplified(tpath, snap, simplify, width, height);
@@ -1236,6 +1231,10 @@
inline unsigned total_vertices() {
return 5;
}
+
+ inline bool should_simplify() {
+ return false;
+ }
};
public:
Modified: trunk/matplotlib/src/_path.cpp
===================================================================
--- trunk/matplotlib/src/_path.cpp 2008-08-11 07:09:16 UTC (rev 6017)
+++ trunk/matplotlib/src/_path.cpp 2008-08-11 12:48:50 UTC (rev 6018)
@@ -1120,7 +1120,7 @@
double width = Py::Float(args[2]);
double height = Py::Float(args[3]);
- bool simplify = !path.has_curves() && width != 0.0 && height != 0.0;
+ bool simplify = path.should_simplify() && width != 0.0 && height != 0.0;
transformed_path_t tpath(path, trans);
simplify_t simplified(tpath, false, simplify, width, height);
Modified: trunk/matplotlib/src/agg_py_path_iterator.h
===================================================================
--- trunk/matplotlib/src/agg_py_path_iterator.h 2008-08-11 07:09:16 UTC (rev 6017)
+++ trunk/matplotlib/src/agg_py_path_iterator.h 2008-08-11 12:48:50 UTC (rev 6018)
@@ -15,6 +15,7 @@
PyArrayObject* m_codes;
size_t m_iterator;
size_t m_total_vertices;
+ bool m_should_simplify;
public:
PathIterator(const Py::Object& path_obj) :
@@ -22,6 +23,7 @@
{
Py::Object vertices_obj = path_obj.getAttr("vertices");
Py::Object codes_obj = path_obj.getAttr("codes");
+ Py::Object should_simplify_obj = path_obj.getAttr("should_simplify");
m_vertices = (PyArrayObject*)PyArray_FromObject
(vertices_obj.ptr(), PyArray_DOUBLE, 2, 2);
@@ -38,6 +40,7 @@
throw Py::ValueError("Invalid codes array.");
}
+ m_should_simplify = bool(Py::Int(should_simplify_obj));
m_total_vertices = m_vertices->dimensions[0];
}
@@ -100,9 +103,9 @@
return m_total_vertices;
}
- inline bool has_curves()
+ inline bool should_simplify()
{
- return m_codes;
+ return m_should_simplify;
}
};
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|