Projects/laydi
Projects
/
laydi
Archived
7
0
Fork 0

Toolbar update

This commit is contained in:
Arnar Flatberg 2006-10-09 18:04:39 +00:00
parent 9bfe4a30df
commit e6bf49c34b
1 changed files with 341 additions and 163 deletions

View File

@ -1,11 +1,15 @@
import os,sys import os,sys
from itertools import izip
import pygtk import pygtk
import gobject import gobject
import gtk import gtk
import fluents
from system import logger
import matplotlib import matplotlib
import scipy
from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas
from matplotlib.backends.backend_gtkagg import NavigationToolbar2GTK as NavigationToolbar2 from matplotlib.backend_bases import NavigationToolbar2,cursors
from matplotlib.backends.backend_gtk import FileChooserDialog,cursord
from matplotlib.widgets import SubplotTool,RectangleSelector
from matplotlib.axes import Subplot from matplotlib.axes import Subplot
from matplotlib.figure import Figure from matplotlib.figure import Figure
from matplotlib import cm,cbook from matplotlib import cm,cbook
@ -13,9 +17,10 @@ from pylab import Polygon
from matplotlib.collections import LineCollection from matplotlib.collections import LineCollection
from matplotlib.mlab import prctile from matplotlib.mlab import prctile
import networkx import networkx
from system import logger import scipy
from itertools import izip
# global active mode. Used by toolbars to communicate correct mode
active_mode = 'DEFAULT'
class ObjectTable: class ObjectTable:
"""A 2D table of elements.""" """A 2D table of elements."""
@ -151,7 +156,7 @@ class ViewFrame (gtk.Frame):
selection, info, timestamp): selection, info, timestamp):
treestore, path = selection.tree_get_row_drag_data() treestore, path = selection.tree_get_row_drag_data()
iter = treestore.get_iter(path) iter = treestore.get_iter(path)
obj = treestore.get_value(iter,2) obj = treestore.get_value(iter, 2)
if isinstance(obj, Plot): if isinstance(obj, Plot):
self.set_view(obj) self.set_view(obj)
@ -243,16 +248,15 @@ class MainView (gtk.Notebook):
class Plot (gtk.Frame): class Plot (gtk.Frame):
def __init__(self, title): def __init__(self, title):
gtk.Frame.__init__(self) gtk.Frame.__init__(self)
self.sel_obj = None
self.title = title self.title = title
self.sel_obj = None
self.selection_listener = None self.selection_listener = None
self.fig = Figure()
self.canvas = FigureCanvas(self.fig)
self.set_shadow_type(gtk.SHADOW_NONE) self.set_shadow_type(gtk.SHADOW_NONE)
self._background = None self._background = None
self.canvas = None
self.fig = Figure(figsize=(5,4), dpi=72)
self.canvas = FigureCanvas(self.fig)
self.fig.set_facecolor('white')
self._sel_sensitive = True self._sel_sensitive = True
self.canvas.add_events(gtk.gdk.ENTER_NOTIFY_MASK)
def set_selection_sensitive(self,event): def set_selection_sensitive(self,event):
if event: if event:
@ -263,6 +267,7 @@ class Plot (gtk.Frame):
logger.log('debug','Selections active') logger.log('debug','Selections active')
self._sel_sensitive = True self._sel_sensitive = True
def get_title(self): def get_title(self):
return self.title return self.title
@ -282,7 +287,7 @@ class Plot (gtk.Frame):
def get_toolbar(self): def get_toolbar(self):
return None return None
class EmptyView (Plot): class EmptyView (Plot):
def __init__(self): def __init__(self):
@ -291,124 +296,10 @@ class EmptyView (Plot):
ebox = gtk.EventBox() ebox = gtk.EventBox()
ebox.add(label) ebox.add(label)
self.add(ebox) self.add(ebox)
label.show() label.show()
ebox.show() ebox.show()
self.show() self.show()
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
self.message.hide()
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.push_current()
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
class PlotToolbar(NavToolbar):
"""Extensions to existing toolbar
"""
def __init__(self, *args):
NavToolbar.__init__(self, *args)
self.tb_freeze = gtk.ToolItem()
self.chk = gtk.CheckButton ()
self.chk.set_label ('Freeze')
self.tb_freeze.add (self.chk)
self.tb_freeze.set_tooltip(self.tooltips, 'Freeze current selection')
self.insert(self.tb_freeze,-1)
toolitem = gtk.SeparatorToolItem()
self.insert(toolitem, -1)
self.show_all()
self.message.hide()
class LineViewPlot(Plot): class LineViewPlot(Plot):
"""Line view of current selection, no interaction """Line view of current selection, no interaction
Only works on 2d-arrays Only works on 2d-arrays
@ -417,7 +308,7 @@ class LineViewPlot(Plot):
-- minor_axis : needs definition only for higher order arrays -- minor_axis : needs definition only for higher order arrays
ps: slow (cant get linecollection and blit to work) ps: slow (cant get linecollection and blit to work)
""" """
def __init__(self, dataset,major_axis=1,minor_axis=None, name="Line view"): def __init__(self, dataset, major_axis=1, minor_axis=None, name="Line view"):
self.use_blit = False self.use_blit = False
self._last_index = [] self._last_index = []
self._data = dataset.asarray() self._data = dataset.asarray()
@ -433,7 +324,7 @@ class LineViewPlot(Plot):
x_axis = scipy.arange(self._data.shape[minor_axis]) x_axis = scipy.arange(self._data.shape[minor_axis])
self.line_segs=[] self.line_segs=[]
for xi in range(self._data.shape[major_axis]): for xi in range(self._data.shape[major_axis]):
yi = self._data.take([xi],major_axis) yi = self._data.take([xi], major_axis)
self.line_segs.append([(xx,yy) for xx,yy in izip(x_axis,yi)]) self.line_segs.append([(xx,yy) for xx,yy in izip(x_axis,yi)])
#background #background
@ -443,41 +334,40 @@ class LineViewPlot(Plot):
verts_2 = [] # 75,25 verts_2 = [] # 75,25
med = [] med = []
for i in xax: for i in xax:
pp = prctile(self._data[i,:],[0.,5.,25,50.,75.,95.,100]) pp = prctile(self._data[i,:], [0.,5.,25,50.,75.,95.,100])
verts_0.append((i,pp[0])) verts_0.append((i,pp[0]))
verts_1.append((i,pp[1])) verts_1.append((i,pp[1]))
verts_2.append((i,pp[2])) verts_2.append((i,pp[2]))
for i in xax[::-1]: for i in xax[::-1]:
pp = prctile(self._data[i,:],[0.,5.,25,50.,75.,95.,100]) pp = prctile(self._data[i,:], [0.,5.,25,50.,75.,95.,100])
verts_0.append((i,pp[-1])) verts_0.append((i, pp[-1]))
verts_1.append((i,pp[-2])) verts_1.append((i, pp[-2]))
verts_2.append((i,pp[-3])) verts_2.append((i, pp[-3]))
med.append(pp[3]) med.append(pp[3])
bck0 = Polygon(verts_0,alpha=.15,lw=0) bck0 = Polygon(verts_0, alpha=.15, lw=0)
bck1 = Polygon(verts_1,alpha=.15,lw=0) bck1 = Polygon(verts_1, alpha=.15, lw=0)
bck2 = Polygon(verts_2,alpha=.15,lw=0) bck2 = Polygon(verts_2, alpha=.15, lw=0)
self.ax.add_patch(bck0) self.ax.add_patch(bck0)
self.ax.add_patch(bck1) self.ax.add_patch(bck1)
self.ax.add_patch(bck2) self.ax.add_patch(bck2)
self.ax.plot(xax,med,'b') self.ax.plot(xax,med, 'b')
self.ax.autoscale_view() self.ax.autoscale_view()
self.add(self.canvas) self.add(self.canvas)
self.canvas.show() self.canvas.show()
#FIXME: Lineview plot cannot do selections -> disable in toolbar #FIXME: Lineview plot cannot do selections -> disable in toolbar
self._toolbar = PlotToolbar(self.canvas, None) self._toolbar = PlotToolbar(self.canvas,self)
self._toolbar.set_property('show-arrow', False) self._toolbar.chk.connect ('toggled' , self.set_selection_sensitive)
self._toolbar.chk.connect ('toggled' ,self.set_selection_sensitive) self.canvas.mpl_connect('resize_event', self.clear_background)
self.canvas.mpl_connect('resize_event',self.clear_background)
def get_toolbar(self): def get_toolbar(self):
return self._toolbar return self._toolbar
def clear_background(self,event): def clear_background(self, event):
self._background = None self._background = None
def set_current_selection(self, selection): def set_current_selection(self, selection):
@ -493,7 +383,7 @@ class LineViewPlot(Plot):
if len(self.ax.collections)>0: if len(self.ax.collections)>0:
self.ax.collections = [] self.ax.collections = []
segs = [self.line_segs[i] for i in index] segs = [self.line_segs[i] for i in index]
line_coll = LineCollection(segs,colors=(1,0,0,1)) line_coll = LineCollection(segs, colors=(1,0,0,1))
line_coll.set_clip_box(self.ax.bbox) line_coll.set_clip_box(self.ax.bbox)
self.ax.update_datalim(line_coll.get_verts(self.ax.transData)) self.ax.update_datalim(line_coll.get_verts(self.ax.transData))
self._toolbar.forward() self._toolbar.forward()
@ -521,24 +411,24 @@ has no color and size options."""
self.use_blit = False self.use_blit = False
self._background = None self._background = None
self.ax = self.fig.add_subplot(111) self.ax = self.fig.add_subplot(111)
self.ax.axhline(0,color='k',lw=1.,zorder=1) self.ax.axhline(0, color='k', lw=1., zorder=1)
self.ax.axvline(0,color='k',lw=1.,zorder=1) self.ax.axvline(0, color='k', lw=1., zorder=1)
self.current_dim = id_dim self.current_dim = id_dim
self.dataset_1 = dataset_1 self.dataset_1 = dataset_1
self.ms = s self.ms = s
self._selection_line = None self._selection_line = None
x_index = dataset_1[sel_dim][id_1] x_index = dataset_1[sel_dim][id_1]
y_index = dataset_2[sel_dim][id_2] y_index = dataset_2[sel_dim][id_2]
self.xaxis_data = dataset_1._array[:,x_index] self.xaxis_data = dataset_1._array[:, x_index]
self.yaxis_data = dataset_2._array[:,y_index] self.yaxis_data = dataset_2._array[:, y_index]
self.ax.plot(self.xaxis_data,self.yaxis_data,'o',markeredgewidth=0,markersize=s) self.ax.plot(self.xaxis_data, self.yaxis_data, 'o', markeredgewidth=0, markersize=s)
self.ax.set_title(self.get_title()) self.ax.set_title(self.get_title())
self.add(self.canvas) self.add(self.canvas)
self.canvas.show() self.canvas.show()
# add toolbar # add toolbar
self._toolbar = PlotToolbar(self.canvas, None) self._toolbar = PlotToolbar(self.canvas, self)
self._toolbar.chk.connect ('toggled' ,self.set_selection_sensitive) self._toolbar.chk.connect ('toggled', self.set_selection_sensitive)
self._toolbar.set_property('show-arrow', False) self._toolbar.set_property('show-arrow', False)
self._toolbar.set_select_callback(self.rectangle_select_callback) self._toolbar.set_select_callback(self.rectangle_select_callback)
@ -575,7 +465,7 @@ has no color and size options."""
if self._selection_line: if self._selection_line:
self.ax.lines.remove(self._selection_line) self.ax.lines.remove(self._selection_line)
self._selection_line, = self.ax.plot(xdata_new,ydata_new,marker='o',markersize=self.ms,linestyle=None,markerfacecolor='r') self._selection_line, = self.ax.plot(xdata_new, ydata_new,marker='o', markersize=self.ms, linestyle=None, markerfacecolor='r')
self._toolbar.forward() #update data lims before draw self._toolbar.forward() #update data lims before draw
if self.use_blit: if self.use_blit:
@ -598,14 +488,14 @@ class ScatterPlot(Plot):
y_index = dataset_2[sel_dim_2][id_2] y_index = dataset_2[sel_dim_2][id_2]
else: else:
y_index = dataset_2[sel_dim][id_2] y_index = dataset_2[sel_dim][id_2]
self.xaxis_data = dataset_1._array[:,x_index] self.xaxis_data = dataset_1._array[:, x_index]
self.yaxis_data = dataset_2._array[:,y_index] self.yaxis_data = dataset_2._array[:, y_index]
lw = scipy.zeros(self.xaxis_data.shape) lw = scipy.zeros(self.xaxis_data.shape)
sc = self.ax.scatter(self.xaxis_data,self.yaxis_data,s=s,c=c,linewidth=lw,edgecolor='k',alpha=.6,cmap = cm.jet) sc = self.ax.scatter(self.xaxis_data, self.yaxis_data, s=s, c=c, linewidth=lw, edgecolor='k', alpha=.6, cmap = cm.jet)
if len(c)>1: if len(c)>1:
self.fig.colorbar(sc,ticks=[],fraction=.05) self.fig.colorbar(sc,ticks=[], fraction=.05)
self.ax.axhline(0,color='k',lw=1.,zorder=1) self.ax.axhline(0, color='k', lw=1., zorder=1)
self.ax.axvline(0,color='k',lw=1.,zorder=1) self.ax.axvline(0, color='k', lw=1., zorder=1)
self.ax.set_title(self.get_title()) self.ax.set_title(self.get_title())
# collection # collection
self.coll = self.ax.collections[0] self.coll = self.ax.collections[0]
@ -615,8 +505,8 @@ class ScatterPlot(Plot):
self.canvas.show() self.canvas.show()
# create toolbar # create toolbar
self._toolbar = PlotToolbar(self.canvas, None) self._toolbar = PlotToolbar(self.canvas, self)
self._toolbar.chk.connect ('toggled' ,self.set_selection_sensitive) self._toolbar.chk.connect ('toggled' , self.set_selection_sensitive)
self._toolbar.set_property('show-arrow', False) self._toolbar.set_property('show-arrow', False)
self._toolbar.set_select_callback(self.rectangle_select_callback) self._toolbar.set_select_callback(self.rectangle_select_callback)
@ -715,8 +605,8 @@ class NetworkPlot(Plot):
networkx.draw_networkx(self.graph, ax=self.ax, **kw) networkx.draw_networkx(self.graph, ax=self.ax, **kw)
# Setup toolbar # Setup toolbar
self._toolbar = PlotToolbar(self.canvas, None) self._toolbar = PlotToolbar(self.canvas, self)
self._toolbar.chk.connect ('toggled' ,self.set_selection_sensitive) self._toolbar.chk.connect ('toggled' , self.set_selection_sensitive)
self._toolbar.set_property('show-arrow', False) self._toolbar.set_property('show-arrow', False)
self._toolbar.set_select_callback(self.rectangle_select_callback) self._toolbar.set_select_callback(self.rectangle_select_callback)
@ -726,8 +616,8 @@ class NetworkPlot(Plot):
def rectangle_select_callback(self, x1, y1, x2, y2): def rectangle_select_callback(self, x1, y1, x2, y2):
'event1 and event2 are the press and release events' 'event1 and event2 are the press and release events'
pos = self.keywords['pos'] pos = self.keywords['pos']
ydata = scipy.zeros((len(pos),),'l') ydata = scipy.zeros((len(pos),), 'l')
xdata = scipy.zeros((len(pos),),'l') xdata = scipy.zeros((len(pos),), 'l')
node_ids = [] node_ids = []
c = 0 c = 0
for name,(x,y) in pos.items(): for name,(x,y) in pos.items():
@ -778,6 +668,294 @@ class NetworkPlot(Plot):
self.canvas.draw() self.canvas.draw()
class PlotToolbar(NavigationToolbar2,gtk.Toolbar):
# list of toolitems to add to the toolbar, format is:
# text, tooltip_text, image_file, callback(str)
toolitems = (
('Home', 'Reset original view', 'home.png', 'home'),
#('Back', 'Back to previous view','back.png', 'back'),
#('Forward', 'Forward to next view','forward.png', 'forward'),
#('Subplots', 'Configure subplots','subplots.png', 'configure_subplots'),
('Save', 'Save the figure','filesave.png', 'save_figure'),
)
radiobuttons = (
('DEFAULT', 'Default mode', 'cursor.png', 'default'),
('PAN', 'Pan axes with left mouse, zoom with right', 'move.png', 'pan'),
('ZOOM', 'Zoom to rectangle','zoom_to_rect.png', 'zoom'),
('SELECT', 'Select within rectangle', 'select.png', 'select'),
)
def __init__(self, canvas, plot):
self.win = None
gtk.Toolbar.__init__(self)
NavigationToolbar2.__init__(self, canvas)
self._idleId = 0
self._select_callback = None
canvas.connect('enter-notify-event', self.on_enter_notify)
def _init_toolbar(self):
self.set_style(gtk.TOOLBAR_ICONS)
self.tooltips = gtk.Tooltips()
self._states = {}
self._selector = None
self.set_property('show-arrow', False)
basedir = fluents.ICONDIR
# setup base buttons
for text, tooltip_text, image_file, callback in self.toolitems:
if text is None:
self.insert(gtk.SeparatorToolItem(), -1 )
continue
fname = os.path.join(basedir, image_file)
image = gtk.Image()
image.set_from_file(fname)
tbutton = gtk.ToolButton(image, text)
self.insert(tbutton, -1)
tbutton.connect('clicked', getattr(self, callback))
tbutton.set_tooltip(self.tooltips, tooltip_text, 'Private')
self.insert(gtk.SeparatorToolItem(), -1)
# mode/state buttons
rbutton = None
for text,tooltip_text,image_file,callback in self.radiobuttons:
if text is None:
self.insert(gtk.SeparatorToolItem(), -1 )
continue
fname = os.path.join(basedir, image_file)
image = gtk.Image()
image.set_from_file(fname)
rbutton = gtk.RadioToolButton(rbutton)
rbutton.set_icon_widget(image)
rbutton.connect('toggled', getattr(self, callback))
rbutton.set_tooltip(self.tooltips, tooltip_text, 'Private')
self._states[text] = rbutton
self.insert(rbutton, -1)
self.insert(gtk.SeparatorToolItem(), -1)
toolitem = gtk.ToolItem()
self.insert(toolitem, -1)
self.message = gtk.Label()
toolitem.add(self.message)
self.tb_freeze = gtk.ToolItem()
self.chk = gtk.CheckButton ()
self.chk.set_label ('Freeze')
self.tb_freeze.add (self.chk)
self.tb_freeze.set_tooltip(self.tooltips, 'Freeze current selection')
self.insert(self.tb_freeze,-1)
toolitem = gtk.SeparatorToolItem()
self.insert(toolitem, -1)
self.show_all()
self.fileselect = FileChooserDialog(title='Save the figure', parent=self.win,)
def on_enter_notify(self, widget, event):
if self._active != active_mode:
self.set_mode(active_mode)
def set_mode(self, active):
# if state is unkown or not set, set to default
if active == None or active not in self._states.keys():
active = 'DEFAULT'
# remove current Selector:
if self._selector:
print "Removing selector"
self._selector = None
# remove current button bindings
if self._idPress != None:
self._idPress = self.canvas.mpl_disconnect(self._idPress)
self.mode = ''
if self._idRelease != None:
self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
self.mode = ''
for state, button in self._states.items():
if state != active:
continue
if state == 'SELECT':
ax, = self.canvas.figure.get_axes()
props = dict(facecolor='blue', edgecolor = 'black',
alpha=0.3, fill=True)
self._selector = RectangleSelector(ax, self.onselect,
drawtype='box', useblit=True,
rectprops=props)
self.mode = 'Select rectangle mode'
print self.mode
elif state == 'PAN':
self._idPress = self.canvas.mpl_connect(
'button_press_event', self.press_pan)
self._idRelease = self.canvas.mpl_connect(
'button_release_event', self.release_pan)
self.mode = 'pan/zoom mode'
elif state == 'ZOOM':
self._idPress = self.canvas.mpl_connect('button_press_event', self.press_zoom)
self._idRelease = self.canvas.mpl_connect('button_release_event', self.release_zoom)
self.mode = 'Zoom to rect mode'
elif state == 'DEFAULT':
pass
else:
pass
if not button.get_active():
button.set_active(True)
for a in self.canvas.figure.get_axes():
a.set_navigate_mode(self._active)
self.set_message(self.mode)
self._active = active
# update global active_mode (for all toolbar)
globals()['active_mode'] = active
def get_mode(self):
if self._active == None:
return 'DEFAULT'
return self._active
def default(self, button):
"""Activates default mode"""
if not button.get_active():
return
self.set_mode('DEFAULT')
def select(self, button):
"""Activate select mode"""
if not button.get_active():
return
self.set_mode('SELECT')
def onselect(self,eclick, erelease):
'eclick and erelease are matplotlib events at press and release'
if self._select_callback:
self._select_callback(eclick.xdata, eclick.ydata, erelease.xdata, erelease.ydata)
def pan(self, button):
"""Activate the pan/zoom tool. pan with left button, zoom with right"""
if not button.get_active():
return
self.set_mode('PAN')
def zoom(self, button):
"""Activate zoom to rect mode"""
if not button.get_active():
return
self.set_mode('ZOOM')
def mouse_move(self, event):
"""Extend NavigationToolbar2.mouse_move to provide selection support."""
# 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
def set_cursor(self, cursor):
self.canvas.window.set_cursor(cursord[cursor])
def dynamic_update(self):
# legacy method; new method is canvas.draw_idle
self.canvas.draw_idle()
def mpl_draw_rubberband(self,event):
"""Use RectangleSelector for rubberband drawing"""
def draw_rubberband(self, event, x0, y0, x1, y1):
'adapted from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/189744'
drawable = self.canvas.window
if drawable is None:
return
gc = drawable.new_gc()
height = self.canvas.figure.bbox.height()
y1 = height - y1
y0 = height - y0
w = abs(x1 - x0)
h = abs(y1 - y0)
rect = [int(val)for val in min(x0,x1), min(y0, y1), w, h]
try: lastrect, imageBack = self._imageBack
except AttributeError:
#snap image back
if event.inaxes is None:
return
ax = event.inaxes
l,b,w,h = [int(val) for val in ax.bbox.get_bounds()]
b = int(height)-(b+h)
axrect = l,b,w,h
self._imageBack = axrect, drawable.get_image(*axrect)
drawable.draw_rectangle(gc, False, *rect)
self._idleId = 0
else:
def idle_draw(*args):
drawable.draw_image(gc, imageBack, 0, 0, *lastrect)
drawable.draw_rectangle(gc, False, *rect)
self._idleId = 0
return False
if self._idleId == 0:
self._idleId = gobject.idle_add(idle_draw)
def save_figure(self, button):
fname = self.fileselect.get_filename_from_user()
if fname:
self.canvas.print_figure(fname)
def configure_subplots(self, button):
toolfig = Figure(figsize=(6,3))
canvas = self._get_canvas(toolfig)
toolfig.subplots_adjust(top=0.9)
tool = SubplotTool(self.canvas.figure, toolfig)
w = int (toolfig.bbox.width())
h = int (toolfig.bbox.height())
window = gtk.Window()
window.set_title("Subplot Configuration Tool")
window.set_default_size(w, h)
vbox = gtk.VBox()
window.add(vbox)
vbox.show()
canvas.show()
vbox.pack_start(canvas, True, True)
window.show()
def _get_canvas(self, fig):
return FigureCanvas(fig)
# Create a view-changed signal that should be emitted every time # Create a view-changed signal that should be emitted every time
# the active view changes. # the active view changes.
gobject.signal_new('view-changed', MainView, gobject.SIGNAL_RUN_LAST, gobject.signal_new('view-changed', MainView, gobject.SIGNAL_RUN_LAST,