Kivy和Matplotlib试图更新按钮回调的情节

时间:2016-07-27 22:23:21

标签: python matplotlib kivy

我可以用Kivy和Matplotlib很好地生成2D曲面图。我试图在按钮单击时更新Z值。怎么可以实现呢?

我注意到我可以发出一个plt.clf()来清除绘图,但是执行plt.gcf()来显示当前的绘图并不起作用。

任何建议都会非常感激。

import matplotlib
matplotlib.use('module://kivy.garden.matplotlib.backend_kivy')
from matplotlib.figure import Figure
from numpy import arange, sin, pi
from kivy.app import App

import numpy as np
from matplotlib.mlab import griddata
from kivy.garden.matplotlib.backend_kivy import FigureCanvas,\
                                                NavigationToolbar2Kivy

# from backend_kivy import FigureCanvasKivy as FigureCanvas

from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from matplotlib.transforms import Bbox
from kivy.uix.button import Button
from kivy.graphics import Color, Line, Rectangle

import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D

fig, ax = plt.subplots()

X = np.arange(-508, 510, 203.2)
Y = np.arange(-508, 510, 203.2)
X, Y = np.meshgrid(X, Y)

Z = np.random.rand(6, 6)

plt.contourf(X, Y, Z, 100, zdir='z', offset=1.0, cmap=cm.hot)
plt.colorbar()

ax.set_ylabel('Y [mm]')
ax.set_title('NAILS surface')
ax.set_xlabel('X [mm]')

canvas = fig.canvas


def callback(instance):


    fig, ax = plt.subplots()

    X = np.arange(-508, 510, 203.2)
    Y = np.arange(-508, 510, 203.2)
    X, Y = np.meshgrid(X, Y)

    Z = np.random.rand(6, 6)

    plt.contourf(X, Y, Z, 100, zdir='z', offset=1.0, cmap=cm.hot)
    plt.colorbar()

    ax.set_ylabel('Y [mm]')
    ax.set_title('NAILS surface')
    ax.set_xlabel('X [mm]')

    canvas = fig.canvas
    canvas.draw()


class MatplotlibTest(App):
    title = 'Matplotlib Test'

    def build(self):
        fl = BoxLayout(orientation="vertical")
        a = Button(text="press me", height=40, size_hint_y=None)
        a.bind(on_press=callback)

        fl.add_widget(canvas)
        fl.add_widget(a)
        return fl

if __name__ == '__main__':
    MatplotlibTest().run()

2 个答案:

答案 0 :(得分:1)

代码的第45行:

fig, ax = plt.subplots()

创建一个新图形,从而创建一个新画布。此画布永远不会添加到BoxLayout,因此从未显示过。重新使用旧画布可能是个更好的主意。将回调函数更改为:

def callback(instance):
    # Clear the existing figure and re-use it
    plt.clf()

    X = np.arange(-508, 510, 203.2)
    Y = np.arange(-508, 510, 203.2)
    X, Y = np.meshgrid(X, Y)

    Z = np.random.rand(6, 6)

    plt.contourf(X, Y, Z, 100, zdir='z', offset=1.0, cmap=cm.hot)
    plt.colorbar()

    ax.set_ylabel('Y [mm]')
    ax.set_title('NAILS surface')
    ax.set_xlabel('X [mm]')

    canvas.draw_idle()

答案 1 :(得分:0)

需要使fig和ax变量全局化。调用plt.clf()清除当前图形并使用适当的颜色条重新绘制。

import matplotlib
matplotlib.use('module://kivy.garden.matplotlib.backend_kivy')
from matplotlib.figure import Figure
from numpy import arange, sin, pi
from kivy.app import App

import numpy as np
from matplotlib.mlab import griddata
from kivy.garden.matplotlib.backend_kivy import FigureCanvas,\
                                                NavigationToolbar2Kivy

# from backend_kivy import FigureCanvasKivy as FigureCanvas

from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from matplotlib.transforms import Bbox
from kivy.uix.button import Button
from kivy.graphics import Color, Line, Rectangle

import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D

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

X = np.arange(-508, 510, 203.2)
Y = np.arange(-508, 510, 203.2)
X, Y = np.meshgrid(X, Y)

Z = np.random.rand(6, 6)

plt.contourf(X, Y, Z, 100, zdir='z', offset=1.0, cmap=cm.hot)
plt.colorbar()

ax.set_ylabel('Y [mm]')
ax.set_title('NAILS surface')
ax.set_xlabel('X [mm]')

canvas = fig.canvas



def callback(instance):

    global fig, ax
    # fig, ax = plt.subplots()

    X = np.arange(-508, 510, 203.2)
    Y = np.arange(-508, 510, 203.2)
    X, Y = np.meshgrid(X, Y)

    Z = 1000*np.random.rand(6, 6)
    plt.clf()
    plt.contourf(X, Y, Z, 100, zdir='z', offset=1.0, cmap=cm.hot)
    plt.colorbar()

    # ax.set_ylabel('Y [mm]')
    # ax.set_title('NAILS surface')
    # ax.set_xlabel('X [mm]')

    # canvas = fig.canvas
    canvas.draw()


class MatplotlibTest(App):
    title = 'Matplotlib Test'

    def build(self):
        fl = BoxLayout(orientation="vertical")
        a = Button(text="press me", height=40, size_hint_y=None)
        a.bind(on_press=callback)

        fl.add_widget(canvas)
        fl.add_widget(a)
        return fl

if __name__ == '__main__':
    MatplotlibTest().run()