2006-04-16 20:25:54 +02:00
|
|
|
|
|
|
|
import pygtk
|
|
|
|
import gtk
|
|
|
|
import matplotlib
|
2006-04-19 20:25:44 +02:00
|
|
|
import scipy
|
2006-04-16 20:25:54 +02:00
|
|
|
from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas
|
2006-04-26 14:11:23 +02:00
|
|
|
from matplotlib.backends.backend_gtkagg import NavigationToolbar2GTK as NavigationToolbar2
|
2006-04-16 20:25:54 +02:00
|
|
|
from matplotlib.axes import Subplot
|
|
|
|
from matplotlib.figure import Figure
|
|
|
|
from matplotlib.numerix import arange, sin, pi
|
2006-04-18 11:19:59 +02:00
|
|
|
from matplotlib.widgets import RectangleSelector
|
2006-04-27 13:03:11 +02:00
|
|
|
from matplotlib import cm
|
2006-04-25 11:53:35 +02:00
|
|
|
from system import logger
|
2006-04-18 11:19:59 +02:00
|
|
|
|
2006-04-16 20:25:54 +02:00
|
|
|
|
2006-05-22 23:43:24 +02:00
|
|
|
class ObjectTable:
|
|
|
|
"""A 2D table of elements."""
|
|
|
|
|
|
|
|
def __init__(self, xsize=0, ysize=0, creator=None):
|
|
|
|
self._elements = []
|
|
|
|
self._creator = creator or (lambda : None)
|
|
|
|
self.xsize = xsize
|
|
|
|
self.ysize = ysize
|
|
|
|
self.resize(xsize, ysize)
|
|
|
|
|
|
|
|
def resize(self, xsize, ysize):
|
|
|
|
"""Resizes the table by removing and creating elements as required."""
|
|
|
|
# Delete or append new rows
|
|
|
|
del self._elements[ysize:]
|
|
|
|
new_rows = ysize - len(self._elements)
|
|
|
|
self._elements.extend([list() for i in range(new_rows)])
|
|
|
|
|
|
|
|
# Delete or append new columns
|
|
|
|
for row in self._elements:
|
|
|
|
del row[xsize:]
|
|
|
|
new_elems = xsize - len(row)
|
|
|
|
row.extend([self._creator() for i in range(new_elems)])
|
|
|
|
|
|
|
|
def __getitem__(self, index):
|
|
|
|
x, y = index
|
|
|
|
return self._elements[y][x]
|
|
|
|
|
|
|
|
def __setitem__(self, index, value):
|
|
|
|
x, y = index
|
|
|
|
self._elements[y][x] = value
|
|
|
|
|
|
|
|
|
|
|
|
class ViewFrame (gtk.Frame):
|
|
|
|
def __init__(self, view_frames):
|
|
|
|
gtk.Frame.__init__(self)
|
|
|
|
self.focused = False
|
|
|
|
self.view_frames = view_frames
|
|
|
|
self.empty_view = EmptyView()
|
|
|
|
|
|
|
|
view_frames.append(self)
|
|
|
|
if len(view_frames) == 1:
|
|
|
|
self.focus()
|
|
|
|
else:
|
|
|
|
self.unfocus()
|
|
|
|
|
|
|
|
self._view = self.empty_view
|
|
|
|
self.set_view(self._view)
|
|
|
|
self.show()
|
|
|
|
|
|
|
|
def focus(self):
|
|
|
|
"""Gets focus and ensures that no other window is in focus."""
|
|
|
|
if self.focused:
|
|
|
|
return self
|
|
|
|
|
|
|
|
for frame in self.view_frames:
|
|
|
|
frame.unfocus()
|
|
|
|
|
|
|
|
self.set_shadow_type(gtk.SHADOW_IN)
|
|
|
|
self.focused = True
|
|
|
|
return self
|
|
|
|
|
|
|
|
def unfocus(self):
|
|
|
|
"""Removes focus from the ViewFrame if it is focused."""
|
|
|
|
if not self.focused:
|
|
|
|
return
|
|
|
|
|
|
|
|
self.set_shadow_type(gtk.SHADOW_OUT)
|
|
|
|
self.focused = False
|
|
|
|
|
|
|
|
def set_view(self, view):
|
|
|
|
"""Set view to view or to empty view if parameter is None"""
|
|
|
|
# if None is passed, use empty view
|
|
|
|
if view == None:
|
|
|
|
view = self.empty_view
|
|
|
|
|
|
|
|
# # do nothing if the view is already there
|
|
|
|
# if view == self._view:
|
|
|
|
# return
|
|
|
|
|
|
|
|
# switch which widget we are listening to
|
|
|
|
# if self._view:
|
|
|
|
# self._view.disconnect(self.on_button_press_event)
|
|
|
|
view.connect("button-press-event", self.on_button_press_event)
|
|
|
|
|
|
|
|
# remove old view, set new view
|
|
|
|
self._view.hide()
|
|
|
|
self.remove(self._view)
|
|
|
|
self.add(view)
|
|
|
|
view.show()
|
|
|
|
|
|
|
|
self._view = view
|
|
|
|
|
|
|
|
def get_view(self):
|
|
|
|
"""Returns current view, or None if the empty view is set."""
|
|
|
|
if self._view == self.empty_view:
|
|
|
|
return None
|
|
|
|
return self._view
|
|
|
|
|
|
|
|
def on_button_press_event(self, widget, event):
|
|
|
|
print "foo"
|
|
|
|
if not self.focused:
|
|
|
|
self.focus()
|
|
|
|
|
2006-04-18 00:30:53 +02:00
|
|
|
class MainView (gtk.Notebook):
|
2006-05-22 23:43:24 +02:00
|
|
|
def __init__(self):
|
2006-04-18 00:30:53 +02:00
|
|
|
gtk.Notebook.__init__(self)
|
|
|
|
self.set_show_tabs(False)
|
|
|
|
self.set_show_border(False)
|
|
|
|
|
2006-05-22 23:43:24 +02:00
|
|
|
self._view_frames = []
|
|
|
|
self._views = ObjectTable(2, 2, lambda : ViewFrame(self._view_frames))
|
|
|
|
self._small_views = gtk.Table(2, 2, True)
|
|
|
|
self._small_views.set_col_spacings(4)
|
|
|
|
self._small_views.set_row_spacings(4)
|
|
|
|
self._large_view = ViewFrame(list())
|
|
|
|
self.update_small_views()
|
|
|
|
|
|
|
|
self.append_page(self._small_views)
|
|
|
|
self.append_page(self._large_view)
|
2006-04-18 00:30:53 +02:00
|
|
|
self.set_current_page(0)
|
2006-05-22 23:43:24 +02:00
|
|
|
self.show()
|
|
|
|
|
|
|
|
def __getitem__(self, x, y):
|
|
|
|
return self._views[x, y]
|
|
|
|
|
|
|
|
def update_small_views(self):
|
|
|
|
for x in range(self._views.xsize):
|
|
|
|
for y in range(self._views.ysize):
|
|
|
|
child = self._views[x,y]
|
|
|
|
self._small_views.attach(child, x, x+1, y, y+1)
|
2006-04-18 00:30:53 +02:00
|
|
|
|
2006-05-22 23:43:24 +02:00
|
|
|
def get_active_small_view(self):
|
|
|
|
for vf in self._view_frames:
|
|
|
|
if vf.focused:
|
|
|
|
return vf
|
|
|
|
return None
|
|
|
|
|
2006-04-18 00:30:53 +02:00
|
|
|
def goto_large(self):
|
2006-05-22 23:43:24 +02:00
|
|
|
vf = self.get_active_small_view()
|
|
|
|
view = vf.get_view()
|
|
|
|
vf.set_view(None)
|
|
|
|
self._large_view.set_view(view)
|
2006-04-18 00:30:53 +02:00
|
|
|
self.set_current_page(1)
|
|
|
|
|
2006-05-22 23:43:24 +02:00
|
|
|
def goto_small(self):
|
|
|
|
vf = self.get_active_small_view()
|
|
|
|
view = self._large_view.get_view()
|
|
|
|
self._large_view.set_view(None)
|
|
|
|
vf.set_view(view)
|
|
|
|
self.set_current_page(0)
|
2006-04-18 00:30:53 +02:00
|
|
|
|
|
|
|
def insert_view(self, view):
|
2006-05-22 23:43:24 +02:00
|
|
|
vf = self.get_active_small_view()
|
|
|
|
vf.set_view(view)
|
|
|
|
|
|
|
|
def show(self):
|
|
|
|
for vf in self._view_frames:
|
|
|
|
vf.show()
|
|
|
|
self._small_views.show()
|
|
|
|
gtk.Notebook.show(self)
|
|
|
|
|
|
|
|
# def insert_view(self, view)
|
|
|
|
|
2006-04-26 14:11:23 +02:00
|
|
|
class Plot (gtk.Frame):
|
|
|
|
|
|
|
|
def __init__(self, title):
|
|
|
|
gtk.Frame.__init__(self)
|
|
|
|
self.sel_obj = None
|
|
|
|
self.title = title
|
2006-04-27 16:38:48 +02:00
|
|
|
self.selection_listener = None
|
2006-05-22 23:43:24 +02:00
|
|
|
self.set_shadow_type(gtk.SHADOW_NONE)
|
2006-04-26 14:11:23 +02:00
|
|
|
|
|
|
|
def get_title(self):
|
|
|
|
return self.title
|
|
|
|
|
2006-04-27 16:38:48 +02:00
|
|
|
def selection_changed(self, selection):
|
2006-04-26 14:11:23 +02:00
|
|
|
pass
|
|
|
|
|
2006-04-27 16:38:48 +02:00
|
|
|
def set_selection_listener(self, listener):
|
|
|
|
"""Allow project to listen to selections.
|
|
|
|
|
|
|
|
The selection will propagate back to all plots through the
|
|
|
|
selection_changed() method. The listener will be called as
|
|
|
|
listener(dimension_name, ids).
|
|
|
|
"""
|
|
|
|
self.selection_listener = listener
|
2006-04-26 14:11:23 +02:00
|
|
|
|
|
|
|
def get_toolbar(self):
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
2006-04-17 22:27:39 +02:00
|
|
|
class SmallView (gtk.Table):
|
2006-04-26 14:11:23 +02:00
|
|
|
|
2006-04-17 22:27:39 +02:00
|
|
|
def __init__(self):
|
|
|
|
gtk.Table.__init__(self, 2, 2, True)
|
|
|
|
|
|
|
|
self.child_views = [[EmptyView(), EmptyView()],
|
|
|
|
[EmptyView(), EmptyView()]]
|
|
|
|
self.cols = 2
|
|
|
|
self.rows = 2
|
|
|
|
|
|
|
|
self.active_x = 0
|
|
|
|
self.active_y = 0
|
2006-04-18 00:30:53 +02:00
|
|
|
|
|
|
|
self.set_row_spacings(3)
|
|
|
|
self.set_col_spacings(3)
|
2006-04-26 14:11:23 +02:00
|
|
|
self._listener = None
|
2006-04-17 22:27:39 +02:00
|
|
|
|
|
|
|
for x in range(self.cols):
|
|
|
|
for y in range(self.rows):
|
|
|
|
child = self.child_views[x][y]
|
|
|
|
child.parent_signalling = child.connect('button_press_event', self.__view_button_event__)
|
|
|
|
self.attach(child, x, x+1, y, y+1)
|
|
|
|
|
2006-05-02 13:09:55 +02:00
|
|
|
# drag'n'drop
|
|
|
|
for views in self.child_views:
|
|
|
|
for view in views:
|
2006-05-22 23:43:24 +02:00
|
|
|
view.drag_dest_set(gtk.DEST_DEFAULT_ALL,
|
|
|
|
[("GTK_TREE_MODEL_ROW",gtk.TARGET_SAME_APP,7)],
|
|
|
|
gtk.gdk.ACTION_LINK)
|
2006-05-02 13:09:55 +02:00
|
|
|
view.connect("drag-data-received",self.drag_received_by_view,view)
|
|
|
|
|
|
|
|
|
|
|
|
def drag_received_by_view(self, widget, drag_context, x, y, selection, info, timestamp, view):
|
|
|
|
treestore, path = selection.tree_get_row_drag_data()
|
|
|
|
iter = treestore.get_iter(path)
|
|
|
|
obj = treestore.get_value(iter,2)
|
|
|
|
|
|
|
|
loc = self.find_child(view)
|
|
|
|
|
|
|
|
if loc and isinstance(obj, Plot) and (not self.find_child(obj)):
|
|
|
|
self.set_child(obj,loc[0],loc[1])
|
|
|
|
|
|
|
|
|
2006-04-26 14:11:23 +02:00
|
|
|
def set_view_listener(self, listener):
|
|
|
|
self._listener = listener
|
|
|
|
|
2006-05-02 14:38:00 +02:00
|
|
|
def set_child(self, child, col, row):
|
|
|
|
# urg, this probably belongs somewhere else
|
2006-05-22 23:43:24 +02:00
|
|
|
child.drag_dest_set(gtk.DEST_DEFAULT_ALL,
|
|
|
|
[("GTK_TREE_MODEL_ROW",gtk.TARGET_SAME_APP,7)],
|
|
|
|
gtk.gdk.ACTION_LINK)
|
2006-05-02 14:38:00 +02:00
|
|
|
child.connect("drag-data-received",self.drag_received_by_view,child)
|
|
|
|
|
2006-04-17 22:27:39 +02:00
|
|
|
cur_widget = self.child_views[col][row]
|
|
|
|
cur_widget.disconnect(cur_widget.parent_signalling)
|
|
|
|
self.remove(cur_widget)
|
|
|
|
self.attach(child, col, col+1, row, row+1)
|
|
|
|
child.parent_signalling = child.connect('button_press_event', self.__view_button_event__)
|
|
|
|
self.child_views[col][row] = child
|
2006-04-20 12:34:50 +02:00
|
|
|
if cur_widget.active:
|
|
|
|
child.mark_active(True)
|
|
|
|
cur_widget.mark_active(False)
|
2006-04-17 22:27:39 +02:00
|
|
|
child.show()
|
|
|
|
|
2006-04-18 00:30:53 +02:00
|
|
|
def borrow_current(self):
|
|
|
|
self.borrowed = self.child_views[self.active_x][self.active_y]
|
|
|
|
self.remove_child(self.active_x, self.active_y)
|
|
|
|
return self.borrowed
|
|
|
|
|
|
|
|
def return_current(self, view):
|
|
|
|
self.set_child(view, self.active_x, self.active_y)
|
|
|
|
|
2006-04-17 22:27:39 +02:00
|
|
|
def remove_child(self, col, row):
|
2006-04-18 00:30:53 +02:00
|
|
|
self.remove(self.child_views[col][row])
|
|
|
|
self.attach(EmptyView(), col, col+1, row, row+1)
|
2006-04-17 22:27:39 +02:00
|
|
|
|
2006-04-18 00:30:53 +02:00
|
|
|
def insert_view(self, child):
|
|
|
|
if not self.find_child(child):
|
|
|
|
self.set_child(child, self.active_x, self.active_y)
|
|
|
|
|
2006-04-17 22:27:39 +02:00
|
|
|
def show(self):
|
|
|
|
for x in self.child_views:
|
|
|
|
for y in x:
|
|
|
|
y.show()
|
|
|
|
gtk.Table.show(self)
|
|
|
|
|
|
|
|
def hide(self):
|
|
|
|
for x in self.child_views:
|
|
|
|
for y in x:
|
|
|
|
y.hide()
|
|
|
|
gtk.Table.hide(self)
|
|
|
|
|
|
|
|
def set_active(self, x, y):
|
|
|
|
old_focus = self.child_views[self.active_x][self.active_y]
|
|
|
|
new_focus = self.child_views[x][y]
|
|
|
|
old_focus.mark_active(False)
|
|
|
|
new_focus.mark_active(True)
|
|
|
|
self.active_x = x
|
|
|
|
self.active_y = y
|
2006-04-26 14:11:23 +02:00
|
|
|
if self._listener:
|
|
|
|
logger.log("debug", "emitting")
|
|
|
|
self._listener(new_focus)
|
2006-04-17 22:27:39 +02:00
|
|
|
|
|
|
|
def find_child(self, child):
|
|
|
|
for i, row in enumerate(self.child_views):
|
|
|
|
for j, v in enumerate(row):
|
|
|
|
if v == child:
|
|
|
|
return (i, j)
|
|
|
|
return None
|
|
|
|
|
|
|
|
def __view_button_event__(self, view, *rest):
|
|
|
|
loc = self.find_child(view)
|
|
|
|
if loc:
|
|
|
|
self.set_active(loc[0], loc[1])
|
|
|
|
|
2006-04-18 00:30:53 +02:00
|
|
|
def get_view(self, x, y):
|
|
|
|
return self.child_views[x][y]
|
|
|
|
|
2006-04-17 22:27:39 +02:00
|
|
|
|
|
|
|
class EmptyView (Plot):
|
2006-04-16 20:25:54 +02:00
|
|
|
def __init__(self):
|
2006-04-24 16:52:21 +02:00
|
|
|
Plot.__init__(self, 'Empty view')
|
2006-04-17 22:27:39 +02:00
|
|
|
label = gtk.Label('No view')
|
|
|
|
ebox = gtk.EventBox()
|
|
|
|
ebox.add(label)
|
|
|
|
self.add(ebox)
|
|
|
|
|
2006-05-22 23:43:24 +02:00
|
|
|
label.show()
|
|
|
|
ebox.show()
|
|
|
|
self.show()
|
2006-04-26 14:11:23 +02:00
|
|
|
|
|
|
|
|
|
|
|
class NavToolbar(NavigationToolbar2):
|
|
|
|
toolitems = (('Select', 'Select within rectangle', 'zoom_to_rect.png',
|
|
|
|
'select'),) + NavigationToolbar2.toolitems
|
|
|
|
|
|
|
|
def __init__(self, *args):
|
|
|
|
NavigationToolbar2.__init__(self, *args)
|
|
|
|
self._select_callback = None
|
|
|
|
|
|
|
|
def select(self, *args):
|
|
|
|
"""Selection mode selected handler."""
|
|
|
|
if self._active == 'SELECT':
|
|
|
|
self._active = None
|
|
|
|
else:
|
|
|
|
self._active = 'SELECT'
|
|
|
|
|
|
|
|
if self._idPress is not None:
|
|
|
|
self._idPress = self.canvas.mpl_disconnect(self._idPress)
|
|
|
|
self.mode = ''
|
|
|
|
|
|
|
|
if self._idRelease is not None:
|
|
|
|
self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
|
|
|
|
self.mode = ''
|
|
|
|
|
|
|
|
if self._active:
|
|
|
|
self._idPress = self.canvas.mpl_connect('button_press_event', self.press_select)
|
|
|
|
self._idRelease = self.canvas.mpl_connect('button_release_event', self.release_select)
|
|
|
|
self.mode = 'Select rectangle mode'
|
|
|
|
|
|
|
|
self.set_message(self.mode)
|
|
|
|
|
|
|
|
def set_message(self, s):
|
|
|
|
"""Set status in toolbar to string s.
|
|
|
|
|
|
|
|
Overrided to make sure message can be updated even when
|
|
|
|
drawing rubberband.
|
|
|
|
"""
|
|
|
|
self.message.set_label(s)
|
|
|
|
|
|
|
|
def press_select(self, event):
|
|
|
|
"""Mouse button pressed handler for selection mode."""
|
|
|
|
x, y = event.x, event.y
|
|
|
|
|
|
|
|
for i, a in enumerate(self.canvas.figure.get_axes()):
|
|
|
|
if event.inaxes==a and event.inaxes.get_navigate():
|
|
|
|
xmin, xmax = a.get_xlim()
|
|
|
|
ymin, ymax = a.get_ylim()
|
|
|
|
lim = xmin, xmax, ymin, ymax
|
|
|
|
self._xypress = x, y, a, i, lim, a.transData.deepcopy()
|
|
|
|
break
|
|
|
|
|
|
|
|
self.press(event)
|
|
|
|
|
|
|
|
def release_select(self, event):
|
|
|
|
"""Mouse button released handler for selection mode."""
|
|
|
|
# only release if button was pressed inside first?
|
|
|
|
if self._xypress:
|
|
|
|
x, y = event.x, event.y
|
|
|
|
lastx, lasty, a, ind, lim, trans = self._xypress
|
|
|
|
lastx, lasty = a.transData.inverse_xy_tup( (lastx, lasty) )
|
|
|
|
x, y = a.transData.inverse_xy_tup( (x, y) )
|
|
|
|
|
|
|
|
if self._select_callback:
|
|
|
|
self._select_callback(lastx, lasty, x, y)
|
|
|
|
|
|
|
|
self._xypress = None
|
|
|
|
self.draw()
|
|
|
|
self.release(event)
|
|
|
|
|
|
|
|
def mouse_move(self, event):
|
|
|
|
"""Extend NavigationToolbar2.mouse_move to provide selection support."""
|
|
|
|
from matplotlib.backend_bases import cursors
|
|
|
|
|
|
|
|
# Only update the rubberband for selection mode when mouse is
|
|
|
|
# within the plotting area.
|
|
|
|
if event.inaxes and self._active=='SELECT':
|
|
|
|
if self._lastCursor != cursors.SELECT_REGION:
|
|
|
|
self.set_cursor(cursors.SELECT_REGION)
|
|
|
|
self._lastCursor = cursors.SELECT_REGION
|
|
|
|
if self._xypress is not None:
|
|
|
|
x, y = event.x, event.y
|
|
|
|
lastx, lasty, a, ind, lim, trans= self._xypress
|
|
|
|
self.draw_rubberband(event, x, y, lastx, lasty)
|
|
|
|
|
|
|
|
NavigationToolbar2.mouse_move(self, event)
|
|
|
|
|
|
|
|
def set_select_callback(self, listener):
|
|
|
|
"""Allow plots to register a callback for selection events.
|
|
|
|
|
|
|
|
The callback will be called as listener(x1, y1, x2, y2). All
|
|
|
|
coordinates are in the plot coordinate system, not pixels or
|
|
|
|
widget coordinates.
|
|
|
|
"""
|
|
|
|
self._select_callback = listener
|
2006-04-17 22:27:39 +02:00
|
|
|
|
2006-04-21 16:45:01 +02:00
|
|
|
|
2006-04-20 12:27:58 +02:00
|
|
|
class SinePlot(Plot):
|
2006-04-24 16:42:45 +02:00
|
|
|
def __init__(self):
|
2006-04-24 16:52:21 +02:00
|
|
|
Plot.__init__(self, 'Sine plot')
|
|
|
|
|
2006-04-16 20:25:54 +02:00
|
|
|
fig = Figure(figsize=(5,4), dpi=72)
|
|
|
|
ax = fig.add_subplot(111)
|
|
|
|
t = arange(0.0,3.0,0.01)
|
|
|
|
s = sin(2*pi*t)
|
|
|
|
ax.plot(t,s)
|
2006-04-24 16:52:21 +02:00
|
|
|
|
2006-04-16 20:25:54 +02:00
|
|
|
self.canvas = FigureCanvas(fig)
|
2006-04-26 14:11:23 +02:00
|
|
|
self._toolbar = NavToolbar(self.canvas, None)
|
|
|
|
self._toolbar.set_property('show-arrow', False)
|
2006-04-16 20:25:54 +02:00
|
|
|
self.add(self.canvas)
|
|
|
|
self.canvas.show()
|
|
|
|
|
2006-04-26 14:11:23 +02:00
|
|
|
def get_toolbar(self):
|
|
|
|
return self._toolbar
|
|
|
|
|
2006-04-17 22:27:39 +02:00
|
|
|
|
2006-04-27 13:03:11 +02:00
|
|
|
class LinePlot(Plot):
|
|
|
|
def __init__(self, dataset, name="Line plot"):
|
|
|
|
Plot.__init__(self, name)
|
|
|
|
fig = Figure(figsize=(5,4), dpi=72)
|
|
|
|
self.canvas = FigureCanvas(fig)
|
|
|
|
|
|
|
|
self.ax = ax = fig.add_subplot(111)
|
|
|
|
self._dataset = dataset
|
|
|
|
|
|
|
|
import rpy
|
|
|
|
silent_eval = rpy.with_mode(rpy.NO_CONVERSION, rpy.r)
|
|
|
|
|
2006-05-05 16:43:53 +02:00
|
|
|
rpy.with_mode(rpy.NO_CONVERSION, rpy.r.assign)("m", dataset.asarray())
|
2006-04-27 13:03:11 +02:00
|
|
|
ymin, ymax = rpy.r("range(m)*1.1")
|
|
|
|
self._ymin, self._ymax = ymin, ymax
|
|
|
|
silent_eval("res <- apply(m, 2, density, from=%s, to=%s)" % (ymin, ymax))
|
|
|
|
silent_eval("k <- sapply(1:length(res), function(id) rev(res[[id]]$y))")
|
|
|
|
self._bg_matrix = bg_matrix = rpy.r("k")
|
|
|
|
rpy.r.rm(["k", "res", "m"])
|
2006-04-27 16:38:48 +02:00
|
|
|
|
|
|
|
# Hack - we draw plot in selection_changed()
|
|
|
|
self.selection_changed(None)
|
2006-04-27 13:03:11 +02:00
|
|
|
|
|
|
|
self.add(self.canvas)
|
|
|
|
self.canvas.show()
|
|
|
|
|
|
|
|
# We use a regular toolbar as we don't need selections
|
|
|
|
self._toolbar = NavigationToolbar2(self.canvas, None)
|
|
|
|
self._toolbar.set_property('show-arrow', False)
|
|
|
|
|
|
|
|
def get_toolbar(self):
|
|
|
|
self.canvas.draw()
|
|
|
|
return self._toolbar
|
|
|
|
|
2006-04-27 16:38:48 +02:00
|
|
|
def selection_changed(self, selection):
|
2006-04-27 13:03:11 +02:00
|
|
|
self.ax.clear()
|
|
|
|
|
|
|
|
rows, cols = self._bg_matrix.shape
|
2006-04-27 14:05:20 +02:00
|
|
|
self.ax.imshow(self._bg_matrix, cmap=cm.Greys, extent=(0.5, cols+0.5, self._ymin, self._ymax))
|
2006-04-27 13:03:11 +02:00
|
|
|
|
2006-04-28 13:44:55 +02:00
|
|
|
dim_2, dim_1 = self._dataset.get_dim_names()
|
|
|
|
|
2006-04-27 16:38:48 +02:00
|
|
|
if selection:
|
2006-04-28 13:44:55 +02:00
|
|
|
ids = selection[dim_2] # current identifiers
|
|
|
|
index = [ind for id,ind in self._dataset[dim_2].items() if id in ids] #conversion to index
|
2006-04-27 13:03:11 +02:00
|
|
|
for i in index:
|
2006-05-05 16:43:53 +02:00
|
|
|
line = self._dataset.asarray()[i]
|
2006-04-27 13:03:11 +02:00
|
|
|
self.ax.plot(range(1, len(line)+1), line)
|
|
|
|
|
|
|
|
self.ax.set_xlim((0.5, cols+0.5))
|
|
|
|
self.ax.set_ylim((self._ymin, self._ymax))
|
|
|
|
self.canvas.draw()
|
|
|
|
|
|
|
|
|
2006-04-20 12:27:58 +02:00
|
|
|
class ScatterPlot(Plot):
|
2006-05-09 15:17:17 +02:00
|
|
|
def __init__(self, dataset_1, dataset_2, id_dim, sel_dim, id_1, id_2, name="Scatter plot"):
|
2006-04-27 13:38:40 +02:00
|
|
|
Plot.__init__(self, name)
|
2006-04-16 20:25:54 +02:00
|
|
|
fig = Figure(figsize=(5,4), dpi=72)
|
2006-04-18 11:19:59 +02:00
|
|
|
self.ax = ax = fig.add_subplot(111)
|
2006-04-24 11:53:07 +02:00
|
|
|
self.current_dim = id_dim
|
2006-04-19 20:25:44 +02:00
|
|
|
# testing testing
|
2006-05-09 15:17:17 +02:00
|
|
|
self.dataset_1 = dataset_1
|
2006-04-24 11:53:07 +02:00
|
|
|
|
2006-05-09 15:17:17 +02:00
|
|
|
x_index = dataset_1[sel_dim][id_1]
|
|
|
|
y_index = dataset_2[sel_dim][id_2]
|
|
|
|
|
|
|
|
self.xaxis_data = dataset_1._array[:,x_index]
|
|
|
|
self.yaxis_data = dataset_2._array[:,y_index]
|
2006-04-24 11:53:07 +02:00
|
|
|
ax.plot(self.xaxis_data,self.yaxis_data,'og')
|
2006-04-27 13:38:40 +02:00
|
|
|
ax.set_title(self.get_title())
|
|
|
|
ax.set_xlabel("%s - %s" % (sel_dim, id_1))
|
|
|
|
ax.set_ylabel("%s - %s" % (sel_dim, id_2))
|
2006-04-26 14:11:23 +02:00
|
|
|
|
2006-04-19 20:25:44 +02:00
|
|
|
###
|
|
|
|
|
2006-04-16 20:25:54 +02:00
|
|
|
self.canvas = FigureCanvas(fig)
|
|
|
|
self.add(self.canvas)
|
|
|
|
self.canvas.show()
|
|
|
|
|
2006-04-26 14:11:23 +02:00
|
|
|
self._toolbar = NavToolbar(self.canvas, None)
|
|
|
|
self._toolbar.set_property('show-arrow', False)
|
|
|
|
self._toolbar.set_select_callback(self.rectangle_select_callback)
|
|
|
|
|
|
|
|
def get_toolbar(self):
|
|
|
|
return self._toolbar
|
|
|
|
|
|
|
|
def rectangle_select_callback(self, x1, y1, x2, y2):
|
2006-04-19 12:37:44 +02:00
|
|
|
ydata = self.yaxis_data
|
|
|
|
xdata = self.xaxis_data
|
2006-04-25 12:08:12 +02:00
|
|
|
|
|
|
|
# find indices of selected area
|
2006-04-19 12:37:44 +02:00
|
|
|
if x1>x2:
|
|
|
|
if y1<y2:
|
|
|
|
index =scipy.nonzero((xdata<x1) & (xdata>x2) & (ydata>y1) & (ydata<y2))
|
|
|
|
else:
|
|
|
|
index =scipy.nonzero((xdata<x1) & (xdata>x2) & (ydata<y1) & (ydata>y2))
|
|
|
|
else:
|
2006-04-24 11:53:07 +02:00
|
|
|
#logger.log('debug','Selection x_start less than x_end')
|
2006-04-19 12:37:44 +02:00
|
|
|
if y1<y2:
|
2006-04-24 11:53:07 +02:00
|
|
|
#logger.log('debug','Selection y_start less than y_end')
|
2006-04-19 20:25:44 +02:00
|
|
|
index =scipy.nonzero((xdata>x1) & (xdata<x2) & (ydata>y1) & (ydata<y2))
|
2006-04-19 12:37:44 +02:00
|
|
|
else:
|
2006-04-24 11:53:07 +02:00
|
|
|
#logger.log('debug','Selection y_start bigger than y_end')
|
2006-04-19 20:25:44 +02:00
|
|
|
index =scipy.nonzero((xdata>x1) & (xdata<x2) & (ydata<y1) & (ydata>y2))
|
|
|
|
|
2006-05-09 15:17:17 +02:00
|
|
|
ids = self.dataset_1.get_identifiers(self.current_dim, index)
|
2006-05-03 13:40:12 +02:00
|
|
|
self.selection_listener(self.current_dim, ids)
|
2006-04-19 20:25:44 +02:00
|
|
|
|
2006-04-27 16:38:48 +02:00
|
|
|
def selection_changed(self, selection):
|
|
|
|
ids = selection[self.current_dim] # current identifiers
|
2006-04-24 11:53:07 +02:00
|
|
|
|
2006-05-09 15:17:17 +02:00
|
|
|
index = self.dataset_1.get_indices(self.current_dim, ids)
|
2006-04-19 20:50:10 +02:00
|
|
|
xdata_new = scipy.take(self.xaxis_data,index) #take data
|
2006-04-19 20:25:44 +02:00
|
|
|
ydata_new = scipy.take(self.yaxis_data,index)
|
2006-04-24 16:25:24 +02:00
|
|
|
self.ax.clear()
|
2006-04-24 11:53:07 +02:00
|
|
|
self.ax.plot(self.xaxis_data,self.yaxis_data,'og')
|
2006-04-19 20:25:44 +02:00
|
|
|
self.ax.plot(xdata_new,ydata_new,'or')
|
|
|
|
self.canvas.draw()
|
2006-04-26 14:11:23 +02:00
|
|
|
|