matplotlibwidgets模块提供Cursor类用于支持十字光标的生成。另外官方还提供了自定义十字光标的实例。

widgets模块Cursor类源码

class Cursor(AxesWidget):"""A crosshair cursor that spans the axes and moves with mouse cursor.For the cursor to remain responsive you must keep a reference to it.Parameters----------ax : `matplotlib.axes.Axes`The `~.axes.Axes` to attach the cursor to.horizOn : bool, default: TrueWhether to draw the horizontal line.vertOn : bool, default: TrueWhether to draw the vertical line.useblit : bool, default: FalseUse blitting for faster drawing if supported by the backend.Other Parameters----------------**lineprops`.Line2D` properties that control the appearance of the lines.See also `~.Axes.axhline`.Examples--------See :doc:`/gallery/widgets/cursor`."""def __init__(self, ax, horizOn=True, vertOn=True, useblit=False,**lineprops):AxesWidget.__init__(self, ax)self.connect_event('motion_notify_event', self.onmove)self.connect_event('draw_event', self.clear)self.visible = Trueself.horizOn = horizOnself.vertOn = vertOnself.useblit = useblit and self.canvas.supports_blitif self.useblit:lineprops['animated'] = Trueself.lineh = ax.axhline(ax.get_ybound()[0], visible=False, **lineprops)self.linev = ax.axvline(ax.get_xbound()[0], visible=False, **lineprops)self.background = Noneself.needclear = Falsedef clear(self, event):"""Internal event handler to clear the cursor."""if self.ignore(event):returnif self.useblit:self.background = self.canvas.copy_from_bbox(self.ax.bbox)self.linev.set_visible(False)self.lineh.set_visible(False)def onmove(self, event):"""Internal event handler to draw the cursor when the mouse moves."""if self.ignore(event):returnif not self.canvas.widgetlock.available(self):returnif event.inaxes != self.ax:self.linev.set_visible(False)self.lineh.set_visible(False)if self.needclear:self.canvas.draw()self.needclear = Falsereturnself.needclear = Trueif not self.visible:returnself.linev.set_xdata((event.xdata, event.xdata))self.lineh.set_ydata((event.ydata, event.ydata))self.linev.set_visible(self.visible and self.vertOn)self.lineh.set_visible(self.visible and self.horizOn)self._update()def _update(self):if self.useblit:if self.background is not None:self.canvas.restore_region(self.background)self.ax.draw_artist(self.linev)self.ax.draw_artist(self.lineh)self.canvas.blit(self.ax.bbox)else:self.canvas.draw_idle()return False

自定义十字光标实现

简易十字光标实现

首先在 Cursor类的构造方法__init__中,构造了十字光标的横线、竖线和坐标显示;然后在on_mouse_move方法中,根据事件数据更新横竖线和坐标显示,最后在调用时,通过mpl_connect方法绑定on_mouse_move方法和鼠标移动事件'motion_notify_event'

import matplotlib.pyplot as plt
import numpy as npclass Cursor:"""A cross hair cursor."""def __init__(self, ax):self.ax = axself.horizontal_line = ax.axhline(color='k', lw=0.8, ls='--')self.vertical_line = ax.axvline(color='k', lw=0.8, ls='--')# text location in axes coordinatesself.text = ax.text(0.72, 0.9, '', transform=ax.transAxes)def set_cross_hair_visible(self, visible):need_redraw = self.horizontal_line.get_visible() != visibleself.horizontal_line.set_visible(visible)self.vertical_line.set_visible(visible)self.text.set_visible(visible)return need_redrawdef on_mouse_move(self, event):if not event.inaxes:need_redraw = self.set_cross_hair_visible(False)if need_redraw:self.ax.figure.canvas.draw()else:self.set_cross_hair_visible(True)x, y = event.xdata, event.ydata# update the line positionsself.horizontal_line.set_ydata(y)self.vertical_line.set_xdata(x)self.text.set_text('x=%1.2f, y=%1.2f' % (x, y))self.ax.figure.canvas.draw()x = np.arange(0, 1, 0.01)
y = np.sin(2 * 2 * np.pi * x)fig, ax = plt.subplots()
ax.set_title('Simple cursor')
ax.plot(x, y, 'o')
cursor = Cursor(ax)
#关键部分,绑定鼠标移动事件处理
fig.canvas.mpl_connect('motion_notify_event', cursor.on_mouse_move)
plt.show()

优化十字光标实现

在简易实现中,每次鼠标移动时,都会重绘整个图像,这样效率比较低。
在优化实现中,每次鼠标移动时,只重绘光标和坐标显示,背景图像不再重绘。

