具有Matlibplot的Kivy ScreenManager可以绘制实时数据图

时间:2018-07-29 14:20:22

标签: python-3.x kivy matplotlib-widget

我是Python(使用3.4.2)和Kivy(v1.11.0 dev0)的新手,我正在尝试制作一个具有两个屏幕的应用程序。在一个屏幕中,用户可以设置泵设置,在下一屏幕中,用户可以查看从压力传感器记录的实时压力图。

我已经能够制作一个应用程序,其中图形可以实时显示数据,并且我已经能够制作另一个(完全独立的)应用程序,用户可以选择泵设置并切换到另一个屏幕。

我的问题是我似乎无法将两者结合到一个应用程序中。也许我的问题的一部分是我在屏幕管理器和设置应用程序中使用了奇异的语言,而不是实时图形,但是我不确定。

所以,我的问题是:有没有一种方法可以将Matplotlib kivy应用程序(在“ Graph”类下看到)集成到我的主程序中,从而获得一个应用程序,该应用程序在一个屏幕上被选择,而在另一个屏幕上被选择。该图显示了吗?

请注意:我可以从运行https://github.com/jeysonmc/kivy_matplotlib的示例中获取信息,但是我无法弄清楚如何更改代码以获取实时数据。

这是我的程序:

设置应用程序,尝试将实时图形合并到“ Graph”类中。让我知道是否应该发布文本文件。由于我还没有传感器,因此只有两列用于测试的随机数:

from kivy.garden.matplotlib.backend_kivyagg import FigureCanvasKivyAgg
from matplotlib.figure import Figure
import matplotlib as mpl
from kivy_matplotlib import MatplotFigure, MatplotNavToolbar
import matplotlib.pyplot as plt

from kivy.app import App
from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.properties import ListProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.clock import Clock
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
import numpy as np


class FirstScreen(Screen):
    pass

class PlotScreen(Screen):
    pass

class Graph(BoxLayout):

    def build(self):
        box = BoxLayout(orientation="vertical")
        a = Button(text="Go Back", height = 40, size_hint_y=None)
        self.graf = plt.gcf()
        plt.ylabel('Pressure')
        plt.xlabel('Time')
        box.add_widget(FigureCanvasKivyAgg(self.graf))
        box.add_widget(a)
        Clock.schedule_interval(self.GetData,1/25)
        return box

    def GetData(self, *args):  
        graph_data = open('Mitrample.txt','r').read()   #opens file to read data
        lines = graph_data.split('\n')
        self.x = []
        self.y = []
        for line in lines:
            if len(line) > 1:
                x_Help, y_Help = line.split(',')
                self.x.append(x_Help)
                self.y.append(y_Help)
        plt.plot(self.x,self.y)
        self.graf.canvas.draw()  #updates graph

class MyScreenManager(ScreenManager):
    pass

root_widget = Builder.load_file("two_face.kv")

class ScreenManagerApp(App):
    def build(self):
        return root_widget

ScreenManagerApp().run()

.kv文件:

#:import FadeTransition kivy.uix.screenmanager.FadeTransition

MyScreenManager:
    transition: FadeTransition()
    FirstScreen:
    PlotScreen:

<FirstScreen>:
    name: 'first'
    BoxLayout:
        orientation: 'vertical'
        padding: 5
        spacing: 5
        Label:
            text: 'Settings'
            font_size: 30
        BoxLayout:
            Label:
                text: 'Motor Speed'
                font_size: 30
            ToggleButton:
                text: 'Very Slow'
                font_size: 30
                group: "please1"
                on_release: #root.Light_Run(self.state)
            ToggleButton:
                text: 'Slow'
                font_size: 30
                group: "please1"
                on_release: #root.Light_Run(self.state)
            ToggleButton:
                text: 'Medium'
                font_size: 30
                group: "please1"
                on_release: #root.Light_Run(self.state)
            ToggleButton:
                text: 'Fast'
                font_size: 30
                group: "please1"
                on_release: #root.Light_Run(self.state)
            ToggleButton:
                text: 'Very Fast'
                font_size: 30
                group: "please1"
                on_release: #root.Light_Run(self.state)


        BoxLayout:
            Label:
                text: 'Water Pumped'
                font_size: 30

            ToggleButton:
                text: '50 mL'
                font_size: 30
                group: "please2"

            ToggleButton:
                text: '60 mL'
                font_size: 30
                group: "please2"

            ToggleButton:
                text: '70 mL'
                font_size: 30
                group: "please2"

        BoxLayout:
            Label:
                text: 'Iterations'
                font_size: 30

            ToggleButton:
                text: '1'
                font_size: 30
                group: "please3"

            ToggleButton:
                text: '5'
                font_size: 30
                group: "please3"

            ToggleButton:
                text: '10'
                font_size: 30
                group: "please3"

            ToggleButton:
                text: '30'
                font_size: 30
                group: "please3"

            ToggleButton:
                text: '50'
                font_size: 30
                group: "please3"

        BoxLayout:
            Button:
                text: 'Go to Plot'
                font_size: 30
                on_release: app.root.current = 'second'
            Button:
                text: 'Lets Pump :)'
                font_size: 30
<PlotScreen>:
    name: 'second'
    BoxLayout:
        orientation: 'vertical'
        padding: 5
        spacing: 5
        Label:
            text: 'Settings'
            font_size: 30
    Graph

1 个答案:

答案 0 :(得分:0)

我不知道,这是否对您有帮助,但是我修改了您的代码以至少从示例中看到窦性功能:

fig = mpl.figure.Figure(figsize=(2, 2))
t = np.arange(0.0, 100.0, 0.01)
s = np.sin(0.08 * np.pi * t)
axes = fig.gca()
axes.plot(t, s)
axes.set_xlim(0, 50)
axes.grid(True)


class ScreenManagerApp(App):
    def build(self):
        figure_wgt = root_widget.get_screen('second').ids['figure_wgt']
        figure_wgt.figure = fig
        return root_widget

two_face.kv中:

<PlotScreen>:
    name: 'second'
    BoxLayout:
        orientation: 'vertical'

        MatplotFigure:
            id: figure_wgt
            size_hint: 1, 0.7

        MatplotNavToolbar:
            id: navbar_wgt
            size_hint: 1, 0.3
            figure_widget: figure_wgt

这不能使您动态显示数据,但是也许您可以使用kivy.clock来更新数据。

请让我知道您如何解决您的问题。