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

时间:2019-07-19 11:16:37

标签: python matplotlib tkinter

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

我可以显示热图的值,但它也显示我不想要的信息,当我第一次运行该程序时,有很多错误,我无法弄清楚为什么。

我尝试了多种显示在线上看到的值的方法,例如datacursor(hover=True),但是mplcursors.cursor(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()

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

3 个答案:

答案 0 :(得分:1)

您需要确定是要使用pyplot还是将matplotlib嵌入到tk中。以下假设您要嵌入(在这种情况下,请不要使用pyplot !!)。

使用放大器

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()

手动创建悬停框

您可以执行上述操作,而无需使用放大器。这可以通过创建注释并根据鼠标位置更改其位置和文本来完成。

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

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)                               

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

def hover(event):
    if event.inaxes == ax:
        x,y = event.xdata, event.ydata
        j,i = np.round(np.array((x,y))).astype(int)
        annot.xy = (x,y)
        annot.set_text(str(mapArr[i,j]))
        annot.set_visible(True)
    else:
        annot.set_visible(False)
    fig.canvas.draw_idle()

canvas.mpl_connect("motion_notify_event", hover)

tk.mainloop()

答案 1 :(得分:0)

您可以连接到Mockito.doNothing().when(AmazonS3ClientBuilder.standard());功能,该功能将更改注释中的文本

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)) (我在Cursor的源代码中找到了它)

namedtuple

完整的示例(仅需要代码,因此没有错误)

from collections import namedtuple

_Event = namedtuple('_Event', 'xdata ydata')

编辑:使用@ImportanceOfBeingErnest示例,我发现在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() 版本中我的错误在哪里,现在可以正常工作。

此示例显示了如何使用canvas.mpl_connect()打开/关闭注释。

Checkbutton

答案 2 :(得分:-1)

您始终可以使用袖扣并进行绘图,我相信它们已经内置了以下功能:https://plot.ly/ipython-notebooks/cufflinks/