我正在尝试向图中添加两个矩形选择器(docs):
当前,我在按下键盘按键时创建Area
和Background
类(均包含矩形选择器)。按下另一个键后,我又创建了两个类,分别从Area
和Background
类中获取属性。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import RectangleSelector
class AreaSelector():
""" lets the user select an area"""
def __init__(self, fig, ax, im):
self.x1 = None
self.y1 = None
self.x2 = None
self.y2 = None
self.observers = []
toggle_selector.RS = RectangleSelector(ax, self.line_select_callback,
drawtype='box', useblit=True,
button=[1], # don't use middle button
minspanx=1, minspany=1,
spancoords='pixels',
interactive=True,
rectprops=dict(facecolor='green',edgecolor='black', alpha=0.3))
def line_select_callback(self, eclick, erelease):
""" gets the positions and sends them to the observer"""
'eclick and erelease are the press and release events'
self.x1, self.y1 = eclick.xdata, eclick.ydata
self.x2, self.y2 = erelease.xdata, erelease.ydata
self.set_new_position(self.x1, self.y1, self.x2, self.y2)
def set_new_position(self, x1, y1, x2, y2):
""" informs the observer about the new positions"""
self.x1 = x1
self.y1 = y1
self.x2 = x2
self.y2 = y2
for callback in self.observers:
callback(self.x1, self.y1, self.x2, self.y2)
def bind_to(self, callback):
""" binds the observer"""
self.observers.append(callback)
class ExtractSpectra():
def __init__(self, cube, area_selector):
""" class that will do fancy things with the selected area"""
self.cube = cube
self.x1_area = None
self.y1_area = None
self.x2_area = None
self.y2_area = None
self.sum_area = None
self.sum_background = None
self.area_selector = area_selector
self.area_selector.bind_to(self.update_position_area)
def update_position_area(self, x1, y1, x2, y2):
""" updates position upon changes in Area Selector"""
self.x1_area = x1
self.y1_area = y1
self.x2_area = x2
self.y2_area = y2
def get_spectra(self):
""" some math on the selected area"""
if self.x1_area != None:
self.sum_area = np.sum(self.cube[np.round(self.y1_area,0).astype(int) : np.round(self.y2_area,0).astype(int),
np.round(self.x1_area,0).astype(int) : np.round(self.x2_area,0).astype(int)])
print(self.sum_area)
else:
print("Area not selected!")
class BackgroundSelector():
""" lets the user select an area, same structur as other selector"""
def __init__(self, fig, ax, im):
self.x1 = None
self.y1 = None
self.x2 = None
self.y2 = None
self.observers = []
toggle_selector.RS = RectangleSelector(ax, self.line_select_callback,
drawtype='box', useblit=True,
button=[1], # don't use middle button
minspanx=1, minspany=1,
spancoords='pixels',
interactive=True,
rectprops=dict(facecolor='red',edgecolor='black', alpha=0.3))
def line_select_callback(self, eclick, erelease):
'eclick and erelease are the press and release events'
self.x1, self.y1 = eclick.xdata, eclick.ydata
self.x2, self.y2 = erelease.xdata, erelease.ydata
self.set_new_position(self.x1, self.y1, self.x2, self.y2)
def set_new_position(self, x1, y1, x2, y2):
self.x1 = x1
self.y1 = y1
self.x2 = x2
self.y2 = y2
for callback in self.observers:
callback(self.x1, self.y1, self.x2, self.y2)
def bind_to(self, callback):
self.observers.append(callback)
class ExtractBackground():
def __init__(self, cube, background_selector):
self.cube = cube
self.x1_background = None
self.y1_background = None
self.x2_background = None
self.y2_background = None
self.sum_background = None
self.background_selector = background_selector
self.background_selector.bind_to(self.update_position_background)
def update_position_background(self, x1, y1, x2, y2):
self.x1_background = x1
self.y1_background = y1
self.x2_background = x2
self.y2_background = y2
def get_background(self):
if self.x1_background != None:
self.sum_background = np.sum(self.cube[np.round(self.y1_background,0).astype(int) : np.round(self.y2_background,0).astype(int),
np.round(self.x1_background,0).astype(int) : np.round(self.x2_background,0).astype(int)])
print(self.sum_background)
else:
print("Background not selected!")
def sample_plot():
fig = plt.figure()
ax = plt.subplot()
im = np.ones((100,100))*-1
im[10:20,10:40] = 1.
img = ax.imshow(im, origin='lower', cmap='inferno')
return(fig, ax, img, im)
if __name__ == "__main__":
def toggle_selector( event):
print(' Key pressed.')
if event.key in ['E', 'e']:
area_selector = AreaSelector(fig, ax, im)
extractor_area = ExtractSpectra(im, area_selector)
global extractor_area
print('e')
if event.key in ['C', 'c']:
background_selector = BackgroundSelector(fig, ax, im)
extractor_background = ExtractBackground(im, background_selector)
global extractor_background
print('c')
if event.key in ['Y', 'y']:
try: extractor_area.get_spectra()
except: print('extrator area not designated')
try: extractor_background.get_background()
except: print('background area not designated')
print('y')
fig, ax, img, im = sample_plot()
plt.connect('key_press_event', toggle_selector)
plt.show()
这基本上可以正常工作(即使我对编写此方法的方式并不满意(为什么要使用4个类?使用全局变量等),但是AreaSelector在屏幕上移动时会在屏幕上创建一个奇怪的图案(单人纸牌游戏玩家会认出它!)
发生了什么事?如果您有心情,我该怎么做呢?我正在尝试升级我的编程游戏!
谢谢!