Skip to content

Commit

Permalink
handwrote rectangle selector so it looked prettier
Browse files Browse the repository at this point in the history
  • Loading branch information
westphallm1 committed Apr 16, 2018
1 parent dc39a40 commit 06413a8
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 25 deletions.
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include specdal/gui/*.png
2 changes: 2 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
packages=['specdal', 'specdal.gui','specdal.readers','specdal.containers',
'specdal.operators','specdal.filters'],
install_requires=['numpy', 'pandas', 'matplotlib', 'scipy'],
package_data = {'':['specdal/gui/select.png']},
include_package_data = True,
zip_safe=False,
classifiers=[
'Development Status :: 3 - Alpha',
Expand Down
Binary file added specdal/gui/select.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
118 changes: 93 additions & 25 deletions specdal/gui/viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.backends.backend_tkagg import NavigationToolbar2TkAgg
from matplotlib.figure import Figure
from matplotlib.widgets import RectangleSelector
from matplotlib.patches import Rectangle
import matplotlib
sys.path.insert(0, os.path.abspath("../.."))
from specdal.containers.spectrum import Spectrum
Expand All @@ -30,7 +30,8 @@ def __init__(self, parent, collection=None, with_toolbar=True):
self.ax = self.fig.add_subplot(111)
self.canvas = FigureCanvasTkAgg(self.fig, master=self)
self.setupMouseNavigation()
NavigationToolbar2TkAgg(self.canvas, self) # for matplotlib features
self.navbar = NavigationToolbar2TkAgg(self.canvas, self) # for matplotlib features
self.setupNavBarExtras(self.navbar)
self.canvas.get_tk_widget().pack(side=tk.LEFT, fill=tk.BOTH,expand=1)
# spectra list
self.create_listbox()
Expand All @@ -56,30 +57,94 @@ def __init__(self, parent, collection=None, with_toolbar=True):
self.last_draw = datetime.now()


def setupNavBarExtras(self,navbar):
working_dir = os.path.dirname(os.path.abspath(__file__))
self.select_icon = tk.PhotoImage(file=os.path.join(working_dir,"select.png"))

self.select_button = tk.Button(navbar,width="24",height="24",
image=self.select_icon, command = lambda:self.ax.set_navigate_mode(None)).pack(side=tk.LEFT,anchor=tk.W)



def rectangleStartEvent(self,event):
self._rect = None
self._rect_start = event

def rectangleMoveEvent(self,event):
try:
dx = event.xdata - self._rect_start.xdata
dy = event.ydata - self._rect_start.ydata
except TypeError:
#we're out of canvas bounds
return

if self._rect is not None:
self._rect.remove()

self._rect = Rectangle((self._rect_start.xdata,self._rect_start.ydata),
dx,dy, color='k',ls='--',lw=1,fill=False)
self.ax.add_patch(self._rect)
self.ax.draw_artist(self._rect)

def rectangleEndEvent(self,event):
if self._rect is not None:
self._rect.remove()

if not self.collection is None:
x_data = self.collection.data.loc[self._rect_start.xdata:event.xdata]
ylim = sorted([self._rect_start.ydata,event.ydata])
is_in_box = ((x_data > ylim[0]) & (x_data < ylim[1])).any()

highlighted = is_in_box.index[is_in_box].tolist()
key_list = list(self.collection._spectra.keys())

self.update_selected(highlighted)
for highlight in highlighted:
#O(n^2) woof
pos = key_list.index(highlight)
self.listbox.selection_set(pos)


def setupMouseNavigation(self):
def onRectangleDraw(eclick,erelease):
print("This is a rectangle event!")
print(eclick.xdata,erelease.xdata)
if not self.collection is None:
x_data = self.collection.data.loc[eclick.xdata:erelease.xdata]
ylim = sorted([eclick.ydata,erelease.ydata])
is_in_box = ((x_data > ylim[0]) & (x_data < ylim[1])).any()
#TODO: Pandas builtin
highlighted = is_in_box.index[is_in_box].tolist()
print(highlighted)
key_list = list(self.collection._spectra.keys())

self.update_selected(highlighted)
for highlight in highlighted:
#O(n^2) woof
pos = key_list.index(highlight)
self.listbox.selection_set(pos)

self.rs = RectangleSelector(self.ax, onRectangleDraw, drawtype='none',
useblit=False, button=[1],spancoords='pixels',
interactive=False)
self.clicked = False
self.select_mode = 'rectangle'
self._bg_cache = None

START_EVENTS = {
'rectangle':self.rectangleStartEvent
}

MOVE_EVENTS = {
'rectangle':self.rectangleMoveEvent
}

END_EVENTS = {
'rectangle':self.rectangleEndEvent
}

def onMouseDown(event):
if self.ax.get_navigate_mode() is None:
self._bg_cache = self.canvas.copy_from_bbox(self.ax.bbox)
self.clicked = True
START_EVENTS[self.select_mode](event)

def onMouseUp(event):
self.canvas.restore_region(self._bg_cache)
self.canvas.blit(self.ax.bbox)
self.clicked = False
END_EVENTS[self.select_mode](event)

def onMouseMove(event):
if(self.clicked):
self.canvas.restore_region(self._bg_cache)
MOVE_EVENTS[self.select_mode](event)
self.canvas.blit(self.ax.bbox)

self.canvas.mpl_connect('button_press_event',onMouseDown)
self.canvas.mpl_connect('button_release_event',onMouseUp)
self.canvas.mpl_connect('motion_notify_event',onMouseMove)



@property
def head(self):
Expand Down Expand Up @@ -390,10 +455,13 @@ def update(self):

# reapply limits
# legend
self.ax.legend().remove()
if self.spectrum_mode:
self.ax.legend()
#self.ax.legend()
pass
else:
self.ax.legend().remove()
#self.ax.legend().remove()
pass
self.ax.set_ylabel(self.collection.measure_type)
#toggle appearance of statistics
if self.mean_line != None: self.mean_line.set_visible(self.mean)
Expand Down

0 comments on commit 06413a8

Please sign in to comment.