예제 #1
0
class LinePlotUI(HasTraits):
    # Line data source
    line_data_source = Instance(LineDataSource)

    # container for all plots
    container = Instance(HPlotContainer)

    # Plot components within this container
    line_plot = Instance(Plot)

    # Plot data
    pd = Instance(ArrayPlotData)

    # Traits view definitions:
    traits_view = View(Group(
        UItem('container', editor=ComponentEditor(size=(500, 200)))),
                       resizable=True)

    # -------------------------------------------------------------------------
    # Private Traits
    # -------------------------------------------------------------------------

    # -------------------------------------------------------------------------
    # Public View interface
    # -------------------------------------------------------------------------

    def __init__(self, line_data_source=None):
        super(LinePlotUI, self).__init__()
        with errstate(invalid='ignore'):
            self.create_plot()
        self.line_data_source = line_data_source

    def create_plot(self):

        self.pd = ArrayPlotData(line_index=array([]), line_value=array([]))

        # Create the colormapped scalar plot
        self.line_plot = Plot(self.pd)
        self.line_plot.plot(("line_index", "line_value"), type="line")

        # Create a container and add components
        self.container = HPlotContainer()
        self.container.add(self.line_plot)

    @on_trait_change('line_data_source.data_source_changed')
    def update(self):
        xs = self.line_data_source.xs
        ys = self.line_data_source.ys
        self.pd.update(line_index=xs, line_value=ys)
        self.container.invalidate_draw()
        self.container.request_redraw()
예제 #2
0
class MandelbrotPlot(HasTraits):
    """View and Controller for the Mandelbrot Plot interface."""

    mandelbrot_model_view = View(
        VGroup(
            HGroup(
                Item("use_multiprocessing", label="multiprocessing?"),
                Item("number_of_processors", label="processors"),
                label="multiprocessing",
                show_border=True,
            ),
            VGroup(
                Item("max_iterations"),
                Item("x_steps"),
                Item("y_steps"),
                label="calculation",
                show_border=True,
            ),
        ),
        buttons=OKCancelButtons,
        kind="modal",
        resizable=True,
        title="Mandelbrot calculation settings",
        icon=None,
    )
    traits_view = View(
        VGroup(
            HGroup(
                Item("mandelbrot_model", show_label=False),
                Item("colormap"),
                Item("reset_button", show_label=False),
            ),
            Item("container", editor=ComponentEditor(), show_label=False),
            orientation="vertical",
        ),
        resizable=True,
        title="mandelbrot",
    )

    mandelbrot_model = Instance(MandelbrotModel, view=mandelbrot_model_view)
    container = Instance(HPlotContainer)
    colormap = Enum(colormaps)
    reset_button = Button(label="reset")

    _initial_region = (-2.25, 0.75, -1.25, 1.25)
    _plot_data = ArrayPlotData()
    _plot_object = Plot(_plot_data)

    def __init__(self, *args, **kwargs):
        """Instantiates the mandelbrot model and necessary objects for the view/controller."""
        super().__init__(*args, **kwargs)
        self.mandelbrot_model = MandelbrotModel()
        self._update_with_initial_plot_data()

        self.image_plot = self._create_image_plot()
        self.container = HPlotContainer(padding=10,
                                        fill_padding=True,
                                        bgcolor="white",
                                        use_backbuffer=True)
        self.container.add(self._plot_object)
        self._fix_aspect_ratio()
        self._colormap_changed()
        self._append_tools()

    def _create_image_plot(self):
        """Return a Chaco image plot from the plot object referencing the ArrayPlotData fields."""
        return self._plot_object.img_plot("mandelbrot",
                                          xbounds="x_bounds",
                                          ybounds="y_bounds")[0]

    def _fix_aspect_ratio(self):
        """Fix the aspect ratio of the container."""
        x_width = (self.mandelbrot_model.latest_xs[-1] -
                   self.mandelbrot_model.latest_xs[0])
        y_width = (self.mandelbrot_model.latest_ys[-1] -
                   self.mandelbrot_model.latest_ys[0])
        self.container.aspect_ratio = x_width / y_width

    def _update_plot_data(self, mandelbrot_C: numpy.ndarray) -> None:
        """Update the plot_data attribute with passed values.

        Updates the main 2d-array data with mandelbrot_C values
        Updates the x bounds and y bounds of the image with the latest values
         stored on the mandelbrot model.

        :param mandelbrot_C:
        """
        self._plot_data.set_data("mandelbrot", mandelbrot_C)
        self._plot_data.set_data("x_bounds", self.mandelbrot_model.latest_xs)
        self._plot_data.set_data("y_bounds", self.mandelbrot_model.latest_ys)
        if hasattr(self, "image_plot"):
            self.image_plot.index.set_data(
                xdata=self.mandelbrot_model.latest_xs,
                ydata=self.mandelbrot_model.latest_ys,
            )

    def _append_tools(self):
        """Add tools to the necessary components."""
        zoom = RecalculatingZoomTool(
            self._zoom_recalculation_method,
            component=self.image_plot,
            tool_mode="box",
            always_on=True,
        )
        self.image_plot.overlays.append(zoom)

    def _zoom_recalculation_method(self, mins: Tuple[float, float],
                                   maxs: Tuple[float, float]):
        """Callable for the RecalculatingZoomTool to recalculate/display the mandelbrot set on zoom events.

        :param mins: min positions in selected zoom range
        :param maxs: max positions in selected zoom range
        :return:
        """
        min_x, max_x = mins[0], maxs[0]
        min_y, max_y = mins[1], maxs[1]

        mandelbrot_C = self._recalculate_mandelbrot(min_x, max_x, min_y, max_y)
        self._update_plot_data(mandelbrot_C)
        self.container.invalidate_draw()
        self.container.request_redraw()
        self._fix_aspect_ratio()

    def _recalculate_mandelbrot(self, min_x: float, max_x: float, min_y: float,
                                max_y: float) -> numpy.ndarray:
        """Recalculate the mandelbrot set for a given region.

        :param min_x:
        :param max_x:
        :param min_y:
        :param max_y:
        :return:
        """
        z = self.mandelbrot_model.create_initial_array(min_x, max_x, min_y,
                                                       max_y)
        return self.mandelbrot_model.calculate_mandelbrot(z[:-1, :-1])

    def _mandelbrot_model_changed(self):
        """Method automatically called by Traits when mandelbrot_model attribute changes.

        Recalculates the mandelbrot set for the current range.
        """
        if self.mandelbrot_model.latest_xs is None:
            return
        min_x, max_x = (
            self.mandelbrot_model.latest_xs[-1],
            self.mandelbrot_model.latest_xs[0],
        )
        min_y, max_y = (
            self.mandelbrot_model.latest_ys[-1],
            self.mandelbrot_model.latest_ys[0],
        )
        mandelbrot_C = self._recalculate_mandelbrot(min_x, max_x, min_y, max_y)
        self._update_plot_data(mandelbrot_C)
        self.container.invalidate_draw()
        self.container.request_redraw()
        self._fix_aspect_ratio()

    def _colormap_changed(self):
        """Method automatically called by Traits when colormap attribute changes.

        Updates the color map for the image plot with the selected colormap.
        """
        self._cmap = default_colormaps.color_map_name_dict[self.colormap]
        if self.image_plot is not None:
            value_range = self.image_plot.color_mapper.range
            self.image_plot.color_mapper = self._cmap(value_range)
            self.container.request_redraw()

    def _reset_button_fired(self):
        """Method automatically called by Traits when reset_button fired.

        Resets to the initial range and recalculates the plot.
        """
        self._update_with_initial_plot_data()
        self._fix_aspect_ratio()

    def _update_with_initial_plot_data(self):
        """Creates the initial mesh-grid and mandelbrot values on the grid."""
        self._initial_z_array = self.mandelbrot_model.create_initial_array(
            *self._initial_region)
        mandelbrot_C = self.mandelbrot_model.calculate_mandelbrot(
            self._initial_z_array[:-1, :-1])
        self._update_plot_data(mandelbrot_C)
