/usr/lib/python2.7/dist-packages/chaco/point_data_source.py is in python-chaco 4.4.1-1.2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | """
Defines the PointDataSource class.
"""
# Major library imports
from numpy import array, transpose
# Enthought library imports
from traits.api import Enum, Property, ReadOnly, Tuple
# Local, relative imports
from base import PointTrait, reverse_map_1d, SortOrderTrait
from array_data_source import ArrayDataSource
class PointDataSource(ArrayDataSource):
""" A data source representing a (possibly unordered) set of (X,Y) points.
This is internally always represented by an Nx2 array, so that data[i]
refers to a single point (represented as a length-2 array).
Most of the traits and methods of ArrayDataSeries work for the
PointDataSeries as well, since its data is linear. This class
overrides only the methods and traits that are different.
"""
# The dimensionality of the indices into this data source (overrides
# ArrayDataSource).
index_dimension = ReadOnly('scalar')
# The dimensionality of the value at each index point (overrides
# ArrayDataSource).
value_dimension = ReadOnly('point')
# The sort order of the data. Although sort order is less common with point
# data, it can be useful in case where the value data is sorted along some
# axis. Note that **sort_index** is used only if **sort_order** is not
# 'none'.
sort_order = SortOrderTrait
# Which of the value axes the **sort_order** refers to.
# If **sort_order** is 'none', this attribute is ignored.
# In the unlikely event that the value data is sorted along both
# X and Y (i.e., monotonic in both axes), then set **sort_index** to
# whichever one has the best binary-search performance for hit-testing.
sort_index = Enum(0, 1)
#------------------------------------------------------------------------
# Private traits
#------------------------------------------------------------------------
# The actual data (overrides ArrayDataSource).
_data = PointTrait
# Cached values of min and max as long as **_data** doesn't change
# (overrides ArrayDataSource). ((min_x, max_x), (min_y, max_y))
_cached_bounds = Tuple
# These return lists of all the x and y positions, respectively
# List of X positions.
_xdata = Property
# List of Y positions.
_ydata = Property
#------------------------------------------------------------------------
# AbstractDataSource interface
#------------------------------------------------------------------------
def __init__(self, data = transpose(array([[],[]])), **kw):
shape = data.shape
if (len(shape) != 2) or (shape[1] != 2):
raise RuntimeError, "PointDataSource constructor requires Nx2 array, but got array of shape " + str(shape) + " instead."
super(PointDataSource, self).__init__(data, **kw)
return
def get_data(self):
""" Returns the data for this data source, or (0.0, 0.0) if it has no
data.
Overrides ArryDataSource.
"""
if self._data is not None:
return self._data
else:
return (0.0, 0.0)
def reverse_map(self, pt, index=0, outside_returns_none=True):
"""Returns the index of *pt* in the data source.
Overrides ArrayDataSource.
Parameters
----------
pt : (x, y)
value to find
index : 0 or 1
Which of the axes of *pt* the *sort_order* refers to.
outside_returns_none : Boolean
Whether the method returns None if *pt* is outside the range of
the data source; if False, the method returns the value of the
bound that *pt* is outside of, in the *index* dimension.
"""
# reverse_map is of limited utility for a PointDataSeries and thus
# we only perform reverse-mapping if the data is sorted along an axis.
if self.sort_order == "none":
# By default, only provide reverse_map if the value data is sorted
# along one of its axes.
raise NotImplementedError
if index != 0 and index != 1:
raise ValueError, "Index must be 0 or 1."
# This basically reduces to a scalar data search along self.data[index].
lowerleft, upperright= self._cached_bounds
min_val = lowerleft[index]
max_val = upperright[index]
val = pt[index]
if (val < min_val):
if outside_returns_none:
return None
else:
return self._min_index
elif (val > max_val):
if outside_returns_none:
return None
else:
return self._max_index
else:
return reverse_map_1d(self._data[:,index], val, self.sort_order)
#------------------------------------------------------------------------
# Private methods
#------------------------------------------------------------------------
def _compute_bounds(self):
""" Computes the minimum and maximum values of self._data.
Overrides ArrayDataSource.
"""
if len(self._data) == 0:
self._cached_bounds = ((0.0,0.0), (0.0,0.0))
elif len(self._data) == 1:
x,y = self._data[0]
self._cached_bounds = ((x,y), (x,y))
else:
# calculate the X and Y values independently
x = self._data[:,0]
min_x = min(x)
max_x = max(x)
y = self._data[:,1]
min_y = min(y)
max_y = max(y)
self._cached_bounds = ((min_x,min_y), (max_x,max_y))
return
def _get__xdata(self):
return ArrayDataSource(self._data[:,0])
def _get__ydata(self):
return ArrayDataSource(self._data[:,1])
# EOF
|