当前位置 博文首页 > matplotlib交互式数据光标实现(mplcursors)

    matplotlib交互式数据光标实现(mplcursors)

    作者:mighty13 时间:2021-02-10 18:28

    简介

    mplcursors包也可以为matplotlib提供交互式的数据光标(弹出式注释框),它的灵感来源于mpldatacursor包,可以认为是基于mpldatacursor包的二次开发。
    相对于mpldatacursor包,mplcursors包最大的特点就是提供了一些相对底层的API,这样功能实现更加灵活。

    安装

    pip install mplcursors

    基本应用

    mplcursors包的基本应用方法与mpldatacursor包类似,直接应用cursor函数即可。

    基本操作方法

    • 鼠标左键单击图表数据元素时会弹出文本框显示最近的数据元素的坐标值。
    • 鼠标右键单击文本框取消显示数据光标。
    • 按d键时切换显示\关闭数据光标。

    案例源码

    import matplotlib.pyplot as plt
    import numpy as np
    import mplcursors
    
    data = np.outer(range(10), range(1, 5))
    
    fig, ax = plt.subplots()
    lines = ax.plot(data)
    ax.set_title("Click somewhere on a line.\nRight-click to deselect.\n"
           "Annotations can be dragged.")
    
    mplcursors.cursor(lines) # or just mplcursors.cursor()
    
    plt.show()

    mplcursors自定义应用

    mpldatacursor包中自定义功能主要通过向datacursor函数传递实参实现。
    mplcursors包中的cursor函数对标mpldatacursor包中的datacursor函数,但是在参数上发生了变化,保留了artistshoverbindingsmultiplehighlight等类似参数。
    mplcursors包增加Selection对象(底层为namedtuple)表示选择的数据元素的属性。
    当选中某个数据点时,可以通过添加(add)或删除(remove)事件触发、注册回调函数实现功能,回调函数只有一个参数,及选择的数据点。
    在注册回调函数时,mplcursors包支持使用装饰器。

    mpldatacursor与mplcursors API对比

    下面以修改显示文本信息为例对比下mpldatacursormplcursors的不同实现方式。

    在这里插入图片描述

    mpldatacursor实现方式

    import matplotlib.pyplot as plt
    import numpy as np
    from mpldatacursor import datacursor
    
    ax=plt.gca()
    labels = ["a", "b", "c"]
    for i in range(3):
      ax.plot(i, i,'o', label=labels[i])
    
    datacursor(formatter='{label}'.format)
    plt.show()

    mplcursors实现方式一

    import matplotlib.pyplot as plt
    import numpy as np
    import mplcursors
    
    ax=plt.gca()
    lines = ax.plot(range(3), range(3), "o")
    labels = ["a", "b", "c"]
    cursor = mplcursors.cursor(lines)
    cursor.connect(
      "add", lambda sel: sel.annotation.set_text(labels[sel.target.index]))
    
    plt.show()

    mplcursors实现方式二

    import matplotlib.pyplot as plt
    import numpy as np
    import mplcursors
    
    ax=plt.gca()
    lines = ax.plot(range(3), range(3), "o")
    labels = ["a", "b", "c"]
    cursor = mplcursors.cursor(lines)
    
    @cursor.connect("add")
    def on_add(sel):
      sel.annotation.set_text(labels[sel.target.index])
    plt.show()

    结论

    mplcursors包实现的功能与mpldatacursor包非常相似。相对而言mplcursors包的API更加灵活,通过connect函数或者装饰器自定义属性耦合性更弱,便于实现绘图与数据光标实现的分离。

    参考

    https://mplcursors.readthedocs.io/en/stable/
    https://github.com/anntzer/mplcursors

    js