使用Kivy和Matplotlib绘制的图形未被绘制

inn6fuwd  于 2023-06-30  发布在  其他
关注(0)|答案(1)|浏览(181)

几天前我问了一个关于这个特定代码的问题,然而,从那以后已经做了一些修改。我试图写一个移动的应用程序,当用户按下一个按钮,他们可以查看各种真实的图形。目前,我只是在做一个简单的曲线图。问题是,每当我按下绘图按钮时,屏幕会正确转换,画布会显示出来,但实际上画布上没有绘制任何东西。它只是空的。下面是我的Python代码和.kv文件。

button_log = []


class HomeScreen(Screen):
    def button_log(self,button):

        button_text = button.text
        global button_log
        button_log.append(button_text)
        return button_text, button_log

class LinePlotScreen(Screen):
    def on_pre_enter(self):
        graph_widget = self.ids.graph_widget
        graph_widget.start_update()


class WindowManager(ScreenManager):
    pass

class GraphWidget1(BoxLayout):
    def __init__(self,**kwargs):
        super(GraphWidget1,self).__init__(**kwargs)

        self.fig , self.ax = plt.subplots()
        self.line, = self.ax.plot([],[])
        canvas = FigureCanvasKivyAgg(self.fig)
        self.add_widget(canvas)

        self.x_data = []
        self.y_data = []

        self.is_running = False

    def start_update(self):
        if not self.is_running:
            self.is_running = True
            #self.thread = threading.Thread(target=self.update_graph)
            #self.thread.daemon = True
            #self.thread.start()
            #Clock.schedule_interval(self.update_graph, 0.1)
            Clock.schedule_once(self.update_graph)

    def stop_update(self):
        if self.is_running():
            self.is_running = False

    def update_graph(self, dt):
        x = np.linspace(0,10,100)
        y = np.sin(x)

        self.x_data.append(x)
        self.y_data.append(y)
        #self.ax.cla()

        self.line.set_data(self.x_data,self.y_data)
        self.ax.relim()
        self.ax.autoscale_view(True,True,True)
        self.canvas.draw

        if self.is_running:
            Clock.schedule_once(self.update_graph, 0.1)

kv = Builder.load_file('Simplified.kv')
class TestApp(App):

    def build(self):

        self.stop_value = 0
        self.data_int = None
        self.left_shoe = []
        self.right_shoe = []

        return kv

    def on_button_press(self):
        global button_log
        if button_log[-1] == 'Start Data Collection':
            UDP_IP = "192.168.1.100"
            UDP_PORT = 3333
            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            sock.bind((socket.gethostname(), UDP_PORT))

            def collect_data(dt):
                nonlocal sock
                nonlocal self
                global button_log

                data, addr = sock.recvfrom(1024)
                self.data_int = fmt_str(data)
                if self.data_int[0] == 1:
                    self.left_shoe.append(self.data_int)
                elif self.data_int[0] == 2:
                    self.right_shoe.append(self.data_int)
                if self.stop_value == 1:
                    Clock.unschedule(collect_data)

            Clock.schedule_interval(collect_data, 0.1)

        elif button_log[-1] == 'Stop Data Collection':
            self.stop_value = 1
        elif button_log[-1] == 'Plot Line Charts':

            self.root.current = 'lineplot'
            line_plot_screen = self.root.get_screen('lineplot')
            graph_widget = line_plot_screen.ids.graph_widget

Simplified.kv

WindowManager:
    HomeScreen:
    LinePlotScreen:

<HomeScreen>:
    name: 'home'
    BoxLayout:
        orientation: 'vertical'
        size: root.width,root.height

        Label:
            text: 'Home'
            font_size: 32

        Button:
            id: Start
            text: 'Start Data Collection'
            font_size: 32
            pos_hint: {'center_x':0.5}
            size_hint: (0.5,1)
            valign: 'center'
            on_press: root.button_log(self)
            on_release: app.on_button_press()

        Button:
            id: Stop
            text: 'Stop Data Collection'
            font_size: 32
            pos_hint: {'center_x':0.5}
            size_hint: (0.5,1)
            valign: 'center'
            on_press: root.button_log(self)
            on_release: app.on_button_press()

        Button:
            id: plot_line
            text: 'Plot Line Charts'
            font_size: 32
            pos_hint: {'center_x':0.5}
            size_hint: (0.5,1)
            valign: 'center'
            on_press:
                root.button_log(self)
                app.on_button_press()

<LinePlotScreen>:
    name: 'lineplot'
    BoxLayout:
        id: box
        orientation: 'vertical'
        size: root.width,root.height

        Label:
            text: 'Line Graphs'
            font_size: 32

        GraphWidget1:
            id: graph_widget

我有问题之前,试图只是过渡屏幕,并有数字显示。现在,我正在处理的问题,过渡屏幕成功,但数字不绘图。我认为问题可能是'self.canv.draw'线,但我不完全确定。我试着在那一行的末尾添加括号,使其成为一个函数调用,但当按下绘图按钮时,这只会导致窗口崩溃。我试着查看其他StackOverflow问题,但无法真正找到适合我情况的问题。任何帮助将不胜感激,谢谢。

c8ib6hqw

c8ib6hqw1#

您需要调用pyplotplot()方法以绘制新数据,并且必须将FigureCanvasKivyAggfigure属性设置为当前更新的图。
一种方法是保存对FigureCanvasKivyAgg的引用:

class GraphWidget1(BoxLayout):
    def __init__(self,**kwargs):
        super(GraphWidget1,self).__init__(**kwargs)

        self.fig , self.ax = plt.subplots()
        self.line, = self.ax.plot([],[])
        self.plot = FigureCanvasKivyAgg(self.fig)
        self.add_widget(self.plot)

        self.x_data = []
        self.y_data = []

        self.is_running = False

update_graph()中:

def update_graph(self, dt):
    plt.cla()
    x = np.linspace(0, 10, 100)
    y = np.sin(x)
    plt.plot(x, y)
    plt.grid(True)
    self.plot.figure = plt.gcf()
    self.plot.draw()

相关问题