matplotlib部件(widgets)之多边形选区(PolygonSelector)

本文介绍了matplotlib库中的PolygonSelector类,详细讲解了如何使用多边形选区进行对象选择,包括选区创建、移动、取消以及回调函数的配置。通过实例演示了如何在图形中创建并控制多边形选区,以及其在数据可视化的实际应用场景。

多边形选区概述

多边形选区是一种常见的对象选择方式,在一个子图中,单击鼠标左键即构建一个多边形的端点,最后一个端点与第一个端点重合即完成多边形选区,选区即为多个端点构成的多边形。在matplotlib中的多边形选区属于部件(widgets),matplotlib中的部件都是中性(neutral )的,即与具体后端实现无关。

多边形选区具体实现定义为matplotlib.widgets.PolygonSelector类,继承关系为:Widget->AxesWidget->_SelectorWidget->PolygonSelector

PolygonSelector类的签名为class matplotlib.widgets.PolygonSelector(ax, onselect, useblit=False, lineprops=None, markerprops=None, vertex_select_radius=15)

PolygonSelector类构造函数的参数为:

  • ax:多边形选区生效的子图,类型为matplotlib.axes.Axes的实例。
  • onselect:多边形选区完成后执行的回调函数,函数签名为def onselect( vertices)vertices数据类型为列表,列表元素格式为(xdata,ydata)元组。
  • drawtype:多边形选区的外观,取值范围为{"box", "line", "none"}"box"为多边形框,"line"为多边形选区对角线,"none"无外观,类型为字符串,默认值为"box"
  • lineprops:多边形选区线条的属性,默认值为dict(color='k', linestyle='-', linewidth=2, alpha=0.5)
  • markerprops:多边形选区端点的属性,默认值为dict(marker='o', markersize=7, mec='k', mfc='k', alpha=0.5)
  • vertex_select_radius:多边形端点的选择半径,浮点数,默认值为15,用于端点选择或者多边形闭合。

PolygonSelector类中的state_modifier_keys公有变量 state_modifier_keys定义了操作快捷键,类型为字典。

  • “move_all”: 移动已存在的选区,默认为"shift"
  • “clear”:清除现有选区,默认为 "escape",即esc键。
  • “move_vertex”:正方形选区,默认为"control"

PolygonSelector类中的verts特性返回多边形选区中的多有端点,类型为列表,元素为(x,y)元组,即端点的坐标元组。

案例

官方案例,https://matplotlib.org/gallery/widgets/polygon_selector_demo.html

案例说明

在这里插入图片描述

单击鼠标左键创建端点,最终点击初始端点闭合多边形,形成多边形选区。选区外的数据元素颜色变淡,选区内数据颜色保持不变。
esc键取消选区。按shift键鼠标可以移动多边形选区位置,按ctrl键鼠标可以移动多边形选区某个端点的位置。退出程序时,控制台输出选区内数据元素的坐标。
控制台输出:

Selected points:
[[2.0 2.0]
 [1.0 3.0]
 [2.0 3.0]]

案例代码


import numpy as np

from matplotlib.widgets import PolygonSelector
from matplotlib.path import Path


class SelectFromCollection:
    """
    Select indices from a matplotlib collection using `PolygonSelector`.

    Selected indices are saved in the `ind` attribute. This tool fades out the
    points that are not part of the selection (i.e., reduces their alpha
    values). If your collection has alpha < 1, this tool will permanently
    alter the alpha values.

    Note that this tool selects collection objects based on their *origins*
    (i.e., `offsets`).

    Parameters
    ----------
    ax : `~matplotlib.axes.Axes`
        Axes to interact with.
    collection : `matplotlib.collections.Collection` subclass
        Collection you want to select from.
    alpha_other : 0 <= float <= 1
        To highlight a selection, this tool sets all selected points to an
        alpha value of 1 and non-selected points to *alpha_other*.
    """

    def __init__(self, ax, collection, alpha_other=0.3):
        self.canvas = ax.figure.canvas
        self.collection = collection
        self.alpha_other = alpha_other

        self.xys = collection.get_offsets()
        self.Npts = len(self.xys)

        # Ensure that we have separate colors for each object
        self.fc = collection.get_facecolors()
        if len(self.fc) == 0:
            raise ValueError('Collection must have a facecolor')
        elif len(self.fc) == 1:
            self.fc = np.tile(self.fc, (self.Npts, 1))

        self.poly = PolygonSelector(ax, self.onselect)
        self.ind = []

    def onselect(self, verts):
        path = Path(verts)
        self.ind = np.nonzero(path.contains_points(self.xys))[0]
        self.fc[:, -1] = self.alpha_other
        self.fc[self.ind, -1] = 1
        self.collection.set_facecolors(self.fc)
        self.canvas.draw_idle()

    def disconnect(self):
        self.poly.disconnect_events()
        self.fc[:, -1] = 1
        self.collection.set_facecolors(self.fc)
        self.canvas.draw_idle()


if __name__ == '__main__':
    import matplotlib.pyplot as plt

    fig, ax = plt.subplots()
    grid_size = 5
    grid_x = np.tile(np.arange(grid_size), grid_size)
    grid_y = np.repeat(np.arange(grid_size), grid_size)
    pts = ax.scatter(grid_x, grid_y)

    selector = SelectFromCollection(ax, pts)

    print("Select points in the figure by enclosing them within a polygon.")
    print("Press the 'esc' key to start a new polygon.")
    print("Try holding the 'shift' key to move all of the vertices.")
    print("Try holding the 'ctrl' key to move a single vertex.")

    plt.show()

    selector.disconnect()

    # After figure is closed print the coordinates of the selected points
    print('\nSelected points:')
    print(selector.xys[selector.ind])
