如何通过将光标悬停在热图元素上来显示它的值?

2024-10-03 21:27:29 发布

您现在位置:Python中文网/ 问答频道 /正文

当我将鼠标悬停在热图的某个元素上时,我想显示它的值。在

我已经让它显示热图的值,但它显示了我不想要的信息,当我第一次运行程序时,有很多错误,我不知道为什么。在

我尝试过各种方法来显示我在网上看到的值,比如datacursor(hover=True),但是{}是唯一一个“有效”的方法。在

import tkinter as tk                                                    
from tkinter import ttk
from tkinter import messagebox
import numpy as np
from math import pi
import random
import matplotlib.pyplot as plt

from mpldatacursor import datacursor
import mplcursors

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg


import pandas as pd
from openpyxl import load_workbook
from tkinter import filedialog

root = tk.Tk()                                                          
root.title("Stage 2 GUI")                                               
root.geometry("1270x590")  

mapArr = np.zeros([2,2],dtype=float)

mapArr=([113,62,31,63],
        [50,101,72,47],
        [92,10,40,12],
        [83,21,128,16])

xy=(['A','B','C','D','E','F'])


figure, axis = plt.subplots(figsize=(8,7))                              
heatmap = axis.imshow(
    mapArr,cmap="gray",interpolation='nearest',vmin=0, vmax=128)        

heatmap.axes.get_xaxis().set_visible(False)                             
heatmap.axes.get_yaxis().set_visible(False)

cb = figure.colorbar(heatmap)                                           

canvas = FigureCanvasTkAgg(figure, root)                                
canvas.get_tk_widget().place(x=-60,y=-60)                               

mplcursors.cursor(hover=True)

plt.show()

我想显示热图元素的值,而不是x和y坐标,但我不确定如何删除/自定义显示的信息,我希望它在我运行程序时没有错误(即使它在技术上是可行的)。在


Tags: fromimport程序信息元素gettkinteras
3条回答

你可以随时使用袖扣,我相信他们已经内置了这个功能:https://plot.ly/ipython-notebooks/cufflinks/

您可以连接到coursor函数,该函数将更改批注中的文本

cursor = mplcursors.cursor(hover=True)

@cursor.connect("add")
def on_mouse_move(sel):
    x = sel.target[0]
    y = sel.target[1]

    value = sel.artist.get_cursor_data(_Event(x, y))

    sel.annotation.set_text("value {} at ({:1.2f}, {:1.2f})".format(value, x,y))

要获得值,它需要namedtuple(我在Cursor的源代码中找到它)

^{pr2}$

完整的工作示例(只需要代码,所以没有错误)

import tkinter as tk                                                    
import matplotlib.pyplot as plt
import mplcursors
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

#  - data  -

mapArr = (
    [113, 62, 31, 63],
    [50, 101, 72, 47],
    [92, 10, 40, 12],
    [83, 21, 128, 16]
)

xy = ('A','B','C','D','E','F')

#  - main  -

root = tk.Tk()                                                          

figure, axis = plt.subplots(figsize=(8, 7))

canvas = FigureCanvasTkAgg(figure, root)                                
canvas.get_tk_widget().pack(fill='both', expand=True)

heatmap = axis.imshow(mapArr, cmap="gray", interpolation='nearest', vmin=0, vmax=128)        
heatmap.axes.get_xaxis().set_visible(False)                             
heatmap.axes.get_yaxis().set_visible(False)

colorbar = figure.colorbar(heatmap)                                           

# - connect function to cursor

from collections import namedtuple
_Event = namedtuple('_Event', 'xdata ydata')

cursor = mplcursors.cursor(hover=True)

@cursor.connect("add")
def on_mouse_move(sel):
    x = sel.target[0]
    y = sel.target[1]

    value = sel.artist.get_cursor_data(_Event(x, y))

    sel.annotation.set_text("value {} at ({:1.2f}, {:1.2f})".format(value, x,y))

# - 

root.mainloop()

编辑:使用@ImportanceOfBeingErnest示例,我发现了在canvas.mpl_connect()版本中我的错误在哪里,现在它起作用了。在

这个例子展示了如何使用Checkbutton来打开/关闭注释。在

import tkinter as tk                                                    
import matplotlib.pyplot as plt
import mplcursors
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

#  - data  -

mapArr = (
    [113, 62, 31, 63],
    [50, 101, 72, 47],
    [92, 10, 40, 12],
    [83, 21, 128, 16]
)

xy = ('A','B','C','D','E','F')

#  - functions  -

def on_mouse_move(event):
    if checkbuttonvariable.get() == 0:
        return

    if event.inaxes == axis:
        annotation.xy = (event.xdata, event.ydata)
        row = int(round(event.ydata))
        col = int(round(event.xdata))
        value = mapArr[row][col]
        annotation.set_text(str(value))
        annotation.set_visible(True)
    else:
        annotation.set_visible(False)
    canvas.draw()

#  - main  -

root = tk.Tk()                                                          

figure, axis = plt.subplots(figsize=(8, 7))

canvas = FigureCanvasTkAgg(figure, root)                                
canvas.get_tk_widget().pack(fill='both', expand=True)

heatmap = axis.imshow(mapArr, cmap="gray", interpolation='nearest', vmin=0, vmax=128)        
heatmap.axes.get_xaxis().set_visible(False)                             
heatmap.axes.get_yaxis().set_visible(False)

colorbar = figure.colorbar(heatmap)

#  -

annotation = axis.annotate("", xy=(0,0), xytext=(20,20), textcoords="offset points",
                    arrowprops=dict(arrowstyle="->"), visible=False,
                    bbox=dict(boxstyle="round", fc="w"))

canvas.mpl_connect('motion_notify_event', on_mouse_move)

#  -

checkbuttonvariable = tk.IntVar(value=1)
button = tk.Checkbutton(root, text='visible', variable=checkbuttonvariable)
button.pack()


root.mainloop()

您需要决定是使用pyplot还是在tk中嵌入matplotlib。下面假设您想要嵌入(在这种情况下,不要使用pyplot!!)。在

使用mplcursors

mplcursors documentation解释了如何自定义输出。本质上它包括连接到一个名为"add"的事件。在

import numpy as np
import matplotlib
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import tkinter as tk
import mplcursors

root = tk.Tk()
root.geometry("1270x590")  

mapArr=np.array(([113,62,31,63],
                 [50,101,72,47],
                 [92,10,40,12],
                 [83,21,128,16]))

xy=(['A','B','C','D','E','F'])


fig = matplotlib.figure.Figure() 
ax = fig.add_subplot()

heatmap = ax.imshow(mapArr,cmap="gray",interpolation='nearest',vmin=0, vmax=128)        

cb = fig.colorbar(heatmap)                                           

canvas = FigureCanvasTkAgg(fig, root)                                
canvas.get_tk_widget().place(x=60,y=60)                               

cursor = mplcursors.cursor(heatmap, hover=True)

@cursor.connect("add")
def on_add(sel):
    i,j = sel.target.index
    sel.annotation.set_text(mapArr[i,j])

tk.mainloop()

手动固定悬停框

您可以不使用mplcursor来执行上述操作。这可以通过创建注释并根据鼠标位置更改其位置和文本来完成。在

^{pr2}$

相关问题 更多 >