/usr/lib/python2.7/dist-packages/chaco/base_contour_plot.py is in python-chaco 4.5.0-1.
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 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | from numpy import array, isscalar, issubsctype, linspace, number
# Enthought library imports
from enable.api import ColorTrait
from traits.api import Bool, Instance, Int, List, Property, \
Range, Str, Trait, Tuple
# Local relative imports
from base_2d_plot import Base2DPlot
from color_mapper import ColorMapper
class BaseContourPlot(Base2DPlot):
""" The base class for contour plots. Mostly manages configuration and
change events with colormap and contour parameters.
"""
#------------------------------------------------------------------------
# Data-related traits
#------------------------------------------------------------------------
# Defines the levels to contour.
# ``levels`` can be either: a list of floating point numbers that define
# the value of the function at the contours; a positive integer, in which
# case the range of the value is divided in the given number of equally
# spaced levels; or "auto" (default), which divides the range in 10 levels
levels = Trait("auto", Int, List)
# The color(s) of the lines.
# ``colors`` can be given as a color name, in which case all contours have
# the same color, as a list of colors, or as a colormap. If the list of
# colors is shorter than the number of levels, the values are repeated
# from the beginning of the list. Default is black.
# Colors are associated with levels of increasing value.
colors = Trait(None, Str, Instance(ColorMapper), List, Tuple)
# If present, the color mapper for the colorbar to look at.
color_mapper = Property(Instance(ColorMapper))
# A global alpha value to apply to all the contours
alpha = Trait(1.0, Range(0.0, 1.0))
#------------------------------------------------------------------------
# Private traits
#------------------------------------------------------------------------
# Is the cached level data valid?
_level_cache_valid = Bool(False)
# Is the cached color data valid?
_colors_cache_valid = Bool(False)
# List of levels and their associated line properties.
_levels = List
# List of colors
_colors = List
# Mapped trait used to convert user-suppied color values to AGG-acceptable
# ones. (Mapped traits in lists are not supported, must be converted one at
# a time.)
_color_map_trait = ColorTrait
def __init__(self, *args, **kwargs):
super(BaseContourPlot, self).__init__(*args, **kwargs)
if self.color_mapper:
self.color_mapper.on_trait_change(self._update_color_mapper, "updated")
return
def _update_levels(self):
""" Updates the levels cache. """
low, high = self.value.get_bounds()
if self.levels == "auto":
self._levels = list(linspace(low, high, 10))
elif isinstance(self.levels, int):
self._levels = list(linspace(low, high, self.levels))
else:
self._levels = self.levels
self._levels.sort()
self._level_cache_valid = True
self._colors_cache_valid = False
def _update_colors(self, numcolors=None):
""" Update the colors cache using our color mapper and based
on our number of levels. The **mode** parameter accounts for fenceposting:
- If **mode** is "poly", then the number of colors to generate is 1
less than the number of levels
- If **mode** is "line", then the number of colors to generate is
equal to the number of levels
"""
if numcolors is None:
numcolors = len(self._levels)
colors = self.colors
# If we are given no colors, set a default for all levels
if colors is None:
self._color_map_trait = "black"
self._colors = [self._color_map_trait_] * numcolors
# If we are given a single color, apply it to all levels
elif isinstance(colors, basestring):
self._color_map_trait = colors
self._colors = [self._color_map_trait_] * numcolors
# If we are given a colormap, use it to map all the levels to colors
elif isinstance(colors, ColorMapper):
self._colors = []
mapped_colors = self.color_mapper.map_screen(array(self._levels))
for i in range(numcolors):
self._color_map_trait = tuple(mapped_colors[i])
self._colors.append(self._color_map_trait_)
# A list or tuple
# This could be a length 3 or 4 sequence of scalars, which indicates
# a color; otherwise, this is interpreted as a list of items to
# be converted via self._color_map_trait.
else:
if len(colors) in (3,4) and \
(isscalar(colors[0]) and issubsctype(type(colors[0]), number)):
self._color_map_trait = colors
self._colors = [self._color_map_trait_] * numcolors
else:
# if the list of colors is shorter than the list of levels, simply
# repeat colors from the beginning of the list as needed
self._colors = []
for i in range(len(self._levels)):
self._color_map_trait = colors[i%len(colors)]
self._colors.append(self._color_map_trait_)
self._colors_cache_valid = True
return
#------------------------------------------------------------------------
# Event handlers
#------------------------------------------------------------------------
def _index_data_changed_fired(self):
# If the index data has changed, the reset the levels cache (which
# also triggers all the other caches to reset).
self._level_cache_valid = False
self.invalidate_draw()
def _value_data_changed_fired(self):
# If the index data has changed, the reset the levels cache (which
# also triggers all the other caches to reset).
self._level_cache_valid = False
self.invalidate_draw()
def _index_mapper_changed_fired(self):
# If the index mapper has changed, then we need to redraw
self.invalidate_draw()
def _update_color_mapper(self):
# If the color mapper has changed, then we need to recompute the
# levels and cached data associated with that.
self._level_cache_valid = False
self.invalidate_draw()
def _levels_changed(self):
self._update_levels()
self.invalidate_draw()
self.request_redraw()
def _colors_changed(self):
if self._level_cache_valid:
self._update_colors()
self.invalidate_draw()
#------------------------------------------------------------------------
# Trait properties
#------------------------------------------------------------------------
def _get_color_mapper(self):
if isinstance(self.colors, ColorMapper):
return self.colors
else:
return None
def _set_color_mapper(self, color_mapper):
# Remove the dynamic event handler from the old color mapper
if self.colors is not None and isinstance(self.colors, ColorMapper):
self.colors.on_trait_change(self._update_color_mapper, "updated", remove=True)
# Check to see if we should copy over the range as well
if color_mapper is not None:
if color_mapper.range is None and self.colors.range is not None:
color_mapper.range = self.colors.range
# Attach the dynamic event handler to the new color mapper
if color_mapper is not None:
color_mapper.on_trait_change(self._update_color_mapper, "updated")
self.colors = color_mapper
self._update_color_mapper()
|