/usr/lib/python2.7/dist-packages/chaco/errorbar_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 | from __future__ import with_statement
# Major library imports
from numpy import column_stack, compress, invert, isnan, transpose
import logging
# Enthought library imports
from traits.api import Any, Enum, Float, Instance
# Chaco imports
from lineplot import LinePlot
from abstract_data_source import AbstractDataSource
# Set up a logger for this module
logger = logging.getLogger(__name__)
class ErrorBarPlot(LinePlot):
""" Renders errorbars at various points.
"""
# The datasource containing the low values
value_low = Instance(AbstractDataSource)
# The datasource containing the high values
value_high = Instance(AbstractDataSource)
# The screen-space width of the endcap bars
endcap_size = Float(5.0)
# The kind of encap to render on error bars
endcap_style = Enum("bar", "none", None)
# Override the inherited trait definition
_cached_data_pts = Any
def map_screen(self, data_array):
""" data_array can be Nx2 or Nx3. In the former case, each row is
treated as (index, value), and this method returns screen X and Y
coordinates. In the latter case, each row is treated as (index,
value_low, value_high), and the method returns either (x, ylow, yhigh)
or (y, xlow, xhigh) depending on self.orientation.
"""
if len(data_array) == 0:
return []
elif data_array.shape[1] == 2:
return LinePlot.map_screen(self, data_array)
else:
x, ylow, yhigh = transpose(data_array)
sx = self.index_mapper.map_screen(x)
sylow = self.value_mapper.map_screen(ylow)
syhigh = self.value_mapper.map_screen(yhigh)
return column_stack((sx, sylow, syhigh))
def get_screen_points(self):
self._gather_points()
return self.map_screen(self._cached_data_pts)
def _gather_points(self):
if self._cache_valid:
return
if not self.index or not self.value_low or not self.value_high:
return
index, index_mask = self.index.get_data_mask()
value_low, value_low_mask = self.value_low.get_data_mask()
value_high, value_high_mask = self.value_high.get_data_mask()
value_mask = value_low_mask & value_high_mask
l1, l2, l3 = map(len, (index, value_low, value_high))
if 0 in (l1, l2, l3) or not (l1 == l2 == l3):
logger.warn("Chaco: using empty dataset; index_len=%d, value_low_len=%d, value_high_len=%d." % (l1,l2,l3))
self._cached_data_pts = []
self._cache_valid = True
return
index_range_mask = self.index_mapper.range.mask_data(index)
value_low_mask = self.value_mapper.range.mask_data(value_low)
value_high_mask = self.value_mapper.range.mask_data(value_high)
value_range_mask = value_low_mask | value_high_mask
nan_mask = invert(isnan(index_mask) | isnan(value_mask))
point_mask = index_mask & value_mask & nan_mask & index_range_mask & value_range_mask
points = column_stack((index, value_low, value_high))
self._cached_data_pts = compress(point_mask, points, axis=0)
self._cache_valid = True
return
def _render(self, gc, points, icon_mode=False):
if len(points) == 0:
return
if not icon_mode:
gc.clip_to_rect(self.x, self.y, self.width, self.height)
with gc:
gc.set_antialias(False)
gc.set_stroke_color(self.color_)
gc.set_line_width(self.line_width)
gc.set_line_dash(self.line_style_)
if self.orientation == "h":
x, ylow, yhigh = transpose(points)
start, end = column_stack((x, ylow)), column_stack((x, yhigh))
gc.line_set(start, end)
axis = 0
low = ylow
high = yhigh
else:
y, xlow, xhigh = transpose(points)
start, end = column_stack((xlow, y)), column_stack((xhigh, y))
gc.line_set(start, end)
axis = 1
low = xlow
high = xhigh
if self.endcap_style == "bar":
self._render_bar_endcap(gc, start, end, low, high, axis)
else:
gc.stroke_path()
if not icon_mode:
self._draw_default_axes(gc)
return
def _render_bar_endcap(self, gc, start, end, low, high, axis):
""" Renders the endcaps for endcap_style == "bar". start and end are
the two endpoints of the bare errorbar. axis is the column index
corresponding to the index direction, so for orientation of 'h', axis
is 0.
This method modifies start and end.
"""
delta = self.endcap_size / 2.0
start[:,axis] -= delta
end[:,axis] += delta
start[:,1-axis] = low
end[:,1-axis] = low
gc.line_set(start, end)
start[:,1-axis] = high
end[:,1-axis] = high
gc.line_set(start, end)
gc.stroke_path()
return
def _render_icon(self, gc, x, y, width, height):
pass
|