Source code for snom_analysis.lib.rectangle_selector

##############################################################################
# Copyright (C) 2020-2025 Hans-Joachim Schill

# This file is part of snom_analysis.

# snom_analysis is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# snom_analysis is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with snom_analysis.  If not, see <http://www.gnu.org/licenses/>.
##############################################################################

from matplotlib.widgets import RectangleSelector, Button
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable

from .snom_colormaps import SNOM_amplitude, SNOM_phase

# This is an adaptation of the example code provided by the matplotlib documentation:
# https://matplotlib.org/3.1.3/gallery/widgets/rectangle_selector.html


[docs] def select_rectangle(data, channel): selector = Rectangle_Selector(data, channel) selection = selector.selection return selection
[docs] class Rectangle_Selector(): def __init__(self, data, channel): self.data = data self.channel = channel self.selection = None self.create_plot()
[docs] def create_plot(self): cmap = 'gray' if ('Z' in self.channel) or ('MT' in self.channel): cmap = 'gray' elif ('P' or 'arg') in self.channel: cmap = SNOM_phase elif ('A' or 'abs') in self.channel: cmap = SNOM_amplitude else: print('Unknown channel, could not find the proper colormap!') self.fig, axis = plt.subplots() plot = plt.pcolormesh(self.data, cmap=cmap) axis.invert_yaxis() divider = make_axes_locatable(axis) cax = divider.append_axes("right", size="5%", pad=0.05) cbar = plt.colorbar(plot, cax=cax) cbar.ax.get_yaxis().labelpad = 15 label = 'data' title = 'Select an area via drag and drop' cbar.ax.set_ylabel(label, rotation=270) axis.set_title(title) axis.axis('scaled') def line_select_callback(eclick, erelease): #eclick and erelease are the press and release events x1, y1 = eclick.xdata, eclick.ydata x2, y2 = erelease.xdata, erelease.ydata self.selection = [[round(x1), round(y1)], [round(x2), round(y2)]] def toggle_selector(event): print(' Key pressed.') if event.key in ['Q', 'q'] and toggle_selector.RS.active: print(' RectangleSelector deactivated.') toggle_selector.RS.set_active(False) if event.key in ['A', 'a'] and not toggle_selector.RS.active: print(' RectangleSelector activated.') toggle_selector.RS.set_active(True) # drawtype is 'box' or 'line' or 'none' toggle_selector.RS = RectangleSelector(axis, line_select_callback, useblit=True, button=[1, 3], # don't use middle button minspanx=5, minspany=5, spancoords='pixels', interactive=True) self.cid = self.fig.canvas.mpl_connect('key_press_event', toggle_selector) accept = plt.axes([0.8, 0.025, 0.1, 0.04]) button = Button(accept, 'Accept') button.on_clicked(self.accept) plt.show()
[docs] def accept(self, value): # print('value:', value) self.fig.canvas.mpl_disconnect(self.cid) plt.close()