当鼠标悬停在matplotlib中的一个点上时,是否可以在茎图中显示标签?

u0njafvf  于 2022-11-15  发布在  其他
关注(0)|答案(2)|浏览(214)

我是新的matplotlib,我期待着标签的茎干图与x,y co-od时,鼠标悬停在该点。当我搜索一切都是为了散点图(可能使标 checkout 现时,悬停在一个点在matplotlib?目前的代码是这样的:

def plot_matching(mzs,ints,matching,scan_num):
fig=p1.gcf()
fig.canvas.set_window_title('MS/MS Viewer')
rel_ints=relative_intensity(ints)
p1.xlim(min(mzs)-100,max(mzs)+100)
p1.ylim(min(rel_ints),max(rel_ints)+5)
p1.title('Scan Number:'+scan_num)
p1.xlabel('m/z')
p1.ylabel('Relative intensity')
mzs_rel=zip(mzs,rel_ints)    
for x,y in mzs_rel:
    x1=[]
    y1=[]
    x1.append(x)
    y1.append(y)
    markerline, stemlines, baseline=p1.stem(x1,y1)
    p1.setp(markerline, 'Marker', '')
    for m in matching:
        if x==m[1] and y>3.0:
            p1.setp(stemlines, linewidth=2, color='r')
            p1.text(x,y,m[0],fontsize=12)
            break
        else:
            p1.setp(stemlines,linewidth=2, color='g')
return p1

散点图也会链接到干图吗?

z31licg0

z31licg01#

要创建一个悬停标签,需要挂接一个函数来处理motion_notify_events

plt.connect('motion_notify_event', some_function)

下面的代码展示了一种实现方法。

cursor = FollowDotCursor(ax, x, y)

其中ax是坐标轴,xy是坐标列表。由于您提供了xy,因此无论您是绘制折线图还是绘制干线图,都没有关系。当鼠标移到(xi, yi)附近时,标签就会出现。
下面的代码使用scipy.spatial.cKDTree来定位最近的点。Here是此代码的较早版本,不需要scipy。

import matplotlib.pyplot as plt
import scipy.spatial as spatial
import numpy as np
pi = np.pi
cos = np.cos

def fmt(x, y):
    return 'x: {x:0.2f}\ny: {y:0.2f}'.format(x=x, y=y)

class FollowDotCursor(object):
    """Display the x,y location of the nearest data point.
    https://stackoverflow.com/a/4674445/190597 (Joe Kington)
    https://stackoverflow.com/a/13306887/190597 (unutbu)
    https://stackoverflow.com/a/15454427/190597 (unutbu)
    """
    def __init__(self, ax, x, y, tolerance=5, formatter=fmt, offsets=(-20, 20)):
        try:
            x = np.asarray(x, dtype='float')
        except (TypeError, ValueError):
            x = np.asarray(mdates.date2num(x), dtype='float')
        y = np.asarray(y, dtype='float')
        mask = ~(np.isnan(x) | np.isnan(y))
        x = x[mask]
        y = y[mask]
        self._points = np.column_stack((x, y))
        self.offsets = offsets
        y = y[np.abs(y-y.mean()) <= 3*y.std()]
        self.scale = x.ptp()
        self.scale = y.ptp() / self.scale if self.scale else 1
        self.tree = spatial.cKDTree(self.scaled(self._points))
        self.formatter = formatter
        self.tolerance = tolerance
        self.ax = ax
        self.fig = ax.figure
        self.ax.xaxis.set_label_position('top')
        self.dot = ax.scatter(
            [x.min()], [y.min()], s=130, color='green', alpha=0.7)
        self.annotation = self.setup_annotation()
        plt.connect('motion_notify_event', self)

    def scaled(self, points):
        points = np.asarray(points)
        return points * (self.scale, 1)

    def __call__(self, event):
        ax = self.ax
        # event.inaxes is always the current axis. If you use twinx, ax could be
        # a different axis.
        if event.inaxes == ax:
            x, y = event.xdata, event.ydata
        elif event.inaxes is None:
            return
        else:
            inv = ax.transData.inverted()
            x, y = inv.transform([(event.x, event.y)]).ravel()
        annotation = self.annotation
        x, y = self.snap(x, y)
        annotation.xy = x, y
        annotation.set_text(self.formatter(x, y))
        self.dot.set_offsets(np.column_stack((x, y)))
        bbox = self.annotation.get_window_extent()
        self.fig.canvas.blit(bbox)
        self.fig.canvas.draw_idle()

    def setup_annotation(self):
        """Draw and hide the annotation box."""
        annotation = self.ax.annotate(
            '', xy=(0, 0), ha = 'right',
            xytext = self.offsets, textcoords = 'offset points', va = 'bottom',
            bbox = dict(
                boxstyle='round,pad=0.5', fc='yellow', alpha=0.75),
            arrowprops = dict(
                arrowstyle='->', connectionstyle='arc3,rad=0'))
        return annotation

    def snap(self, x, y):
        """Return the value in self.tree closest to x, y."""
        dist, idx = self.tree.query(self.scaled((x, y)), k=1, p=1)
        try:
            return self._points[idx]
        except IndexError:
            # IndexError: index out of bounds
            return self._points[0]

fig, ax = plt.subplots()
x = np.linspace(0.1, 2*pi, 10)
y = cos(x)
markerline, stemlines, baseline = ax.stem(x, y, '-.')
plt.setp(markerline, 'markerfacecolor', 'b')
plt.setp(baseline, 'color','r', 'linewidth', 2)
cursor = FollowDotCursor(ax, x, y, tolerance=20)
plt.show()

prdp8dxp

prdp8dxp2#

有一个伟大的插件:https://github.com/anntzer/mplcursors安装非常简单。不需要自己实现。

相关问题