import matplotlib.pyplot as plt
import numpy as npclass BlittedCursor:"""A cross hair cursor using blitting for faster redraw."""def __init__(self, ax):self.ax = axself.background = Noneself.horizontal_line = ax.axhline(color='k', lw=0.8, ls='--')self.vertical_line = ax.axvline(color='k', lw=0.8, ls='--')# text location in axes coordinatesself.text = ax.text(0.72, 0.9, '', transform=ax.transAxes)self._creating_background = Falseax.figure.canvas.mpl_connect('draw_event', self.on_draw)def on_draw(self, event):self.create_new_background()def set_cross_hair_visible(self, visible):need_redraw = self.horizontal_line.get_visible() != visibleself.horizontal_line.set_visible(visible)self.vertical_line.set_visible(visible)self.text.set_visible(visible)return need_redrawdef create_new_background(self):if self._creating_background:# discard calls triggered from within this functionreturnself._creating_background = Trueself.set_cross_hair_visible(False)self.ax.figure.canvas.draw()self.background = self.ax.figure.canvas.copy_from_bbox(self.ax.bbox)self.set_cross_hair_visible(True)self._creating_background = Falsedef on_mouse_move(self, event):if self.background is None:self.create_new_background()if not event.inaxes:need_redraw = self.set_cross_hair_visible(False)if need_redraw:self.ax.figure.canvas.restore_region(self.background)self.ax.figure.canvas.blit(self.ax.bbox)else:self.set_cross_hair_visible(True)# update the line positionsx, y = event.xdata, event.ydataself.horizontal_line.set_ydata(y)self.vertical_line.set_xdata(x)self.text.set_text('x=%1.2f, y=%1.2f' % (x, y))self.ax.figure.canvas.restore_region(self.background)self.ax.draw_artist(self.horizontal_line)self.ax.draw_artist(self.vertical_line)self.ax.draw_artist(self.text)self.ax.figure.canvas.blit(self.ax.bbox)x = np.arange(0, 1, 0.01)
y = np.sin(2 * 2 * np.pi * x)fig, ax = plt.subplots()
ax.set_title('Blitted cursor')
ax.plot(x, y, 'o')
blitted_cursor = BlittedCursor(ax)
fig.canvas.mpl_connect('motion_notify_event', blitted_cursor.on_mouse_move)
plt.show()

捕捉数据十字光标实现

在前面的两种实现中,鼠标十字光标可以随意移动。在本实现中,十字光标只会出现在离鼠标x坐标最近的数据点上。

import matplotlib.pyplot as plt
import numpy as npclass SnappingCursor:"""A cross hair cursor that snaps to the data point of a line, which isclosest to the *x* position of the cursor.For simplicity, this assumes that *x* values of the data are sorted."""def __init__(self, ax, line):self.ax = axself.horizontal_line = ax.axhline(color='k', lw=0.8, ls='--')self.vertical_line = ax.axvline(color='k', lw=0.8, ls='--')self.x, self.y = line.get_data()self._last_index = None# text location in axes coordsself.text = ax.text(0.72, 0.9, '', transform=ax.transAxes)def set_cross_hair_visible(self, visible):need_redraw = self.horizontal_line.get_visible() != visibleself.horizontal_line.set_visible(visible)self.vertical_line.set_visible(visible)self.text.set_visible(visible)return need_redrawdef on_mouse_move(self, event):if not event.inaxes:self._last_index = Noneneed_redraw = self.set_cross_hair_visible(False)if need_redraw:self.ax.figure.canvas.draw()else:self.set_cross_hair_visible(True)x, y = event.xdata, event.ydataindex = min(np.searchsorted(self.x, x), len(self.x) - 1)if index == self._last_index:return  # still on the same data point. Nothing to do.self._last_index = indexx = self.x[index]y = self.y[index]# update the line positionsself.horizontal_line.set_ydata(y)self.vertical_line.set_xdata(x)self.text.set_text('x=%1.2f, y=%1.2f' % (x, y))self.ax.figure.canvas.draw()x = np.arange(0, 1, 0.01)
y = np.sin(2 * 2 * np.pi * x)fig, ax = plt.subplots()
ax.set_title('Snapping cursor')
line, = ax.plot(x, y, 'o')
snap_cursor = SnappingCursor(ax, line)
fig.canvas.mpl_connect('motion_notify_event', snap_cursor.on_mouse_move)
plt.show()

参考资料

https://www.matplotlib.org.cn/gallery/misc/cursor_demo_sgskip.html

