[英]Kivy: update matplotlib canvas with a slider
我需要创建一个更新matplotlib图形的滑块。 到目前为止,我有这个main.py:
from kivy.app import App
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
import numpy as np
import matplotlib.pyplot as plt
from kivy.garden.matplotlib.backend_kivyagg import FigureCanvasKivyAgg
class Container(BoxLayout):
display = ObjectProperty()
def __init__(self, *args, **kwargs):
global canvas
super(Container, self).__init__(**kwargs)
lum_img = np.random.rand(10,10)
plt.imshow(lum_img, cmap="gray")
plt.colorbar()
canvas = FigureCanvasKivyAgg(plt.gcf())
self.ids.box_display.add_widget(canvas)
canvas.draw()
def add_one(self, value):
lum_img = np.random.rand(10,10)
plt.imshow(lum_img, cmap="gray")
plt.colorbar()
canvas.draw()
self.display.text = str(round(value,2))
class MainApp(App):
def build(self):
self.title = 'Image and slider app'
return Container()
if __name__ == "__main__":
app = MainApp()
app.run()
和main.kv:
<Container>:
display: display
id: main_display
orientation: "vertical"
BoxLayout:
id: box_display
orientation: "vertical"
Slider:
id: slider_image
min: 0
max: 1
value: 0.5
on_value: root.add_one(value = slider_image.value)
Label:
id: display
font_size: dp(50)
text: '0'
该行为不符合预期,它只是移动图像而不是更新图像画布! 我认为错误是将画布声明为全局变量,但不执行此操作我不知道如何更新它。
任何想法?
您的代码实际上是在创建新的图,但是它们的位置不正确并且彼此重叠。 解决该问题的一种方法是使用plt.subplot()
。 这需要预先知道要添加多少个子图。 这是使用此方法的代码的修改版本(为方便起见,我将.kv
作为字符串包含在内):
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
import numpy as np
import matplotlib.pyplot as plt
from kivy.garden.matplotlib.backend_kivyagg import FigureCanvasKivyAgg
Builder.load_string('''
<Container>:
display: display
id: main_display
orientation: "vertical"
BoxLayout:
id: box_display
orientation: "vertical"
Slider:
id: slider_image
min: 0
max: 1
value: 0.0
on_value: root.add_one(value = slider_image.value)
Label:
id: display
font_size: dp(50)
text: '0'
''')
class Container(BoxLayout):
display = ObjectProperty()
def __init__(self, *args, **kwargs):
global canvas
super(Container, self).__init__(**kwargs)
self.index = 1 # index of the current plot
self.max_plots = 5 # maximum number of subplots
self.old_slider_value = 0.0 # starting value of the slider
lum_img = np.random.rand(10,10)
plt.subplot(1, self.max_plots, self.index) # create the first subplot
plt.imshow(lum_img, cmap="gray")
plt.colorbar()
canvas = FigureCanvasKivyAgg(plt.gcf())
self.ids.box_display.add_widget(canvas)
canvas.draw()
def add_one(self, value):
# only make a new subplot if the slider has moved at least 0.2
if (value - self.old_slider_value) > 1.0/self.max_plots and self.index < self.max_plots:
self.old_slider_value = value
self.index += 1
plt.subplot(1, self.max_plots, self.index) # make new subplot
lum_img = np.random.rand(10,10)
plt.imshow(lum_img, cmap="gray")
plt.colorbar()
plt.tight_layout() # arrange the subplots a bit to eliminate overlaps
canvas.draw()
self.display.text = str(round(value,2))
class MainApp(App):
def build(self):
self.title = 'Image and slider app'
return Container()
if __name__ == "__main__":
app = MainApp()
app.run()
误解了您想要的东西(我的错误)。 如果您不想创建新的绘图,而只是更新现有的绘图,则只需在执行其他绘图之前在add_one()
方法中添加对plt.clf()
的调用即可。 这将清除当前图形,并允许您将其替换为新图形。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.