My goal.个 我正在使用matplotlib滑块来绘制几个系列.我想 for each 点都贴上悬停标签.每一点都对应着测量.所以我想在这些悬停标签上显示测量名称.

Question.个 如何更新新系列的标签(用于滑块位置)?如果我在UPDATE函数中创建新的游标,我会得到每个点的几个标签.所以我需要想办法先删除旧标签.我该怎么做呢?

Description.个 在第一张幻灯片上,我得到了A和B标签的分数.在第二张幻灯片上,我应该得到C和D标签,但我又得到了A和B.

My code.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
import mplcursors as mplc
%matplotlib widget
data = {'Name': ['A', 'B', 'C', 'D'], 'x': [1,3,3,2],'y': [4,7,5,1],'color': [1,2,3,2],'size' :[50,40,10,30],'slide': [1,1,2,2]}
df=pd.DataFrame.from_dict(data)
dff=df.loc[df['slide']==1]
z=list(set(df['slide'].to_list()))
x = dff['x'].to_list()
y = dff['y'].to_list()
lbl=dff['Name'].to_list()
fig, ax = plt.subplots()
ax.clear()
points = ax.scatter(x,y,s=100, alpha=0.5)
mplc.cursor(ax, hover=True).connect(
"add", lambda sel: sel.annotation.set_text(lbl[sel.index]))
xmin=min(x)
xmax=max(x)
ymin=min(y)
ymax=max(y)
ax.set_ylim([xmin-10,xmax+10])
ax.set_xlim([ymin-10,xmax+10])

axfreq = fig.add_axes([0.15, 0.1, 0.65, 0.03])
plot_slider = Slider(
    ax=axfreq,
    label='',
    valmin=0,
    valmax=len(z),
    valinit=1,
    valstep=1,)

def update(val):
    dff=df.loc[df['slide']==plot_slider.val]
    x = dff['x'].to_list()
    y = dff['y'].to_list()
    lbl=dff['Name'].to_list()
    points.set_offsets(np.c_[x,y])
plot_slider.on_changed(update)
plt.show()

推荐答案

在我可以运行您的代码之前,我必须(!pip install mplcursors ipympl).

以下是我在更新滑块后获得正确注释/标签的workaround条:

sliders = df["slide"].unique()

fig, ax = plt.subplots()

d = {}
for sl in sliders:
    lbl, x, y = df.loc[
        df["slide"].eq(sl), ["Name", "x", "y"]].T.to_numpy()
    pts = ax.scatter(x, y, s=100)
    curs = mplc.cursor(pts, hover=True)
    curs.connect("add", lambda sel, lbl=lbl:
        sel.annotation.set_text(lbl[sel.index]))
    d[sl] = {"cursor": curs, "scatter": pts}
    
axfreq = fig.add_axes([0.15, 0.01, 0.73, 0.03]) # << I adjusted this

plot_slider = Slider(
    ax=axfreq, label="", valinit=1, valstep=1,
    valmin=min(sliders), valmax=max(sliders))

def curscatter(sl, op=0.5):
    """Display the cur/pts for the requested slider only"""
    for _sl, inf in d.items():
        curs = inf["cursor"]; pts = inf["scatter"]
        pts.set_alpha(op if _sl == sl else 0)
        curs.visible = (_sl == sl)
        
def update(curr_sl):
    curscatter(curr_sl)

curscatter(plot_slider.val) # or curscatter(1) 
plot_slider.on_changed(update)
plt.show()

Name x y color size slide
A 1 4 1 50 1
B 3 7 2 40 1
C 3 5 3 10 2
D 2 1 2 30 2

enter image description here

Python相关问答推荐

Python中的负前瞻性regex遇到麻烦

如何根据条件在多指标框架上进行groupby

比较两个数据帧并并排附加结果(获取性能警告)

Odoo 14 hr. emergency.public内的二进制字段

如何在Python中将returns.context. DeliverresContext与Deliverc函数一起使用?

处理带有间隙(空)的duckDB上的重复副本并有效填充它们

如何请求使用Python将文件下载到带有登录名的门户网站?

当独立的网络调用不应该互相阻塞时,'

我如何根据前一个连续数字改变一串数字?

Pandas DataFrame中行之间的差异

SQLAlchemy bindparam在mssql上失败(但在mysql上工作)

Tkinter菜单自发添加额外项目

使用Python查找、替换和调整PDF中的图像'

处理具有多个独立头的CSV文件

在Docker容器(Alpine)上运行的Python应用程序中读取. accdb数据库

在用于Python的Bokeh包中设置按钮的样式

如何强制向量中的特定元素在Gekko中处于优化解决方案中

Pandas:计数器的滚动和,复位

Matplotlib中的曲线箭头样式

如果列包含空值,则PANAS查询不起作用