class ImageGUI(HasTraits):
    
    # TO FIX : put here the last available shot
    #shot = File('L:\\data\\app3\\2011\\1108\\110823\\column_5200.ascii')
    #shot = File('/home/pmd/atomcool/lab/data/app3/2012/1203/120307/column_3195.ascii')

    #-- Shot traits
    shotdir = Directory('/home/pmd/atomcool/lab/data/app3/2012/1203/120320/')
    shots = List(Str)
    selectedshot = List(Str)
    namefilter = Str('column')

    #-- Report trait
    report = Str

    #-- Displayed analysis results
    number = Float
     
    #-- Column density plot container
    column_density = Instance(HPlotContainer)
    #---- Plot components within this container
    imgplot     = Instance(CMapImagePlot)
    cross_plot  = Instance(Plot)
    cross_plot2 = Instance(Plot)
    colorbar    = Instance(ColorBar)
    #---- Plot data
    pd = Instance(ArrayPlotData)
    #---- Colorbar 
    num_levels = Int(15)
    colormap = Enum(color_map_name_dict.keys())

    #-- Crosshair location
    cursor = Instance(BaseCursorTool)
    xy = DelegatesTo('cursor', prefix='current_position')
    xpos = Float(0.)
    ypos = Float(0.)
    xpos_read = Float(0.)
    ypos_read = Float(0.)
    cursor_group = Group( Group(Item('xpos', show_label=True), 
	                        Item('xpos_read', show_label=False, style="readonly"),
				orientation='horizontal'),
			  Group(Item('ypos', show_label=True), 
				Item('ypos_read', show_label=False, style="readonly"),
				orientation='horizontal'),
		          orientation='vertical', layout='normal',springy=True)

    
    #---------------------------------------------------------------------------
    # Traits View Definitions
    #---------------------------------------------------------------------------
    
    traits_view = View(
                    Group(
                      #Directory
                      Item( 'shotdir',style='simple', editor=DirectoryEditor(), width = 400, \
				      show_label=False, resizable=False ),
                      #Bottom
                      HSplit(
		        #-- Pane for shot selection
        	        Group(
		          Item( 'namefilter', show_label=False,springy=False),		
                          Item( 'shots',show_label=False, width=180, height= 360, \
					editor = TabularEditor(selected='selectedshot',\
					editable=False,multi_select=True,\
					adapter=SelectAdapter()) ),
			  cursor_group,
                          orientation='vertical',
		          layout='normal', ),

		        #-- Pane for column density plots
			Group(
			  Item('column_density',editor=ComponentEditor(), \
                                           show_label=False, width=600, height=500, \
                                           resizable=True ), 
			  Item('report',show_label=False, width=180, \
					springy=True, style='custom' ),
			  layout='tabbed', springy=True),

			#-- Pane for analysis results
			Group(
		          Item('number',show_label=False)
			  )
                      ),
                      orientation='vertical',
                      layout='normal',
                    ),
                  width=1400, height=500, resizable=True)
    
    #-- Pop-up view when Plot->Edit is selcted from the menu
    plot_edit_view = View(
                    Group(Item('num_levels'),
                          Item('colormap')),
                          buttons=["OK","Cancel"])
                          
    
    #---------------------------------------------------------------------------
    # Private Traits
    #---------------------------------------------------------------------------

    #-- Represents the region where the data set is defined
    _image_index = Instance(GridDataSource) 

    #-- Represents the data that will be plotted on the grid
    _image_value = Instance(ImageData)

    #-- Represents the color map that will be used
    _cmap = Trait(jet, Callable)
    
    
    #---------------------------------------------------------------------------
    # Public View interface
    #---------------------------------------------------------------------------

    def __init__(self, *args, **kwargs):
	#-- super is used to run the inherited __init__ method
	#-- this ensures that all the Traits machinery is properly setup
	#-- even though the __init__ method is overridden
        super(ImageGUI, self).__init__(*args, **kwargs)

	#-- after running the inherited __init__, a plot is created
        self.create_plot()



    def create_plot(self):

        #-- Create the index for the x an y axes and the range over
	#-- which they vary
        self._image_index = GridDataSource(array([]), array([]),
                                          sort_order=("ascending","ascending"))
        image_index_range = DataRange2D(self._image_index)
        
	#-- I believe this is what allows tracking the mouse
        self._image_index.on_trait_change(self._metadata_changed,
                                          "metadata_changed")


	#-- Create the image values and determine their range
        self._image_value = ImageData(data=array([]), value_depth=1)
        image_value_range = DataRange1D(self._image_value)
        
        # Create the image plot
        self.imgplot = CMapImagePlot( index=self._image_index,
                                      value=self._image_value,
                                      index_mapper=GridMapper(range=image_index_range),
                                      color_mapper=self._cmap(image_value_range),)
                                 

        # Add a left axis to the plot
        left = PlotAxis(orientation='left',
                        title= "axial",
                        mapper=self.imgplot.index_mapper._ymapper,
                        component=self.imgplot)
        self.imgplot.overlays.append(left)

        # Add a bottom axis to the plot
        bottom = PlotAxis(orientation='bottom',
                          title= "radial",
                          mapper=self.imgplot.index_mapper._xmapper,
                          component=self.imgplot)
        self.imgplot.overlays.append(bottom)


        # Add some tools to the plot
        self.imgplot.tools.append(PanTool(self.imgplot,drag_button="right",
                                            constrain_key="shift"))

        self.imgplot.overlays.append(ZoomTool(component=self.imgplot,
                                            tool_mode="box", always_on=False))

        # Create a colorbar
        cbar_index_mapper = LinearMapper(range=image_value_range)
        self.colorbar = ColorBar(index_mapper=cbar_index_mapper,
                                 plot=self.imgplot,
                                 padding_top=self.imgplot.padding_top,
                                 padding_bottom=self.imgplot.padding_bottom,
                                 padding_right=40,
                                 resizable='v',
                                 width=30)


	# Add a cursor 
	self.cursor = CursorTool( self.imgplot, drag_button="left", color="white")
	# the cursor is a rendered component so it goes in the overlays list
	self.imgplot.overlays.append(self.cursor)
                        
        # Create the two cross plots
        self.pd = ArrayPlotData(line_index = array([]),
                                line_value = array([]),
                                scatter_index = array([]),
                                scatter_value = array([]),
                                scatter_color = array([]))

        self.cross_plot = Plot(self.pd, resizable="h")
        self.cross_plot.height = 100
        self.cross_plot.padding = 20
        self.cross_plot.plot(("line_index", "line_value"),
                             line_style="dot")
        self.cross_plot.plot(("scatter_index","scatter_value","scatter_color"),
                             type="cmap_scatter",
                             name="dot",
                             color_mapper=self._cmap(image_value_range),
                             marker="circle",
                             marker_size=6)

        self.cross_plot.index_range = self.imgplot.index_range.x_range

        self.pd.set_data("line_index2", array([]))
        self.pd.set_data("line_value2", array([]))
        self.pd.set_data("scatter_index2", array([]))
        self.pd.set_data("scatter_value2", array([]))
        self.pd.set_data("scatter_color2", array([]))

        self.cross_plot2 = Plot(self.pd, width = 140, orientation="v", resizable="v", padding=20, padding_bottom=160)
        self.cross_plot2.plot(("line_index2", "line_value2"),
                             line_style="dot")
        self.cross_plot2.plot(("scatter_index2","scatter_value2","scatter_color2"),
                             type="cmap_scatter",
                             name="dot",
                             color_mapper=self._cmap(image_value_range),
                             marker="circle",
                             marker_size=8)

        self.cross_plot2.index_range = self.imgplot.index_range.y_range


        # Create a container and add sub-containers and components
        self.column_density = HPlotContainer(padding=40, fill_padding=True,
                                        bgcolor = "white", use_backbuffer=False)
        inner_cont = VPlotContainer(padding=0, use_backbuffer=True)
        inner_cont.add(self.cross_plot)
	self.imgplot.padding =20
	inner_cont.add(self.imgplot)
        self.column_density.add(self.colorbar)
        self.column_density.add(inner_cont)
        self.column_density.add(self.cross_plot2)

    def update(self):
	#print self.cursor.current_index
	#self.cursor.current_position = 100.,100.
        self.shots = self.populate_shot_list()
	print self.selectedshot    
        imgdata, self.report = self.load_imagedata()
        if imgdata is not None:
            self.minz = imgdata.min()
            self.maxz = imgdata.max()
            self.colorbar.index_mapper.range.low = self.minz
            self.colorbar.index_mapper.range.high = self.maxz
            xs=numpy.linspace(0,imgdata.shape[0],imgdata.shape[0]+1)
            ys=numpy.linspace(0,imgdata.shape[1],imgdata.shape[1]+1)
            #print xs
            #print ys
            self._image_index.set_data(xs,ys)
            self._image_value.data = imgdata
            self.pd.set_data("line_index", xs)
            self.pd.set_data("line_index2",ys)
            self.column_density.invalidate_draw()
            self.column_density.request_redraw()                        

    def populate_shot_list(self):
        try:
            shot_list = os.listdir(self.shotdir)
	    fun = lambda x: iscol(x,self.namefilter)
            shot_list = filter( fun, shot_list)
	    shot_list = sorted(shot_list)
        except ValueError:
            print " *** Not a valid directory path ***"
        return shot_list

    def load_imagedata(self):
        try:
            directory = self.shotdir
	    if self.selectedshot == []:
		    filename = self.shots[0]
	    else:
		    filename = self.selectedshot[0]
            #shotnum = filename[filename.rindex('_')+1:filename.rindex('.ascii')]
	    shotnum = filename[:filename.index('_')]
        except ValueError:
            print " *** Not a valid path *** " 
            return None
        # Set data path
        # Prepare PlotData object
	print "Loading file #%s from %s" % (filename,directory)
        return import_data.load(directory,filename), import_data.load_report(directory,shotnum)


    #---------------------------------------------------------------------------
    # Event handlers
    #---------------------------------------------------------------------------
    
    def _selectedshot_changed(self):
	print self.selectedshot
        self.update()

    def _shots_changed(self):
        self.shots = self.populate_shot_list()
	return

    def _namefilter_changed(self):
	self.shots = self.populate_shot_list()
	return

  
    def _xpos_changed(self):
	self.cursor.current_position = self.xpos, self.ypos
    def _ypos_changed(self):
	self.cursor.current_position = self.xpos, self.ypos

    def _metadata_changed(self):
	self._xy_changed()
	    
    def _xy_changed(self):
	self.xpos_read = self.cursor.current_index[0]
	self.ypos_read = self.cursor.current_index[1]
	#print self.cursor.current_index
        """ This function takes out a cross section from the image data, based
        on the cursor selections, and updates the line and scatter
        plots."""
        self.cross_plot.value_range.low = self.minz
        self.cross_plot.value_range.high = self.maxz
        self.cross_plot2.value_range.low = self.minz
        self.cross_plot2.value_range.high = self.maxz
        if True:
            x_ndx, y_ndx = self.cursor.current_index
            if y_ndx and x_ndx:
                self.pd.set_data("line_value",
				self._image_value.data[:,y_ndx])
                self.pd.set_data("line_value2",
				self._image_value.data[x_ndx,:])
                xdata, ydata = self._image_index.get_data()
                xdata, ydata = xdata.get_data(), ydata.get_data()
                self.pd.set_data("scatter_index", array([ydata[y_ndx]]))
                self.pd.set_data("scatter_index2", array([xdata[x_ndx]]))
                self.pd.set_data("scatter_value",
                    array([self._image_value.data[y_ndx, x_ndx]]))
                self.pd.set_data("scatter_value2",
                    array([self._image_value.data[y_ndx, x_ndx]]))
                self.pd.set_data("scatter_color",
                    array([self._image_value.data[y_ndx, x_ndx]]))
                self.pd.set_data("scatter_color2",
                    array([self._image_value.data[y_ndx, x_ndx]]))
        else:
            self.pd.set_data("scatter_value", array([]))
            self.pd.set_data("scatter_value2", array([]))
            self.pd.set_data("line_value", array([]))
            self.pd.set_data("line_value2", array([]))

    def _colormap_changed(self):
        self._cmap = color_map_name_dict[self.colormap]
        if hasattr(self, "polyplot"):
            value_range = self.polyplot.color_mapper.range
            self.polyplot.color_mapper = self._cmap(value_range)
            value_range = self.cross_plot.color_mapper.range
            self.cross_plot.color_mapper = self._cmap(value_range)
            # FIXME: change when we decide how best to update plots using
            # the shared colormap in plot object
            self.cross_plot.plots["dot"][0].color_mapper = self._cmap(value_range)
            self.cross_plot2.plots["dot"][0].color_mapper = self._cmap(value_range)
            self.column_density.request_redraw()

    def _num_levels_changed(self):
        if self.num_levels > 3:
            self.polyplot.levels = self.num_levels
            self.lineplot.levels = self.num_levels
