Search code examples
pythonpython-3.xmatplotlibkivy

Periodically update FigureCanvasKivyAgg object


I'm quite new to Kivy and I want to have an app updating a graph periodically, ie: every minute.

Using the following example:

<mainScreen>
    RewardGraph:

from kivy.garden.matplotlib.backend_kivyagg import FigureCanvasKivyAgg
import matplotlib.pyplot as plt

class RewardGraph(FigureCanvasKivyAgg):
    def __init__(self, **kwargs):
        super().__init__(plt.gcf(), **kwargs)

class AppLayout(App):
    def build(self):
        Clock.schedule_interval(lambda dt: self.PlotRewardGraph(rArray), 60)
        return mainScreen()

    def PlotRewardGraph(self, rArray):
        plt.cla()
        plt.plot(rArray, color='r')
        plt.grid(True)
        plt.gcf()

class mainScreen(GridLayout):
    pass

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

Say my rArray updates every minute and I want to plot it out. The app only shows the graph once at its starting value and stays there. For example, if the rArray is [0, -1], then the screen would show this:

enter image description here

Is there a way I could update the graph? I tried using but plt.cla() plt.clf() but nothing changes.

If the rArray increases to say [0, -1, 0.5], the graph stays the same.


Solution

  • If you add an id to your RewardGraph in your kv, you can use that to access the RewardGraph for updates:

    <mainScreen>
        cols: 1
        RewardGraph:
            id: graph
    

    Then your PlotRewardGraph() method can update the RewardGraph:

    def PlotRewardGraph(self, rArray):
        plt.cla()
        plt.plot(rArray, color='r')
        plt.grid(True)
        graph = self.root.ids.graph
        graph.figure = plt.gcf()
        graph.draw()