matplotlib部件(widgets)之套索(Lasso)

套索概述

套索(Lasso)是与套索选区(LassoSelector)相似的matplotlib部件(widgets),两者的区别主要在于:

  • 继承关系:
    • 套索具体实现定义为matplotlib.widgets.Lasso类,继承关系为:Widget->AxesWidget->Lasso
    • 套索选区具体实现定义为matplotlib.widgets.LassoSelector类,继承关系为:Widget->AxesWidget->_SelectorWidget->LassoSelector
  • 构造参数:
    • Lasso类的签名为class matplotlib.widgets.Lasso(ax, xy, callback=None, useblit=True)Lasso类需要给定套索一个起始的坐标。
    • LassoSelector类的签名为class matplotlib.widgets.LassoSelector(ax, onselect=None, useblit=True, lineprops=None, button=None)
  • 事件处理:
    • Lasso事件在鼠标释放时即被销毁。
    • LassoSelector在鼠标释放时仍然可以继续与子图交互,直到断开与子图的连接。

Lasso类构造函数的参数为:

  • ax:套索生效的子图,类型为matplotlib.axes.Axes的实例。
  • xy:套索起始的坐标。
  • callback:套索完成即鼠标释放时执行的回调函数,函数签名为def func(verts)verts的为套索端点的坐标列表。

套索可以使用matplotlib.path.Path类的contains_point方法获取选区内的数据点
貌似 Lasso是实验性API,还不够完善,matplotlib 3.3之后可能逐步废弃 Lasso

案例:

官方案例,https://matplotlib.org/3.2.1/gallery/event_handling/lasso_demo.html

案例说明

在这里插入图片描述

案例代码


from matplotlib import colors as mcolors, path
from matplotlib.collections import RegularPolyCollection
import matplotlib.pyplot as plt
from matplotlib.widgets import Lasso
import numpy as np


class Datum:
    colorin = mcolors.to_rgba("red")
    colorout = mcolors.to_rgba("blue")

    def __init__(self, x, y, include=False):
        self.x = x
        self.y = y
        if include:
            self.color = self.colorin
        else:
            self.color = self.colorout


class LassoManager:
    def __init__(self, ax, data):
        self.axes = ax
        self.canvas = ax.figure.canvas
        self.data = data

        self.Nxy = len(data)

        facecolors = [d.color for d in data]
        self.xys = [(d.x, d.y) for d in data]
        self.collection = RegularPolyCollection(
            6, sizes=(100,),
            facecolors=facecolors,
            offsets=self.xys,
            transOffset=ax.transData)

        ax.add_collection(self.collection)

        self.cid = self.canvas.mpl_connect('button_press_event', self.onpress)

    def callback(self, verts):
        facecolors = self.collection.get_facecolors()
        p = path.Path(verts)
        ind = p.contains_points(self.xys)
        for i in range(len(self.xys)):
            if ind[i]:
                facecolors[i] = Datum.colorin
            else:
                facecolors[i] = Datum.colorout

        self.canvas.draw_idle()
        self.canvas.widgetlock.release(self.lasso)
        del self.lasso

    def onpress(self, event):
        if self.canvas.widgetlock.locked():
            return
        if event.inaxes is None:
            return
        self.lasso = Lasso(event.inaxes,
                           (event.xdata, event.ydata),
                           self.callback)
        # acquire a lock on the widget drawing
        self.canvas.widgetlock(self.lasso)


if __name__ == '__main__':

    np.random.seed(19680801)

    data = [Datum(*xy) for xy in np.random.rand(100, 2)]
    ax = plt.axes(xlim=(0, 1), ylim=(0, 1), autoscale_on=False)
    ax.set_title('Lasso points using left mouse button')

    lman = LassoManager(ax, data)

    plt.show()

代码分析

案例的关键代码在于LassoManager类的onpress方法和callback方法。由于Lasso类在事件处理上比较原始,需要用户进行控制,在鼠标按下、释放事件中需要使用canvas.widgetlock对象锁定/解锁绘图功能,保证只有一个对象进行绘图,canvas.widgetlockmatplotlib.widgets.LockDraw类的实例。

总结

尽量使用套索选区(LassoSelector)而不是套索(Lasso),两者功能相似,索选区(LassoSelector)使用相对更简单一些,套索(Lasso)还有一些BUG,matplotlib 3.3已不再推荐使用。

<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]。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值