matplotlib绘制鼠标的十字光标(自定义方式,官方实例)相关推荐

  1. matplotlib绘制鼠标的十字光标(内置方式)

    相对于echarts等基于JavaScript的图表库,matplotlib的交互能力相对较差. 在实际应用中,我们经常想使用十字光标来定位数据坐标,matplotlib内置提供支持. 官方示例 ma ...

  2. python画十字_matplotlib绘制鼠标的十字光标的实现(内置方式)

    相对于echarts等基于JavaScript的图表库,matplotlib的交互能力相对较差. 在实际应用中,我们经常想使用十字光标来定位数据坐标,matplotlib内置提供支持. 官方示例 ma ...

  3. python使用matplotlib绘制鼠标路径

    python使用matplotlib绘制鼠标路径 一.前言 本程序实现的基本原理是:根据单位时间内鼠标经过的点绘制成折线图. 二.代码 # -*- coding = utf-8 -*- # @Time ...

  4. 实现绘图区的大十字光标

    有时,我们需要用VB快速开发一个试验数据绘图处理程序,将绘图控件内的鼠标光标改变成与AutoCAD软件中使用的大十字光标的形式,将可以比普通的箭头光标达到更好的效果.那么我们如何实现这样的大十字光标呢 ...

  5. matplotlib绘制多子图共享鼠标光标

    matplotlib官方除了提供了鼠标十字光标的示例,还提供了同一图像内多子图共享光标的示例,其功能主要由widgets模块中的MultiCursor类提供支持. MultiCursor类与Curso ...

  6. Matplotlib绘制象限图——支持中文、箭头、自定义轴线交点

    Matplotlib绘制象限图--支持中文.箭头.自定义轴线交点 1. 效果图 2. 原理 2.1 绘制象限图步骤 2.1 添加文字到图表 3. 源码 参考 这篇博客将介绍如何使用matplotlib ...

  7. AUTOCAD——调整十字光标、CAD表格文字对齐方式

    CAD如何调整十字光标? 执行方式 1.输入自定义设置命令"OPTIONS"(快捷键:OP),按下空格键. 自定义设置 2.在弹出的选项界面中,打开显示页面,选择页面中的" ...

  8. android 画布 轨迹,Android 多点触控,绘制滑动轨迹和十字光标

    这个测试项,要捕捉当前有几个触摸点,当前触摸点坐标,滑动事件在x轴.y轴方向的速度等信息,在触摸时跟随触摸点会出现十字光标,绘制出滑动轨迹. 首先绘制出暗色格子背景,采用了自定义View,较为简单,核 ...

  9. 【CAD】【个人习惯】十字光标大小和自定义右键单击

    目录 1. 十字光标大小 2. 自定义右键单击 1. 十字光标大小 在哪里设置呢??? 点击[工具],再点击[选项],点击[显示],再找到[十字光标大小(Z)] 我个人习惯,右边拉满 2. 自定义右键 ...

  10. python画十字_如何绘制十字线并在pyqtgraph中绘制鼠标位置?

    我是Python和pyqtgraph的新手.我正在为不同类型的信号查看器.当然,当我想用​​鼠标位置包含十字准线和文本标签时,我陷入了困境.我正在使用GridLayout,因为后来该图与其他几个元素结 ...

最新文章

  1. 【Android 事件分发】ItemTouchHelper 简介 ( 拖动/滑动事件 | ItemTouchHelper.Callback 回调 )
  2. 【VC++】Visual Studio编辑器“智能提示(IntelliSense)”异常的解决方案
  3. using的几种用法
  4. Angular 依赖注入学习笔记之工厂函数的用法
  5. 数字电路数据选择器及其应用实验报告_科普|说说大数据是什么,及其特点与应用...
  6. 2017计算机应用技术考研,2017年中国科学技术大学081203计算机应用技术考研专业目录与考试科目.docx...
  7. The 2020 ICPC Asia Macau Regional Contest J. Jewel Grab(数颜色+链表)
  8. JavaScript获取select下拉框中的第一个值
  9. html 文本框 初始化,Flutter 文本框初始化时显示默认值
  10. 从NeurIPS 2018看AI发展路线!
  11. mvc:annotation-driven 注解的作用
  12. .net人员用Java 之Java EE
  13. Android 四大组件学习之Activity四
  14. java实体类属性比较_实体类之间属性对比的方法
  15. 密码破解—Hashcat
  16. 酷睿i7 8750h相当于什么水平 i78750h属于什么级别
  17. RGB颜色转16进制颜色
  18. paper的经验和会议排名
  19. 彻底禁用win10自动更新功能及其powershell代码
  20. HDU6357 Hills And Valleys

热门文章

  1. 无人机拉力测试台研制测试过程中的9个关键技术点
  2. 电子科技大学 计算机学院 夏令营,2018年电子科技大学全校各学院保研夏令营通知信息大汇总...
  3. 监控网站与接口宕机,并推送 App 消息提醒的程序
  4. 监督管理计算机系统的安全保,网络信息安全知识:监督管理计算机信息系统安全保护工作应由()完成。...
  5. Zookeeper总结——知识点、选举机制、客户端操作及写数据流程、API操作、zookeeper分布式锁之 Curator、ZAB协议、CAP理论之zookeeper的CP理论
  6. 中国工商注册企业统计数据
  7. wordpress插件_5个最佳WordPress企业目录插件
  8. Java、JSP网吧自动计费收费管理系统
  9. 如何使用phpDesigner 编写一个表格
  10. WineQQ2012 最新下载