如何拖拽matplotlib的RectangleSelector时保持固定尺寸?
实现拖拽RectangleSelector时保持尺寸固定的方法
要让RectangleSelector在拖拽过程中保持宽高不变,你可以通过自定义继承自RectangleSelector的类,重写拖拽相关的处理逻辑,强制在移动时维持初始的宽高值。具体实现如下:
- 定义一个新的类
FixedSizeRectangleSelector,继承原有的RectangleSelector - 在类中重写
_on_move方法,记录初始宽高,在每次移动时重新计算位置,保持宽高不变 - 使用这个自定义类替代原有的RectangleSelector即可
下面是完整的代码示例:
import matplotlib.pyplot as plt from matplotlib.widgets import RectangleSelector class FixedSizeRectangleSelector(RectangleSelector): def __init__(self, ax, onselect, **kwargs): super().__init__(ax, onselect, **kwargs) self._initial_width = None self._initial_height = None def _on_move(self, event): # 第一次拖拽时记录初始宽高 if self._active: if self._initial_width is None or self._initial_height is None: self._initial_width = abs(self.extents[1] - self.extents[0]) self._initial_height = abs(self.extents[3] - self.extents[2]) else: # 计算当前中心位置,保持宽高不变 center_x = (event.xdata + self._corner_x) / 2 center_y = (event.ydata + self._corner_y) / 2 # 重新设置选框范围,维持初始宽高 x_min = center_x - self._initial_width / 2 x_max = center_x + self._initial_width / 2 y_min = center_y - self._initial_height / 2 y_max = center_y + self._initial_height / 2 self.extents = (x_min, x_max, y_min, y_max) super()._on_move(event) # 测试代码 def on_select(eclick, erelease): print(f"选中区域: x={eclick.xdata}-{erelease.xdata}, y={eclick.ydata}-{erelease.ydata}") fig, ax = plt.subplots() ax.plot([1,2,3,4,5], [2,4,1,3,5]) # 使用自定义的固定尺寸矩形选择器 rs = FixedSizeRectangleSelector(ax, on_select, drawtype='box', interactive=True) plt.show()
关键逻辑说明:
- 在
__init__中初始化存储初始宽高的变量 - 在
_on_move方法中,当开始拖拽(_active为True)时,第一次记录选框的初始宽高 - 后续移动时,根据当前鼠标位置和选框对角点计算中心,再用初始宽高重新计算选框范围,确保宽高不随拖拽改变
- 调用父类的
_on_move方法维持原有的绘制逻辑
这样处理后,拖拽RectangleSelector的任意位置时,选框的宽高都会保持创建时的大小,和EllipseSelector的行为一致,甚至可以拖拽到当前axes视图之外。
内容的提问来源于stack exchange,提问作者sfzhang
相关产品推荐
相关产品推荐