<think>我们正在讨论matplotlib.widgets模块。根据引用[4],我们知道Jupyter Widgets可以用于创建交互式可视化,而matplotlib.widgetsMatplotlib自带的交互式控件模块,它允许在图形中添加滑块、按钮等控件,并实现用户交互。 引用[1]提到,指令式绘图(pyplot)适合快速可视化但不适合交互式GUI应用,而widgets模块正是为了增强交互性。 引用[3]介绍了Matplotlib的基本绘图结构,包括创建坐标轴和图形,这在使用widgets时也是基础。 因此,我们将重点介绍matplotlib.widgets模块的功能和使用方法。 功能概述: matplotlib.widgets模块提供了一系列控件,如按钮(Button)、单选按钮(RadioButtons)、复选框(CheckButtons)、滑块(Slider)、文本框(TextBox)等,这些控件可以嵌入到Matplotlib图形中,并绑定回调函数,实现交互式数据可视化。 使用步骤: 1. 导入必要的模块。 2. 创建图形和坐标轴,注意为控件预留位置(通常使用subplots_adjust或GridSpec调整布局)。 3. 创建控件,并指定其位置和属性。 4. 为控件绑定回调函数(事件处理函数)。 5. 显示图形。 示例:使用滑块控件(Slider)调整正弦曲线的频率和振幅。 下面我们通过一个具体示例来演示如何使用matplotlib.widgets.Slider。 注意:在Jupyter Notebook中运行交互式控件需要适当的环境(如使用%matplotlib widget或%matplotlib notebook),或者使用独立的GUI后端(如Tkinter, Qt等)。 我们将创建一个包含两个滑块(分别控制频率和振幅)的图形,滑块的值改变时,正弦曲线会实时更新。 步骤详解:</think>### Matplotlib.widgets 使用指南 `matplotlib.widgets` 是 Matplotlib 提供的交互式控件模块,允许在图表中嵌入可交互元素(如按钮、滑块等),实现动态数据可视化。以下是核心功能介绍和使用方法: #### 一、核心控件类型 1. **按钮控件** - `Button`:执行单次操作的按钮 - `RadioButtons`:单选按钮组 - `CheckButtons`:多选按钮组 ```python from matplotlib.widgets import Button btn_ax = plt.axes([0.7, 0.05, 0.1, 0.04]) # 位置参数 [左, 下, 宽, 高] button = Button(btn_ax, '重置') ``` 2. **滑块控件** - `Slider`:连续值调节滑块 - `RangeSlider`:范围选择滑块 ```python from matplotlib.widgets import Slider slider_ax = plt.axes([0.2, 0.1, 0.6, 0.03]) slider = Slider(slider_ax, '振幅', 0.1, 5.0, valinit=1.0) ``` 3. **文本输入控件** `TextBox`:接收用户文本输入 ```python from matplotlib.widgets import TextBox text_ax = plt.axes([0.2, 0.05, 0.2, 0.04]) text_box = TextBox(text_ax, '公式:', initial="sin(x)") ``` 4. **其他高级控件** `Cursor`(十字准线)、`PolygonSelector`(多边形选择器)等 #### 二、核心交互机制 1. **回调函数绑定** 所有控件通过事件回调实现交互: ```python def update(val): amp = slider.val line.set_ydata(amp * np.sin(x)) fig.canvas.draw_idle() # 重绘图形 slider.on_changed(update) # 绑定滑块值变化事件 ``` 2. **控件布局管理** 使用 `plt.axes()` 指定控件位置(归一化坐标): ```python plt.subplots_adjust(bottom=0.25) # 为底部控件预留空间 ``` #### 三、完整使用示例 ```python import numpy as np import matplotlib.pyplot as plt from matplotlib.widgets import Slider, Button # 创建数据 x = np.linspace(0, 2*np.pi, 200) y = np.sin(x) # 初始化图形 fig, ax = plt.subplots() plt.subplots_adjust(bottom=0.25) # 底部预留控件空间 line, = ax.plot(x, y) # 添加滑块 slider_ax = plt.axes([0.2, 0.1, 0.6, 0.03]) slider = Slider(slider_ax, '频率', 0.1, 5.0, valinit=1.0) # 添加按钮 btn_ax = plt.axes([0.8, 0.025, 0.1, 0.04]) button = Button(btn_ax, '重置') # 回调函数 def update(val): freq = slider.val line.set_ydata(np.sin(freq * x)) fig.canvas.draw_idle() def reset(event): slider.reset() # 绑定事件 slider.on_changed(update) button.on_clicked(reset) plt.show() ``` 此代码创建正弦波图形,用户可通过滑块调整频率,点击按钮重置参数[^3]。 #### 四、应用场景 1. **参数动态调节**:实时调整模型参数(如滤波器截止频率) 2. **数据探索**:交互式浏览大型数据集 3. **教学演示**:动态展示数学函数变化 4. **仪表盘开发**:结合其他控件构建分析面板 > **注意**:在 Jupyter 环境中运行时,需先执行 `%matplotlib widget` 启用交互支持[^4]。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值