我们可以在Kivy中使用matplotlib.animation吗?如果是,如何?

时间:2018-12-18 10:26:58

标签: python animation matplotlib kivy

这个How to use matplotlib animation within kivy问题很相似,但是答案根本没有价值 另外,正如@ImportanceOfBeingErnest指出的那样,我将问题编辑为“我们可以实际执行吗?如果是,请继续进行以下操作。

因此,根据以下教程Sentdex tutorial on how to add matplotlib animation in tkinter

,可以在tkinter中轻松添加动画。

我试图用奇异果做同样的事情,但无法弄清楚在哪里写ani=animation.Funcanimation(blabla)行,请参见以下代码的最后一行

class Graph(FigureCanvasKivyAgg):
    def __init__(self,*args,**kwargs):
        FigureCanvasKivyAgg.__init__(self,f)
        pullData = open("TimeLatitude.txt", "r").read()
        dataList = pullData.split('\n')
        xList = []
        yList = []
        pullData2 = open("TimeLongitude.txt", "r").read()
        dataList2 = pullData2.split('\n')
        xList2 = []
        yList2 = []
        for eachLine in dataList:
            if len(eachLine) > 1:
                x, y = eachLine.split(',')
                xList.append(int(x))
                yList.append(int(y))
        for eachLine in dataList2:
            if len(eachLine) > 1:
                x, y = eachLine.split(',')
                xList2.append(int(x))
                yList2.append(int(y))
        a.clear()
        a.plot(xList, yList, "#00A3E0", label="Latitude")
        a.plot(xList2, yList2, "#183A54", label="Longitude")
        a.legend(bbox_to_anchor=(0, 1.02, 1, .102), loc=3,
                 ncol=2, borderaxespad=0)
        title = "Oxymora Mars Rover Geographic Points\nLast Longitude : " + str(
            yList2[len(yList2) - 1]) + "\nLast Latitude : " + str(yList[len(yList) - 1])
        a.set_title(title)
        ani = animation.FuncAnimation(f, animate, interval=1000)

2 个答案:

答案 0 :(得分:0)

我认为当今人们很少使用kivy。没人回答。所以我以某种方式想出了我想要实现的目标的替代方案。 我添加了一个“刷新”按钮,该按钮再次运行整个功能,其中包括从文件中获取值并再次绘制图形。因此,只要文件中的值更新,我们都会得到相应的图。

这是python 3代码。

class Graph(FigureCanvasKivyAgg):
    def __init__(self,*args,**kwargs):
        FigureCanvasKivyAgg.__init__(self,f)
        pullData = open("TimeLatitude.txt", "r").read()
        dataList = pullData.split('\n')
        xList = []
        yList = []
        pullData2 = open("TimeLongitude.txt", "r").read()
        dataList2 = pullData2.split('\n')
        xList2 = []
        yList2 = []
        for eachLine in dataList:
            if len(eachLine) > 1:
                x, y = eachLine.split(',')
                xList.append(int(x))
                yList.append(int(y))
        for eachLine in dataList2:
            if len(eachLine) > 1:
                x, y = eachLine.split(',')
                xList2.append(int(x))
                yList2.append(int(y))
        a.plot(xList, yList, "#00A3E0", label="Latitude")
        a.plot(xList2, yList2, "#183A54", label="Longitude")
        a.legend(bbox_to_anchor=(0, 1.02, 1, .102), loc=3,
             ncol=2, borderaxespad=0)
        title = "Oxymora Mars Rover Coordinates\nLast Longitude : " + str(
            yList2[len(yList2) - 1]) + "\nLast Latitude : " + str(yList[len(yList) - 1])
        a.set_title(title)
    def animate(self):
        pullData = open("TimeLatitude.txt", "r").read()
        dataList = pullData.split('\n')
        xList = []
        yList = []
        pullData2 = open("TimeLongitude.txt", "r").read()
        dataList2 = pullData2.split('\n')
        xList2 = []
        yList2 = []
        for eachLine in dataList:
            if len(eachLine) > 1:
                x, y = eachLine.split(',')
                xList.append(int(x))
                yList.append(int(y))
        for eachLine in dataList2:
            if len(eachLine) > 1:
                x, y = eachLine.split(',')
                xList2.append(int(x))
                yList2.append(int(y))
        a.clear()
        a.plot(xList, yList, "#00A3E0", label="Latitude")
        a.plot(xList2, yList2, "#183A54", label="Longitude")
        a.legend(bbox_to_anchor=(0, 1.02, 1, .102), loc=3,
                 ncol=2, borderaxespad=0)
        title = "Oxymora Mars Rover Coordinates\nLast Longitude : " + str(
            yList2[len(yList2) - 1]) + "\nLast Latitude : " + str(yList[len(yList) - 1])
        a.set_title(title)
        self.draw()

,这是相应的猕猴桃代码。

<MainScreen>:
    name: "main"
    FloatLayout:
        Graph
            id:gr
        Button:
            on_release: gr.animate()
            text: "Refresh"
            font_size: 15
            size_hint:0.068,0.05
            pos_hint: {"x":0,"top":0.8}
            color: 1,0,1,1

所以最后,在运行完我完整的代码之后,kivy应用程序看起来像这样- Kivy application image

答案 1 :(得分:0)

好的。。所以我知道已经晚了一年,但是我解决了我的实时图形绘制问题。在我看来,Matplotlib的FuncAnimation()方法不适用于FigureCanvasKivyAgg。

相反,您必须使用Kivy的Clock.schedule_interval()方法,然后在它调用的方法中使用一行来重画画布。像这样: self.fig.canvas.draw()

它不够快,无法进行适当的实时音频处理。但是对于大多数典型的图形用途,它是可用的。

这是一个例子:

import queue
from matplotlib.animation import FuncAnimation
import matplotlib.pyplot as plt
import numpy as np
from kivy.clock import Clock

class PlotInputStream():

    def __init__(self, queue):
        self.q = queue
        self.length = int((2048*2) * 44100 / (1000 * 10))
        self.plotdata = np.zeros((self.length, 1))
        self.fig, self.ax = plt.subplots()
        self.lineColour = 'blue'
        self.lines = self.ax.plot(self.plotdata, color=self.lineColour)
        # self.ani = FuncAnimation(self.fig, self.update_plot, interval=10, blit=False)
        Clock.schedule_interval(self.update_plot, 1 / 60.)

    def update_plot(self, frame):
        while True:
            try:
                data = self.q.get_nowait()
            except queue.Empty:
                break
            shift = len(data)
            self.plotdata = np.roll(self.plotdata, -shift, axis=0)
            self.plotdata[-shift:, :] = data
        for column, line in enumerate(self.lines):
            line.set_ydata(self.plotdata[:, column])
        self.fig.canvas.draw()
        return self.lines

我正在绘制音频数据,但是您应该能够采用相同的原理并绘制任何内容。需要注意的是,以上是在我的Kivy应用程序的build方法中实例化的类。然后,我使用以下方法将实例输入到Screen实例中:

self.figurecanvas = FigureCanvasKivyAgg(self.figure)
self.boxlayout_01.add_widget(self.figurecanvas)

这足以让您在Kivy应用程序中更新Pyplot图,而不必依赖Matplotlib的默认图形窗口。