예제 #4
0
class PlotUI(HasTraits):
    
    # container for all plots
    container = Instance(HPlotContainer)
    
    # Plot components within this container:
    polyplot = Instance(ContourPolyPlot)
    lineplot = Instance(ContourLinePlot)
    cross_plot = Instance(Plot)
    cross_plot2 = Instance(Plot)
    colorbar = Instance(ColorBar)
    
    # plot data
    pd = Instance(ArrayPlotData)

    # view options
    num_levels = Int(15)
    colormap = Enum(colormaps)
    
    #Traits view definitions:
    traits_view = View(
        Group(UItem('container', editor=ComponentEditor(size=(800,600)))),
        resizable=True)

    plot_edit_view = View(
        Group(Item('num_levels'),
              Item('colormap')),
              buttons=["OK","Cancel"])

    
    #---------------------------------------------------------------------------
    # Private Traits
    #---------------------------------------------------------------------------

    _image_index = Instance(GridDataSource)
    _image_value = Instance(ImageData)

    _cmap = Trait(default_colormaps.jet, Callable)

    #---------------------------------------------------------------------------
    # Public View interface
    #---------------------------------------------------------------------------

    def __init__(self, *args, **kwargs):
        super(PlotUI, self).__init__(*args, **kwargs)
        # FIXME: 'with' wrapping is temporary fix for infinite range in initial 
        # color map, which can cause a distracting warning print. This 'with'
        # wrapping should be unnecessary after fix in color_mapper.py.
        with errstate(invalid='ignore'):
            self.create_plot()

    def create_plot(self):

        # Create the mapper, etc
        self._image_index = GridDataSource(array([]),
                                          array([]),
                                          sort_order=("ascending","ascending"))
        image_index_range = DataRange2D(self._image_index)
        self._image_index.on_trait_change(self._metadata_changed,
                                          "metadata_changed")

        self._image_value = ImageData(data=array([]), value_depth=1)
        image_value_range = DataRange1D(self._image_value)



        # Create the contour plots
        self.polyplot = ContourPolyPlot(index=self._image_index,
                                        value=self._image_value,
                                        index_mapper=GridMapper(range=
                                            image_index_range),
                                        color_mapper=\
                                            self._cmap(image_value_range),
                                        levels=self.num_levels)

        self.lineplot = ContourLinePlot(index=self._image_index,
                                        value=self._image_value,
                                        index_mapper=GridMapper(range=
                                            self.polyplot.index_mapper.range),
                                        levels=self.num_levels)


        # Add a left axis to the plot
        left = PlotAxis(orientation='left',
                        title= "y",
                        mapper=self.polyplot.index_mapper._ymapper,
                        component=self.polyplot)
        self.polyplot.overlays.append(left)

        # Add a bottom axis to the plot
        bottom = PlotAxis(orientation='bottom',
                          title= "x",
                          mapper=self.polyplot.index_mapper._xmapper,
                          component=self.polyplot)
        self.polyplot.overlays.append(bottom)


        # Add some tools to the plot
        self.polyplot.tools.append(PanTool(self.polyplot,
                                           constrain_key="shift"))
        self.polyplot.overlays.append(ZoomTool(component=self.polyplot,
                                            tool_mode="box", always_on=False))
        self.polyplot.overlays.append(LineInspector(component=self.polyplot,
                                               axis='index_x',
                                               inspect_mode="indexed",
                                               write_metadata=True,
                                               is_listener=True,
                                               color="white"))
        self.polyplot.overlays.append(LineInspector(component=self.polyplot,
                                               axis='index_y',
                                               inspect_mode="indexed",
                                               write_metadata=True,
                                               color="white",
                                               is_listener=True))

        # Add these two plots to one container
        contour_container = OverlayPlotContainer(padding=20,
                                                 use_backbuffer=True,
                                                 unified_draw=True)
        contour_container.add(self.polyplot)
        contour_container.add(self.lineplot)


        # Create a colorbar
        cbar_index_mapper = LinearMapper(range=image_value_range)
        self.colorbar = ColorBar(index_mapper=cbar_index_mapper,
                                 plot=self.polyplot,
                                 padding_top=self.polyplot.padding_top,
                                 padding_bottom=self.polyplot.padding_bottom,
                                 padding_right=40,
                                 resizable='v',
                                 width=30)

        self.pd = ArrayPlotData(line_index = array([]),
                                line_value = array([]),
                                scatter_index = array([]),
                                scatter_value = array([]),
                                scatter_color = array([]))

        self.cross_plot = Plot(self.pd, resizable="h")
        self.cross_plot.height = 100
        self.cross_plot.padding = 20
        self.cross_plot.plot(("line_index", "line_value"),
                             line_style="dot")
        self.cross_plot.plot(("scatter_index","scatter_value","scatter_color"),
                             type="cmap_scatter",
                             name="dot",
                             color_mapper=self._cmap(image_value_range),
                             marker="circle",
                             marker_size=8)

        self.cross_plot.index_range = self.polyplot.index_range.x_range

        self.pd.set_data("line_index2", array([]))
        self.pd.set_data("line_value2", array([]))
        self.pd.set_data("scatter_index2", array([]))
        self.pd.set_data("scatter_value2", array([]))
        self.pd.set_data("scatter_color2", array([]))

        self.cross_plot2 = Plot(self.pd, width = 140, orientation="v", 
                                resizable="v", padding=20, padding_bottom=160)
        self.cross_plot2.plot(("line_index2", "line_value2"),
                             line_style="dot")
        self.cross_plot2.plot(("scatter_index2",
                               "scatter_value2",
                               "scatter_color2"),
                             type="cmap_scatter",
                             name="dot",
                             color_mapper=self._cmap(image_value_range),
                             marker="circle",
                             marker_size=8)

        self.cross_plot2.index_range = self.polyplot.index_range.y_range



        # Create a container and add components
        self.container = HPlotContainer(padding=40, fill_padding=True,
                                        bgcolor = "white", use_backbuffer=False)
        inner_cont = VPlotContainer(padding=0, use_backbuffer=True)
        inner_cont.add(self.cross_plot)
        inner_cont.add(contour_container)
        self.container.add(self.colorbar)
        self.container.add(inner_cont)
        self.container.add(self.cross_plot2)


    def update(self, model):
        self.minz = model.minz
        self.maxz = model.maxz
        self.colorbar.index_mapper.range.low = self.minz
        self.colorbar.index_mapper.range.high = self.maxz
        self._image_index.set_data(model.xs, model.ys)
        self._image_value.data = model.zs
        self.pd.update_data(line_index=model.xs, line_index2=model.ys)
        self.container.invalidate_draw()
        self.container.request_redraw()


    #---------------------------------------------------------------------------
    # Event handlers
    #---------------------------------------------------------------------------

    def _metadata_changed(self, old, new):
        """ This function takes out a cross section from the image data, based
        on the line inspector selections, and updates the line and scatter
        plots."""

        self.cross_plot.value_range.low = self.minz
        self.cross_plot.value_range.high = self.maxz
        self.cross_plot2.value_range.low = self.minz
        self.cross_plot2.value_range.high = self.maxz
        if self._image_index.metadata.has_key("selections"):
            x_ndx, y_ndx = self._image_index.metadata["selections"]
            if y_ndx and x_ndx:
                xdata, ydata = self._image_index.get_data()
                xdata, ydata = xdata.get_data(), ydata.get_data()
                self.pd.update_data(
                    line_value=self._image_value.data[y_ndx,:],
                    line_value2=self._image_value.data[:,x_ndx],
                    scatter_index=array([xdata[x_ndx]]),
                    scatter_index2=array([ydata[y_ndx]]),
                    scatter_value=array([self._image_value.data[y_ndx, x_ndx]]),
                    scatter_value2=array([self._image_value.data[y_ndx, x_ndx]]),
                    scatter_color=array([self._image_value.data[y_ndx, x_ndx]]),
                    scatter_color2=array([self._image_value.data[y_ndx, x_ndx]])
                )
        else:
            self.pd.update_data({"scatter_value": array([]),
                "scatter_value2": array([]), "line_value": array([]),
                "line_value2": array([])})

    def _colormap_changed(self):
        self._cmap = default_colormaps.color_map_name_dict[self.colormap]
        if self.polyplot is not None:
            value_range = self.polyplot.color_mapper.range
            self.polyplot.color_mapper = self._cmap(value_range)
            value_range = self.cross_plot.color_mapper.range
            self.cross_plot.color_mapper = self._cmap(value_range)
            # FIXME: change when we decide how best to update plots using
            # the shared colormap in plot object
            self.cross_plot.plots["dot"
                                  ][0].color_mapper = self._cmap(value_range)
            self.cross_plot2.plots["dot"
                                   ][0].color_mapper = self._cmap(value_range)
            self.container.request_redraw()

    def _num_levels_changed(self):
        if self.num_levels > 3:
            self.polyplot.levels = self.num_levels
            self.lineplot.levels = self.num_levels
class PlotUI(HasTraits):
    
    # container for all plots
    container = Instance(HPlotContainer)
    
    # Plot components within this container:
    polyplot = Instance(ContourPolyPlot)
    lineplot = Instance(ContourLinePlot)
    cross_plot = Instance(Plot)
    cross_plot2 = Instance(Plot)
    colorbar = Instance(ColorBar)
    
    # plot data
    pd = Instance(ArrayPlotData)

    # view options
    num_levels = Int(15)
    colormap = Enum(colormaps)
    
    #Traits view definitions:
    traits_view = View(
        Group(UItem('container', editor=ComponentEditor(size=(800,600)))),
        resizable=True)

    plot_edit_view = View(
        Group(Item('num_levels'),
              Item('colormap')),
              buttons=["OK","Cancel"])

    
    #---------------------------------------------------------------------------
    # Private Traits
    #---------------------------------------------------------------------------

    _image_index = Instance(GridDataSource)
    _image_value = Instance(ImageData)

    _cmap = Trait(default_colormaps.jet, Callable)

    #---------------------------------------------------------------------------
    # Public View interface
    #---------------------------------------------------------------------------

    def __init__(self, *args, **kwargs):
        super(PlotUI, self).__init__(*args, **kwargs)
        # FIXME: 'with' wrapping is temporary fix for infinite range in initial 
        # color map, which can cause a distracting warning print. This 'with'
        # wrapping should be unnecessary after fix in color_mapper.py.
        with errstate(invalid='ignore'):
            self.create_plot()

    def create_plot(self):

        # Create the mapper, etc
        self._image_index = GridDataSource(array([]),
                                          array([]),
                                          sort_order=("ascending","ascending"))
        image_index_range = DataRange2D(self._image_index)
        self._image_index.on_trait_change(self._metadata_changed,
                                          "metadata_changed")

        self._image_value = ImageData(data=array([]), value_depth=1)
        image_value_range = DataRange1D(self._image_value)



        # Create the contour plots
        self.polyplot = ContourPolyPlot(index=self._image_index,
                                        value=self._image_value,
                                        index_mapper=GridMapper(range=
                                            image_index_range),
                                        color_mapper=\
                                            self._cmap(image_value_range),
                                        levels=self.num_levels)

        self.lineplot = ContourLinePlot(index=self._image_index,
                                        value=self._image_value,
                                        index_mapper=GridMapper(range=
                                            self.polyplot.index_mapper.range),
                                        levels=self.num_levels)


        # Add a left axis to the plot
        left = PlotAxis(orientation='left',
                        title= "y",
                        mapper=self.polyplot.index_mapper._ymapper,
                        component=self.polyplot)
        self.polyplot.overlays.append(left)

        # Add a bottom axis to the plot
        bottom = PlotAxis(orientation='bottom',
                          title= "x",
                          mapper=self.polyplot.index_mapper._xmapper,
                          component=self.polyplot)
        self.polyplot.overlays.append(bottom)


        # Add some tools to the plot
        self.polyplot.tools.append(PanTool(self.polyplot,
                                           constrain_key="shift"))
        self.polyplot.overlays.append(ZoomTool(component=self.polyplot,
                                            tool_mode="box", always_on=False))
        self.polyplot.overlays.append(LineInspector(component=self.polyplot,
                                               axis='index_x',
                                               inspect_mode="indexed",
                                               write_metadata=True,
                                               is_listener=True,
                                               color="white"))
        self.polyplot.overlays.append(LineInspector(component=self.polyplot,
                                               axis='index_y',
                                               inspect_mode="indexed",
                                               write_metadata=True,
                                               color="white",
                                               is_listener=True))

        # Add these two plots to one container
        contour_container = OverlayPlotContainer(padding=20,
                                                 use_backbuffer=True,
                                                 unified_draw=True)
        contour_container.add(self.polyplot)
        contour_container.add(self.lineplot)


        # Create a colorbar
        cbar_index_mapper = LinearMapper(range=image_value_range)
        self.colorbar = ColorBar(index_mapper=cbar_index_mapper,
                                 plot=self.polyplot,
                                 padding_top=self.polyplot.padding_top,
                                 padding_bottom=self.polyplot.padding_bottom,
                                 padding_right=40,
                                 resizable='v',
                                 width=30)

        self.pd = ArrayPlotData(line_index = array([]),
                                line_value = array([]),
                                scatter_index = array([]),
                                scatter_value = array([]),
                                scatter_color = array([]))

        self.cross_plot = Plot(self.pd, resizable="h")
        self.cross_plot.height = 100
        self.cross_plot.padding = 20
        self.cross_plot.plot(("line_index", "line_value"),
                             line_style="dot")
        self.cross_plot.plot(("scatter_index","scatter_value","scatter_color"),
                             type="cmap_scatter",
                             name="dot",
                             color_mapper=self._cmap(image_value_range),
                             marker="circle",
                             marker_size=8)

        self.cross_plot.index_range = self.polyplot.index_range.x_range

        self.pd.set_data("line_index2", array([]))
        self.pd.set_data("line_value2", array([]))
        self.pd.set_data("scatter_index2", array([]))
        self.pd.set_data("scatter_value2", array([]))
        self.pd.set_data("scatter_color2", array([]))

        self.cross_plot2 = Plot(self.pd, width = 140, orientation="v", resizable="v", padding=20, padding_bottom=160)
        self.cross_plot2.plot(("line_index2", "line_value2"),
                             line_style="dot")
        self.cross_plot2.plot(("scatter_index2","scatter_value2","scatter_color2"),
                             type="cmap_scatter",
                             name="dot",
                             color_mapper=self._cmap(image_value_range),
                             marker="circle",
                             marker_size=8)

        self.cross_plot2.index_range = self.polyplot.index_range.y_range



        # Create a container and add components
        self.container = HPlotContainer(padding=40, fill_padding=True,
                                        bgcolor = "white", use_backbuffer=False)
        inner_cont = VPlotContainer(padding=0, use_backbuffer=True)
        inner_cont.add(self.cross_plot)
        inner_cont.add(contour_container)
        self.container.add(self.colorbar)
        self.container.add(inner_cont)
        self.container.add(self.cross_plot2)


    def update(self, model):
        self.minz = model.minz
        self.maxz = model.maxz
        self.colorbar.index_mapper.range.low = self.minz
        self.colorbar.index_mapper.range.high = self.maxz
        self._image_index.set_data(model.xs, model.ys)
        self._image_value.data = model.zs
        self.pd.set_data("line_index", model.xs)
        self.pd.set_data("line_index2", model.ys)
        self.container.invalidate_draw()
        self.container.request_redraw()


    #---------------------------------------------------------------------------
    # Event handlers
    #---------------------------------------------------------------------------

    def _metadata_changed(self, old, new):
        """ This function takes out a cross section from the image data, based
        on the line inspector selections, and updates the line and scatter
        plots."""

        self.cross_plot.value_range.low = self.minz
        self.cross_plot.value_range.high = self.maxz
        self.cross_plot2.value_range.low = self.minz
        self.cross_plot2.value_range.high = self.maxz
        if self._image_index.metadata.has_key("selections"):
            x_ndx, y_ndx = self._image_index.metadata["selections"]
            if y_ndx and x_ndx:
                self.pd.set_data("line_value",
                                 self._image_value.data[y_ndx,:])
                self.pd.set_data("line_value2",
                                 self._image_value.data[:,x_ndx])
                xdata, ydata = self._image_index.get_data()
                xdata, ydata = xdata.get_data(), ydata.get_data()
                self.pd.set_data("scatter_index", array([xdata[x_ndx]]))
                self.pd.set_data("scatter_index2", array([ydata[y_ndx]]))
                self.pd.set_data("scatter_value",
                    array([self._image_value.data[y_ndx, x_ndx]]))
                self.pd.set_data("scatter_value2",
                    array([self._image_value.data[y_ndx, x_ndx]]))
                self.pd.set_data("scatter_color",
                    array([self._image_value.data[y_ndx, x_ndx]]))
                self.pd.set_data("scatter_color2",
                    array([self._image_value.data[y_ndx, x_ndx]]))
        else:
            self.pd.set_data("scatter_value", array([]))
            self.pd.set_data("scatter_value2", array([]))
            self.pd.set_data("line_value", array([]))
            self.pd.set_data("line_value2", array([]))

    def _colormap_changed(self):
        self._cmap = default_colormaps.color_map_name_dict[self.colormap]
        if self.polyplot is not None:
            value_range = self.polyplot.color_mapper.range
            self.polyplot.color_mapper = self._cmap(value_range)
            value_range = self.cross_plot.color_mapper.range
            self.cross_plot.color_mapper = self._cmap(value_range)
            # FIXME: change when we decide how best to update plots using
            # the shared colormap in plot object
            self.cross_plot.plots["dot"][0].color_mapper = self._cmap(value_range)
            self.cross_plot2.plots["dot"][0].color_mapper = self._cmap(value_range)
            self.container.request_redraw()

    def _num_levels_changed(self):
        if self.num_levels > 3:
            self.polyplot.levels = self.num_levels
            self.lineplot.levels = self.num_levels
