【问题标题】:Kivy ScreenManager with Matlibplot to Graph live DataKivy ScreenManager 与 Matlibplot 绘制实时数据
【发布时间】:2018-07-29 14:20:22
【问题描述】:

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

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

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

所以,我的问题是:有没有一种方法可以将我的 Matplotlib kivy 应用程序(见下面的“图表”类)集成到我的主程序中,以获取一个应用程序,其中在一个屏幕上选择设置并在另一个屏幕上图表显示?

作为说明:我能够从 https://github.com/jeysonmc/kivy_matplotlib 运行示例,但我不知道如何更改代码以使其绘制实时数据。

这是我的程序:

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

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

【问题讨论】:

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


    【解决方案1】:

    我不知道这是否对您有帮助,但我修改了您的代码,至少可以看到示例中的 sinus 函数:

    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 来更新数据。

    请告诉我您是如何解决问题的。

    【讨论】:

    • 感谢您的帮助!我已经根据您的建议更新了我的程序,让图表显示在第二个屏幕上是一项重大改进。我有点让数据“实时”绘制,但它只在我更改窗口大小时更新图表,所以它不能完全工作。我主要使用我最初发布的“GetData”函数和 Screen ManagerApp 的构建函数中的 kivy.clock 来执行此操作。我已经尝试在代码中添加“.draw()”(有点猜测和检查),这样它会自行更新,但这只会导致更多错误。如果有帮助的话,我可以发布我的代码/我做了什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多