0

我的代码使用mplcursors显示 matplotlib 散点图中每个点的标签,类似于此示例。我想知道如何形成一个值列表,使某个点脱颖而出,就像我有一个点图一样y=-x^2。当我接近峰值时,它不应该显示 0.001,而是显示 0,而无需找到顶部的确切鼠标位置。我无法解决图表中的每个点,因为我没有特定的功能。

4

1 回答 1

1

假设散点图中的点是有序的,我们可以调查附近窗口中的极值是否也是稍大窗口中的极值。如果,那么我们可以用它的 x 和 y 坐标报告那个极值。

下面的代码仅在我们接近局部最大值或最小值时显示注释。它还临时显示一条水平和垂直线以指示确切的位置。代码可以是许多变体的起点。

import matplotlib.pyplot as plt
import mplcursors
import numpy as np

near_window = 10 # the width of the nearby window
far_window = 20 # the width of the far window

def show_annotation(sel):
    ind = sel.target.index
    near_start_index = max(0, ind - near_window)
    y_near = y[near_start_index: min(N, ind + near_window)]
    y_far = y[max(0, ind - far_window): min(N, ind + far_window)]
    near_max = y_near.max()
    far_max = y_far.max()
    annotation_str = ''
    if near_max == far_max:
        near_argmax = y_near.argmax()
        annotation_str = f'local max:\nx:{x[near_start_index + near_argmax]:.3f}\ny:{near_max:.3f}'
        maxline = plt.axhline(near_max, color='crimson', ls=':')
        maxline_x = plt.axvline(x[near_start_index+near_argmax], color='grey', ls=':')
        sel.extras.append(maxline)
        sel.extras.append(maxline_x)
    else:
        near_min = y_near.min()
        far_min = y_far.min()
        if near_min == far_min:
            near_argmin = y_near.argmin()
            annotation_str = f'local min:\nx:{x[near_start_index+near_argmin]:.3f}\ny:{near_min:.3f}'
            minline = plt.axhline(near_min, color='limegreen', ls=':')
            minline_x = plt.axvline(x[near_start_index + near_argmin], color='grey', ls=':')
            sel.extras.append(minline)
            sel.extras.append(minline_x)
    if len(annotation_str) > 0:
        sel.annotation.set_text(annotation_str)
    else:
        sel.annotation.set_visible(False) # hide the annotation
        # sel.annotation.set_text(f'x:{sel.target[0]:.3f}\n y:{sel.target[1]:.3f}')

N = 500
x = np.linspace(0, 100, 500)
y = np.cumsum(np.random.normal(0, 0.1, N))
box = np.ones(20) / 20
y = np.convolve(y, box, mode='same')
scat = plt.scatter(x, y, s=1)

cursor = mplcursors.cursor(scat, hover=True)
cursor.connect('add', show_annotation)

plt.show()

示例图

于 2020-02-23T00:30:37.663 回答