예제 #6
0
class ImagePlotUI(HasTraits):
    # Image data source
    image_data_source = Instance(ImageDataSource)

    # container for all plots
    container = Instance(HPlotContainer)

    # Plot components within this container
    plot = Instance(CMapImagePlot)
    colorbar = Instance(ColorBar)

    # View options
    colormap = Enum(colormaps)

    # Traits view definitions:
    traits_view = View(Group(
        UItem('container', editor=ComponentEditor(size=(500, 450)))),
                       resizable=True)

    plot_edit_view = View(Group(Item('colormap')), buttons=["OK", "Cancel"])

    # -------------------------------------------------------------------------
    # Private Traits
    # -------------------------------------------------------------------------

    _image_index = Instance(GridDataSource)
    _image_value = Instance(ImageData)

    _cmap = Trait(default_colormaps.gray, Callable)

    # -------------------------------------------------------------------------
    # Public View interface
    # -------------------------------------------------------------------------

    def __init__(self, image_data_source=None):
        super(ImagePlotUI, self).__init__()
        with errstate(invalid='ignore'):
            self.create_plot()
        self.image_data_source = image_data_source

    def create_plot(self):

        # Create the mapper, etc
        self._image_index = GridDataSource(array([]),
                                           array([]),
                                           sort_order=("ascending",
                                                       "ascending"))
        image_index_range = DataRange2D(self._image_index)
        # self._image_index.on_trait_change(self._metadata_changed,
        #                                   "metadata_changed")

        self._image_value = ImageData(data=array([]), value_depth=1)
        image_value_range = DataRange1D(self._image_value)

        # Create the colormapped scalar plot
        self.plot = CMapImagePlot(
            index=self._image_index,
            index_mapper=GridMapper(range=image_index_range),
            value=self._image_value,
            value_mapper=self._cmap(image_value_range))

        # Add a left axis to the plot
        left = PlotAxis(orientation='left',
                        title="y",
                        mapper=self.plot.index_mapper._ymapper,
                        component=self.plot)
        self.plot.overlays.append(left)

        # Add a bottom axis to the plot
        bottom = PlotAxis(orientation='bottom',
                          title="x",
                          mapper=self.plot.index_mapper._xmapper,
                          component=self.plot)
        self.plot.overlays.append(bottom)

        # Add some tools to the plot
        self.plot.tools.append(PanTool(self.plot, constrain_key="shift"))
        self.plot.overlays.append(
            ZoomTool(component=self.plot, tool_mode="box", always_on=False))

        # Create a colorbar
        cbar_index_mapper = LinearMapper(range=image_value_range)
        self.colorbar = ColorBar(index_mapper=cbar_index_mapper,
                                 plot=self.plot,
                                 padding_top=self.plot.padding_top,
                                 padding_bottom=self.plot.padding_bottom,
                                 padding_right=40,
                                 resizable='v',
                                 width=10)

        # Create a container and add components
        self.container = HPlotContainer(padding=40,
                                        fill_padding=True,
                                        bgcolor="white",
                                        use_backbuffer=False)
        self.container.add(self.colorbar)
        self.container.add(self.plot)

    @on_trait_change('image_data_source.data_source_changed')
    def update_plot(self):
        xs = self.image_data_source.xs
        ys = self.image_data_source.ys
        zs = self.image_data_source.zs
        self.colorbar.index_mapper.range.low = zs.min()
        self.colorbar.index_mapper.range.high = zs.max()
        self._image_index.set_data(xs, ys)
        self._image_value.data = zs
        self.container.invalidate_draw()
        self.container.request_redraw()

    # -------------------------------------------------------------------------
    # Event handlers
    # -------------------------------------------------------------------------

    def _colormap_changed(self):
        self._cmap = default_colormaps.color_map_name_dict[self.colormap]
        if self.plot is not None:
            value_range = self.plot.color_mapper.range
            self.plot.color_mapper = self._cmap(value_range)
            self.container.request_redraw()
