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. 搭建Windows Server 2008故障转移群集
  2. redis 五大数据类型之set篇
  3. 得到目标元素距离视口的距离以及元素自身的宽度与高度(用于浮层位置的动态改变)...
  4. php如何从左往右轮播,js实现从左向右滑动式轮播图效果
  5. att格式汇编指令_ARM汇编伪指令介绍.
  6. 消息消费要注意的细节
  7. 【theano-windows】学习笔记十八——混合蒙特卡洛采样
  8. 【Advanced Windows Phone Programming】在windows phone 8中录制MP3和AAC及Amr音频
  9. Java基础之数组合并,详细讲解
  10. 蓝牙版本avrcp怎么选_干货|蓝牙网关是什么?蓝牙网关怎么用?蓝牙网关怎么选?...
  11. 高精度地图数据的结构
  12. 图像处理学习——色彩空间
  13. Vim文件和日历操作
  14. 制作可爱的小黄人插图
  15. 操作系统进程调度算法——吸烟者问题
  16. c# 调整图片分辨率
  17. ubuntu系统下THETA S 全景相机 通过ROS导出图像
  18. Python数据分析与大数据处理从入门到精通
  19. (2020)使用Airtest来爬取某宝评论数据
  20. 物联网项目(四)订单系统

热门文章

  1. xtdpdgmm:动态面板数据模型一网打尽
  2. 如何利用python监控主机存活并邮件、短信通知
  3. 中华人民共和国计算机信息网络,中华人民共和国计算机信息网络 国际联网管理暂行规定...
  4. 地铁线路项目-结对编程
  5. Struts2 通配符使用
  6. BroadcastReceiver启动Service 3.1之后静态注册
  7. 黑苹果安装教程---联想G480安装懒人版10.9.5
  8. 国产双模蓝牙芯片简介
  9. 单片机与触摸屏通信c语言,讲述如何实现单片机与触摸屏的通信
  10. 手机射频工程师培训大纲