简体   繁体   中英

Real-time plotting using matplotlib and kivy in Python

so... I've been trying to get kivy to plot data generated in real time, using matplotlib. I've used similar code to this one before in TkInter and it worked like a charm so I'm really confused why it does not work here.

Here's the code:

import numpy as np
import matplotlib
matplotlib.use('module://kivy.garden.matplotlib.backend_kivy')
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.clock import Clock
import matplotlib.pyplot as plt

class MyApp(App):
    def build(self):
        box = BoxLayout()

        self.fig,self.ax = plt.subplots(1)
        self.plt_canvas = self.fig.canvas
        box.add_widget(self.plt_canvas)

        self.line = self.ax.plot([])[0]
        self.i = 0
        plt.show()
        Clock.schedule_interval(self.update, 1)

        return box

    def update(self, *args):
        self.line.set_xdata(np.arange(self.i))
        self.line.set_ydata(np.arange(self.i))
        self.i +=1

        plt.draw()

MyApp().run()

I wanted to get it to plot the line, 1 point each second. But instead I get this:

Seems like the canvas is not redrawing. What am I doing wrong?

Potentially this has nothing to do with kivy. As can be seen the axes limits are small and outside the range where the data resides. It makes sense to update the limits once data is changed. The easiest way would be to use

self.ax.autoscale()

inside the updating function.

As suggested by @ImportanceOfBeingErnest, the axes limits need to be updated.

The following code should solve your problem:

import matplotlib
matplotlib.use('module://kivy.garden.matplotlib.backend_kivy')
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.clock import Clock
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
canvas = fig.canvas


class MyApp(App):
    def build(self):
        box = BoxLayout()
        self.i = 0
        self.line = [self.i]
        box.add_widget(canvas)
        plt.show()
        Clock.schedule_interval(self.update, 1)
        return box

    def update(self, *args):
        plt.plot(self.line, self.line)
        self.i += 1
        self.line.append(self.i)
        canvas.draw_idle()


MyApp().run()

With python-3.7 kivy-2.0.0 matplotlib-3.5.1 Marines code throws

Traceback (most recent call last): File "c:\\Users\\wiredworks\\Documents\\Simulation-Studio2\\StudioInterface\\MatplotlibUpdate.py", line 32, in MyApp().run() File "C:\\ProgramData\\Anaconda3\\envs\\NewPanda3d\\lib\\site-packages\\kivy\\app.py", line 949, in run self._run_prepare() File "C:\\ProgramData\\Anaconda3\\envs\\NewPanda3d\\lib\\site-packages\\kivy\\app.py", line 919, in _run_prepare root = self.build() File "c:\\Users\\wiredworks\\Documents\\Simulation-Studio2\\StudioInterface\\MatplotlibUpdate.py", line 21, in build plt.show() File "C:\\ProgramData\\Anaconda3\\envs\\NewPanda3d\\lib\\site-packages\\matplotlib\\pyplot.py", line 368, in show return _backend_mod.show(*args, **kwargs) File "C:\\ProgramData\\Anaconda3\\envs\\NewPanda3d\\lib\\site-packages\\matplotlib\\backend_bases.py", line 3579, in call return self.show(block=block) File "C:\\ProgramData\\Anaconda3\\envs\\NewPanda3d\\lib\\site-packages\\matplotlib\\backend_bases.py", line 3544, in show cls.mainloop() TypeError: mainloop() missing 1 required positional argument: 'self'

to solve this:

import matplotlib
matplotlib.use('module://kivy.garden.matplotlib.backend_kivy')
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.clock import Clock
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
canvas = fig.canvas
plt.plot()


class MyApp(App):
    def build(self):
        box = BoxLayout()
        self.i = 0
        self.line = [self.i]
        box.add_widget(canvas)
        Clock.schedule_interval(self.update,1)
        return box

    def update(self, *args):
        plt.plot(self.line, self.line)
        self.i += 1
        self.line.append(self.i)
        canvas.draw_idle()


MyApp().run()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM