[Yt-svn] yt: 2 new changesets
hg at spacepope.org
hg at spacepope.org
Thu Mar 25 23:30:03 PDT 2010
hg Repository: yt
details: yt/rev/cd121e64b0dc
changeset: 1481:cd121e64b0dc
user: Matthew Turk <matthewturk at gmail.com>
date:
Thu Mar 25 19:08:11 2010 -0700
description:
Updating pan-n-scan widget to work with zooming and updating the data range and
index range simultaneously. This requires some new classes in the Chaco API
which I need to add here to be compiled & included if they do not exist in the
Chaco install on system.
hg Repository: yt
details: yt/rev/0ea10be4b283
changeset: 1482:0ea10be4b283
user: Matthew Turk <matthewturk at gmail.com>
date:
Thu Mar 25 23:29:56 2010 -0700
description:
Adding more stuff to the chaco interface
diffstat:
yt/extensions/image_panner/pan_and_scan_widget.py | 121 +++++++++++++++++++++--
1 files changed, 108 insertions(+), 13 deletions(-)
diffs (168 lines):
diff -r 915d0ab1b06b -r 0ea10be4b283 yt/extensions/image_panner/pan_and_scan_widget.py
--- a/yt/extensions/image_panner/pan_and_scan_widget.py Thu Mar 25 13:50:32 2010 -0700
+++ b/yt/extensions/image_panner/pan_and_scan_widget.py Thu Mar 25 23:29:56 2010 -0700
@@ -23,20 +23,80 @@
# Major library imports
from vm_panner import VariableMeshPanner
-from numpy import linspace, meshgrid, pi, sin, mgrid
+from numpy import linspace, meshgrid, pi, sin, mgrid, zeros
# Enthought library imports
from enthought.enable.api import Component, ComponentEditor, Window
-from enthought.traits.api import HasTraits, Instance, Button
+from enthought.traits.api import HasTraits, Instance, Button, Any, Callable, \
+ on_trait_change
from enthought.traits.ui.api import Item, Group, View
# Chaco imports
-from enthought.chaco.api import ArrayPlotData, jet, Plot
-from enthought.chaco.image_data import FunctionImageData
-from enthought.chaco.tools.api import PanTool, ZoomTool
+from enthought.chaco.api import ArrayPlotData, jet, Plot, HPlotContainer, \
+ ColorBar, DataRange1D, DataRange2D, LinearMapper, ImageData
+from enthought.chaco.tools.api import PanTool, ZoomTool, RangeSelection, \
+ RangeSelectionOverlay
from enthought.chaco.tools.image_inspector_tool import ImageInspectorTool, \
ImageInspectorOverlay
-from enthought.chaco.function_data_source import FunctionDataSource
+
+if not hasattr(DataRange2D, "_subranges_updated"):
+ print "You'll need to add _subranges updated to enthought/chaco/data_range_2d.py"
+ print 'Add this at the correct indentation level:'
+ print
+ print ' @on_trait_change("_xrange.updated,_yrange.updated")'
+ print ' def _subranges_updated(self):'
+ print ' self.updated = True'
+ print
+ raise RuntimeError
+
+class FunctionImageData(ImageData):
+ # The function to call with the low and high values of the range.
+ # It should return an array of values.
+ func = Callable
+
+ # A reference to a datarange
+ data_range = Instance(DataRange2D)
+
+ def __init__(self, **kw):
+ # Explicitly call the AbstractDataSource constructor because
+ # the ArrayDataSource ctor wants a data array
+ ImageData.__init__(self, **kw)
+ self.recalculate()
+
+ @on_trait_change('data_range.updated')
+ def recalculate(self):
+ if self.func is not None and self.data_range is not None:
+ newarray = self.func(self.data_range.low, self.data_range.high)
+ ImageData.set_data(self, newarray)
+ else:
+ self._data = zeros((512,512),dtype=float)
+
+ def set_data(self, *args, **kw):
+ raise RuntimeError("Cannot set numerical data on a FunctionDataSource")
+
+ def set_mask(self, mask):
+ # This would be REALLY FREAKING SLICK, but it's current unimplemented
+ raise NotImplementedError
+
+ def remove_mask(self):
+ raise NotImplementedError
+
+
+
+class ImagePixelizerHelper(object):
+ index = None
+ def __init__(self, panner):
+ self.panner = panner
+
+ def __call__(self, low, high):
+ b = self.panner.set_low_high(low, high)
+ if self.index is not None:
+ num_x_ticks = b.shape[0] + 1
+ num_y_ticks = b.shape[1] + 1
+ xs = mgrid[low[0]:high[0]:num_x_ticks*1j]
+ ys = mgrid[low[1]:high[1]:num_y_ticks*1j]
+ self.index.set_data( xs, ys )
+ return b
class VariableMeshPannerView(HasTraits):
@@ -45,10 +105,11 @@
panner = Instance(VariableMeshPanner)
fid = Instance(FunctionImageData)
limits = Button
+ helper = Any
traits_view = View(
Group(
- Item('plot', editor=ComponentEditor(size=(512,512)),
+ Item('container', editor=ComponentEditor(size=(512,512)),
show_label=False),
Item('limits', show_label=False),
orientation = "vertical"),
@@ -60,17 +121,21 @@
super(VariableMeshPannerView, self).__init__(**kwargs)
# Create the plot
pd = ArrayPlotData()
+ plot = Plot(pd)
self.pd = pd
- fid = FunctionImageData(func = self.panner.set_low_high)
+ helper = ImagePixelizerHelper(self.panner)
+ fid = FunctionImageData(func = helper)
+ fid._data = self.panner.buffer
self.fid = fid
bounds = self.panner.bounds
pd.set_data("imagedata", fid)
- plot = Plot(pd)
- img_plot = plot.img_plot("imagedata", colormap=jet)[0]
-
- xlim, ylim = self.panner.bounds
- plot.range2d.set_bounds( (xlim[0], ylim[0]), (xlim[1], ylim[1]) )
+ img_plot = plot.img_plot("imagedata", colormap=jet,
+ interpolation='nearest',
+ xbounds=(0.0, 1.0),
+ ybounds=(0.0, 1.0))[0]
+ helper.index = img_plot.index
+ self.helper = helper
fid.data_range = plot.range2d
@@ -85,6 +150,36 @@
img_plot.overlays.append(overlay)
self.plot = plot
+ image_value_range = DataRange1D(fid)
+ cbar_index_mapper = LinearMapper(range=image_value_range)
+ self.colorbar = ColorBar(index_mapper=cbar_index_mapper,
+ plot=img_plot,
+ padding_right=40,
+ resizable='v',
+ width=30)
+
+ self.colorbar.tools.append(
+ PanTool(self.colorbar, constrain_direction="y", constrain=True))
+ zoom_overlay = ZoomTool(self.colorbar, axis="index", tool_mode="range",
+ always_on=True, drag_button="right")
+ self.colorbar.overlays.append(zoom_overlay)
+
+ # create a range selection for the colorbar
+ range_selection = RangeSelection(component=self.colorbar)
+ self.colorbar.tools.append(range_selection)
+ self.colorbar.overlays.append(
+ RangeSelectionOverlay(component=self.colorbar,
+ border_color="white",
+ alpha=0.8, fill_color="lightgray"))
+
+ # we also want to the range selection to inform the cmap plot of
+ # the selection, so set that up as well
+ range_selection.listeners.append(img_plot)
+
+ self.container = HPlotContainer(padding=30)
+ self.container.add(self.colorbar)
+ self.container.add(self.plot)
+
def _limits_fired(self):
print self.pd["imagedata"].min(), self.pd["imagedata"].max(),
print self.fid.data.min(), self.fid.data.max()
More information about the yt-svn
mailing list