class ImageGUI(HasTraits):

    # TO FIX : put here the last available shot
    shot = File("L:\\data\\app3\\2011\\1108\\110823\\column_5200.ascii")

    # ---------------------------------------------------------------------------
    # Traits View Definitions
    # ---------------------------------------------------------------------------

    traits_view = View(
        HSplit(
            Item(
                "shot",
                style="custom",
                editor=FileEditor(filter=["column_*.ascii"]),
                show_label=False,
                resizable=True,
                width=400,
            ),
            Item("container", editor=ComponentEditor(), show_label=False, width=800, height=800),
        ),
        width=1200,
        height=800,
        resizable=True,
        title="APPARATUS 3 :: Analyze Images",
    )

    plot_edit_view = View(Group(Item("num_levels"), Item("colormap")), buttons=["OK", "Cancel"])

    num_levels = Int(15)
    colormap = Enum(color_map_name_dict.keys())

    # ---------------------------------------------------------------------------
    # Private Traits
    # ---------------------------------------------------------------------------

    _image_index = Instance(GridDataSource)
    _image_value = Instance(ImageData)

    _cmap = Trait(jet, Callable)

    # ---------------------------------------------------------------------------
    # Public View interface
    # ---------------------------------------------------------------------------

    def __init__(self, *args, **kwargs):
        super(ImageGUI, self).__init__(*args, **kwargs)
        self.create_plot()

    def create_plot(self):

        # Create the mapper, etc
        self._image_index = GridDataSource(array([]), array([]), sort_order=("ascending", "ascending"))
        image_index_range = DataRange2D(self._image_index)

        self._image_index.on_trait_change(self._metadata_changed, "metadata_changed")

        self._image_value = ImageData(data=array([]), value_depth=1)
        image_value_range = DataRange1D(self._image_value)

        # Create the image plot
        self.imgplot = CMapImagePlot(
            index=self._image_index,
            value=self._image_value,
            index_mapper=GridMapper(range=image_index_range),
            color_mapper=self._cmap(image_value_range),
        )

        # Create the contour plots
        # ~ self.polyplot = ContourPolyPlot(index=self._image_index,
        # ~ value=self._image_value,
        # ~ index_mapper=GridMapper(range=
        # ~ image_index_range),
        # ~ color_mapper=\
        # ~ self._cmap(image_value_range),
        # ~ levels=self.num_levels)

        # ~ self.lineplot = ContourLinePlot(index=self._image_index,
        # ~ value=self._image_value,
        # ~ index_mapper=GridMapper(range=
        # ~ self.polyplot.index_mapper.range),
        # ~ levels=self.num_levels)

        # Add a left axis to the plot
        left = PlotAxis(
            orientation="left", title="axial", mapper=self.imgplot.index_mapper._ymapper, component=self.imgplot
        )
        self.imgplot.overlays.append(left)

        # Add a bottom axis to the plot
        bottom = PlotAxis(
            orientation="bottom", title="radial", mapper=self.imgplot.index_mapper._xmapper, component=self.imgplot
        )
        self.imgplot.overlays.append(bottom)

        # Add some tools to the plot
        # ~ self.polyplot.tools.append(PanTool(self.polyplot,
        # ~ constrain_key="shift"))
        self.imgplot.overlays.append(ZoomTool(component=self.imgplot, tool_mode="box", always_on=False))
        self.imgplot.overlays.append(
            LineInspector(
                component=self.imgplot,
                axis="index_x",
                inspect_mode="indexed",
                write_metadata=True,
                is_listener=False,
                color="white",
            )
        )
        self.imgplot.overlays.append(
            LineInspector(
                component=self.imgplot,
                axis="index_y",
                inspect_mode="indexed",
                write_metadata=True,
                color="white",
                is_listener=False,
            )
        )

        # Add these two plots to one container
        contour_container = OverlayPlotContainer(padding=20, use_backbuffer=True, unified_draw=True)
        contour_container.add(self.imgplot)
        # ~ contour_container.add(self.polyplot)
        # ~ contour_container.add(self.lineplot)

        # Create a colorbar
        cbar_index_mapper = LinearMapper(range=image_value_range)
        self.colorbar = ColorBar(
            index_mapper=cbar_index_mapper,
            plot=self.imgplot,
            padding_top=self.imgplot.padding_top,
            padding_bottom=self.imgplot.padding_bottom,
            padding_right=40,
            resizable="v",
            width=30,
        )

        # Create the two cross plots
        self.pd = ArrayPlotData(
            line_index=array([]),
            line_value=array([]),
            scatter_index=array([]),
            scatter_value=array([]),
            scatter_color=array([]),
        )

        self.cross_plot = Plot(self.pd, resizable="h")
        self.cross_plot.height = 100
        self.cross_plot.padding = 20
        self.cross_plot.plot(("line_index", "line_value"), line_style="dot")
        self.cross_plot.plot(
            ("scatter_index", "scatter_value", "scatter_color"),
            type="cmap_scatter",
            name="dot",
            color_mapper=self._cmap(image_value_range),
            marker="circle",
            marker_size=8,
        )

        self.cross_plot.index_range = self.imgplot.index_range.x_range

        self.pd.set_data("line_index2", array([]))
        self.pd.set_data("line_value2", array([]))
        self.pd.set_data("scatter_index2", array([]))
        self.pd.set_data("scatter_value2", array([]))
        self.pd.set_data("scatter_color2", array([]))

        self.cross_plot2 = Plot(self.pd, width=140, orientation="v", resizable="v", padding=20, padding_bottom=160)
        self.cross_plot2.plot(("line_index2", "line_value2"), line_style="dot")
        self.cross_plot2.plot(
            ("scatter_index2", "scatter_value2", "scatter_color2"),
            type="cmap_scatter",
            name="dot",
            color_mapper=self._cmap(image_value_range),
            marker="circle",
            marker_size=8,
        )

        self.cross_plot2.index_range = self.imgplot.index_range.y_range

        # Create a container and add components
        self.container = HPlotContainer(padding=40, fill_padding=True, bgcolor="white", use_backbuffer=False)
        inner_cont = VPlotContainer(padding=0, use_backbuffer=True)
        inner_cont.add(self.cross_plot)
        inner_cont.add(contour_container)
        self.container.add(self.colorbar)
        self.container.add(inner_cont)
        self.container.add(self.cross_plot2)

    def update(self):
        imgdata = self.load_imagedata()
        if imgdata is not None:
            self.minz = imgdata.min()
            self.maxz = imgdata.max()
            self.colorbar.index_mapper.range.low = self.minz
            self.colorbar.index_mapper.range.high = self.maxz
            xs = numpy.linspace(0, imgdata.shape[0], imgdata.shape[0] + 1)
            ys = numpy.linspace(0, imgdata.shape[1], imgdata.shape[1] + 1)
            print xs
            print ys
            self._image_index.set_data(xs, ys)
            self._image_value.data = imgdata
            self.pd.set_data("line_index", xs)
            self.pd.set_data("line_index2", ys)
            self.container.invalidate_draw()
            self.container.request_redraw()

    def load_imagedata(self):
        try:
            dir = self.shot[self.shot.index(":\\") + 2 : self.shot.rindex("\\") + 1]
            shotnum = self.shot[self.shot.rindex("_") + 1 : self.shot.rindex(".ascii")]
        except ValueError:
            print " *** Not a valid column density path *** "
            return None
        # Set data path
        # Prepare PlotData object
        print dir
        print shotnum
        return load(dir, shotnum)

    # ---------------------------------------------------------------------------
    # Event handlers
    # ---------------------------------------------------------------------------

    def _shot_changed(self):
        self.update()

    def _metadata_changed(self, old, new):
        """ This function takes out a cross section from the image data, based
        on the line inspector selections, and updates the line and scatter
        plots."""

        self.cross_plot.value_range.low = self.minz
        self.cross_plot.value_range.high = self.maxz
        self.cross_plot2.value_range.low = self.minz
        self.cross_plot2.value_range.high = self.maxz
        if self._image_index.metadata.has_key("selections"):
            x_ndx, y_ndx = self._image_index.metadata["selections"]
            if y_ndx and x_ndx:
                self.pd.set_data("line_value", self._image_value.data[y_ndx, :])
                self.pd.set_data("line_value2", self._image_value.data[:, x_ndx])
                xdata, ydata = self._image_index.get_data()
                xdata, ydata = xdata.get_data(), ydata.get_data()
                self.pd.set_data("scatter_index", array([xdata[x_ndx]]))
                self.pd.set_data("scatter_index2", array([ydata[y_ndx]]))
                self.pd.set_data("scatter_value", array([self._image_value.data[y_ndx, x_ndx]]))
                self.pd.set_data("scatter_value2", array([self._image_value.data[y_ndx, x_ndx]]))
                self.pd.set_data("scatter_color", array([self._image_value.data[y_ndx, x_ndx]]))
                self.pd.set_data("scatter_color2", array([self._image_value.data[y_ndx, x_ndx]]))
        else:
            self.pd.set_data("scatter_value", array([]))
            self.pd.set_data("scatter_value2", array([]))
            self.pd.set_data("line_value", array([]))
            self.pd.set_data("line_value2", array([]))

    def _colormap_changed(self):
        self._cmap = color_map_name_dict[self.colormap]
        if hasattr(self, "polyplot"):
            value_range = self.polyplot.color_mapper.range
            self.polyplot.color_mapper = self._cmap(value_range)
            value_range = self.cross_plot.color_mapper.range
            self.cross_plot.color_mapper = self._cmap(value_range)
            # FIXME: change when we decide how best to update plots using
            # the shared colormap in plot object
            self.cross_plot.plots["dot"][0].color_mapper = self._cmap(value_range)
            self.cross_plot2.plots["dot"][0].color_mapper = self._cmap(value_range)
            self.container.request_redraw()

    def _num_levels_changed(self):
        if self.num_levels > 3:
            self.polyplot.levels = self.num_levels
            self.lineplot.levels = self.num_levels