首页 > 解决方案 > 按下按钮时替换 Kivy 中的 DataFrame 图

问题描述

我正在编写一个 Kivy 应用程序,它将通过 kivy.garden.matplotlib.backend_kivyagg 显示 Pandas DataFrame 的图形,并在按下按钮时根据 UI 中的其他输入重新生成图形(显示不同的数据)。当我运行我的程序时,它会生成第一个图就好了。但是按下按钮并不会改变图形,即使我调用了 plt.clf(),生成了一个新的 DataFrame,并在该 DataFrame 上调用了 plot()。任何指针将不胜感激!

from kivy.garden.matplotlib.backend_kivyagg import FigureCanvasKivyAgg
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

class MyApp(App):
    def plot_random_data(self):
        df = pd.DataFrame(np.random.randint(0, 100, size=(10, 2)), columns=list('AB'))
        df.plot()

    def on_plot_button_press(self, instance):
        # TODO: This does not actually refresh graph with the new random data!
        print('Plot button pressed')
        plt.clf()
        self.plot_random_data()

    def build(self):
        box = BoxLayout(orientation='vertical')

        # The first plot of data works ...
        self.plot_random_data()

        box.add_widget(FigureCanvasKivyAgg(plt.gcf()))
        button_area = BoxLayout(size_hint=(1, 0.10))
        box.add_widget(button_area)
        btn1 = Button(text='Plot')
        btn1.bind(on_press=self.on_plot_button_press)
        button_area.add_widget(btn1)

        return box

MyApp().run()

更新:下面约翰安德森的回答使图表用新数据刷新。但是,在按下按钮 20 次后,您会收到以下错误:

 /Users/rougex/Library/Python/3.7/lib/python/site-packages/pandas/plotting/_matplotlib/core.py:320: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).
   fig = self.plt.figure(figsize=self.figsize)

我发现解决这个问题的方法是调用 plt.close(self.plot.figure),所以 on_plot_button_press 的最终工作代码是:

    def on_plot_button_press(self, instance):
        plt.close(self.plot.figure)
        self.plot_random_data()
        self.root.remove_widget(self.plot)
        self.plot = FigureCanvasKivyAgg(plt.gcf())
        self.root.add_widget(self.plot, index=1)

标签: matplotlibkivy

解决方案


似乎没有任何方法可以更改显示在FigureCanvasKivyAgg. 因此,您必须FigureCanvasKivyAgg改为替换。这是您的修改版本MyApp

class MyApp(App):
    def plot_random_data(self):
        df = pd.DataFrame(np.random.randint(0, 100, size=(10, 2)), columns=list('AB'))
        df.plot()

    def on_plot_button_press(self, instance):
        # TODO: This does not actually refresh graph with the new random data!
        print('Plot button pressed')
        plt.clf()
        self.plot_random_data()
        self.root.remove_widget(self.plot)
        self.plot = FigureCanvasKivyAgg(plt.gcf())
        self.root.add_widget(self.plot, index=1)

    def build(self):
        box = BoxLayout(orientation='vertical')

        # The first plot of data works ...
        self.plot_random_data()
        self.plot = FigureCanvasKivyAgg(plt.gcf())
        box.add_widget(self.plot)
        button_area = BoxLayout(size_hint=(1, 0.10))
        box.add_widget(button_area)
        btn1 = Button(text='Plot')
        btn1.bind(on_press=self.on_plot_button_press)
        button_area.add_widget(btn1)

        return box

build()方法保存对 的引用,用于从方法中FigureCanvasKivyAgg删除它。然后该方法创建一个新图(保存参考),创建一个新图并将其添加到. 该方法使用参数将其插入到.BoxLayouton_plot_button_press()FigureCanvasKivyAggBoxLayoutadd_widget()indexBoxLayout


推荐阅读