Как реализовать всплывающие окна с метками при наведении мыши на диаграмме matplotlib в Kivy - PullRequest
1 голос
/ 11 марта 2019

Я пытаюсь использовать matplotlib в Kivy с линейной диаграммой, которая имеет всплывающие подсказки с интерактивными метками данных, когда мышь наводится на различные точки на диаграмме.Я знаю, что это может быть сделано в matplotlib на основе этого примера: Можно ли заставить ярлыки появляться при наведении курсора на точку в matplotlib?

При использовании Kivy с matplotlib я получаю сообщение об ошибке, когдаЯ пытаюсь использовать это событие:

self.fig.canvas.mpl_connect ("motion_notify_event", hover)

ошибка: "NameError: наведение имени не определено"

import kivy
import matplotlib
matplotlib.use('module://kivy.garden.matplotlib.backend_kivy')
import matplotlib.pyplot as plt
from kivy.garden.matplotlib import FigureCanvasKivyAgg
from matplotlib.ticker import (MultipleLocator, FormatStrFormatter, 
AutoMinorLocator)
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.properties import BooleanProperty, ListProperty, StringProperty, 
ObjectProperty
from kivy.lang import Builder

class testApp(App):

    def __init__(self, **kwargs):
        super(testApp, self).__init__(**kwargs)

    def hover(event):
        # code to track the mouse position within the matplotlib chart and 
        figure out what point in the chart it is hovering over, then display 
        the popup_label defined below
        pass

    def build(self):
        mylayout = FloatLayout()
        # create the matplot lib chart and add it to the kivy float layout
        self.fig,self.ax = plt.subplots(1)
        self.plt_canvas = self.fig.canvas
        mylayout.add_widget(self.plt_canvas)

        # load x and y axis data into variables and use in chart
        year = [1960, 1970, 1980, 1990, 2000, 2010]
        pop_pakistan = [44.91, 58.09, 78.07, 107.7, 138.5, 170.6]
        pop_india = [449.48, 553.57, 696.783, 870.133, 1000.4, 1309.1]

        # set line colors
        plt.plot(year, pop_pakistan, color='g')
        plt.plot(year, pop_india, color='orange')

        # set x and y axis labels and chart title
        plt.xlabel('Countries')
        plt.ylabel('Population in million')
        plt.title('Pakistan India Population till 2010')

        # set minor ticks as a multiple of 2
        minorLocator = MultipleLocator(2)
        self.ax.xaxis.set_minor_locator(minorLocator)

        # create a test popup matplotlib chart label
        popup_label = self.ax.annotate("(1970, 45)", xy=(1970,70)) 
        popup_label.set_visible(True) #popup label works on the chart as an 
        example. this would be triggered in the def(hover) event above when 
        mouse hovers over a point..

        self.fig.canvas.mpl_connect("motion_notify_event", hover) #CODE 
        ERRORS HERE - CAN'T RECOGNIZED HOVER

        return mylayout

if __name__ == '__main__':
    testApp().run()

1 Ответ

0 голосов
/ 15 марта 2019

Я понял, как заставить всплывающие надписи показывать, когда вы наводите курсор мыши на различные точки на графике.Вот что у меня сработало:

import kivy
import time
import matplotlib
matplotlib.use('module://kivy.garden.matplotlib.backend_kivy')
import matplotlib.pyplot as plt
from kivy.garden.matplotlib import FigureCanvasKivyAgg
from matplotlib.ticker import (MultipleLocator, FormatStrFormatter, AutoMinorLocator)
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.properties import BooleanProperty, ListProperty, StringProperty, 
ObjectProperty
from kivy.core.window import Window

class testyApp(App):

    def __init__(self, **kwargs):
        super(testyApp, self).__init__(**kwargs)

    def build(self):
        global line1
        global x
        global y
        global popup_label

        # create the matplotlib chart and add it to the kivy float layout
        mylayout = FloatLayout()
        self.fig = plt.figure()
        self.ax = plt.axes()
        self.plt_canvas = self.fig.canvas
        mylayout.add_widget(self.plt_canvas)

        # load x and y axis data into variables and plot the points in the 
        chart
        xv = 0
        yv = 0
        x = []
        y = []
        for i in range(0, 31):
            xv = xv + 1
            yv = yv + 10
            x.append(xv)
            y.append(yv)
        line1, = plt.plot(x, y)

        # set x and y axis labels and chart title
        plt.xlabel('Countries')
        plt.ylabel('Population in million')
        plt.title('Pakistan Population till 2010')

        # enable mouse hover event
        self.fig.canvas.mpl_connect("motion_notify_event", self.mouse_hover)

        # create starting label and make it invisible
        popup_label = self.ax.annotate("", xy=(0, 0), xytext=(0, 0)) 
        popup_label.set_visible(False) 

        return mylayout

     def show_popup_label(self):
        # changes the coordinates and text of the popup label and makes it 
        # visible when the mouse hovers over a point on the line..
        text = "(" + str(found_x) + ", " + str(found_y) + ")"
        popup_label.set_text(text)
        popup_label.set_position((found_x, found_y))
        popup_label.set_visible(True)
        self.fig.canvas.draw()

    def hide_popup_label(self):
        # hides the popup label when the mouse is NOT on a point on the line
        popup_label.set_visible(False)
        self.fig.canvas.draw()

    def mouse_hover(self, event):
        # mouse hover event to track position of mouse on matplotlib chart 
        # and trigger show/hide popup label tasks
        global found_x
        global found_y
        xd, yd = event.xdata, event.ydata
        active, ind = line1.contains(event) # check to see if the mouse is 
        # hovering over any of the points on the line..
        if active: # if the mouse is hovering over a point on the line 
        # then..
            pos = str([ind["ind"][0]]) # fetch the array position of the 
            # point..
            pos = pos.replace("[", "")
            pos = pos.replace("]", "")
            found_x = x[int(pos)] # use the array position to figure out its 
            # x and y cordinates that we stored in the x and y lists above..
            found_y = y[int(pos)]
            self.show_popup_label() 
        else: # if the mouse is NOT hovering over a point on the line then..
            self.hide_popup_label()

if __name__ == '__main__':
    testyApp().run()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...