Matplotlib redraw plots
Date: March 5th 2016
Last updated: March 5th 2016
This is my cheap and easy approach to redrawing plots using matplotlib in kivy. This example completely removes the widget and redraws everything. I imagine it is a horribly inefficient method, but it works. As this was my first success at redrawing plots, I'm taking it as a win. I'll look for alternative methods in the future. There are some additional comments inside main.py (e.g. what I tried and what failed).
""" Trialled many methods for clearing existing widget. None have worked so far.... until... I decided to cheat! In this example I have simply provided a redraw of everything which will be the most inefficient method of acheiving the desired result. It seems fast enough on my desktop, but it will most likely be slower on a phone or tablet. """ import matplotlib matplotlib.use('module://kivy.garden.matplotlib.backend_kivy') import matplotlib.pyplot as plt from kivy.garden.matplotlib.backend_kivyagg import FigureCanvas import kivy kivy.require('1.9.1') from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Button import matplotlib.mlab as mlab from random import gauss import numpy as np class DrawPlot(BoxLayout): def __init__(self, **kwargs): super(DrawPlot, self).__init__(**kwargs) def get_data(self): x = [gauss(100, 15) for i in range(100)] return x def draw_plot_frame(self): self.fig, self.ax = plt.subplots() self.ax.set_xlim([0, 200]) canvas = FigureCanvas(figure=self.fig) self.add_widget(canvas, 1) def plot(self): x = self.get_data() #self.ax.remove() # Doesnt work: first click rm widget, second click exits program #self.fig.remove() # Doesnt work: cannot remove artist #self.fig.close() #Doesnt work: figure object has no attr 'close' #self.fig.clf() #Doesnt work: clears the entire figure widget n, bins, patches = self.ax.hist(x, 50, normed=1, facecolor='white', alpha=0.3) pdf = mlab.normpdf(bins, 100, 15) self.ax.plot(bins, pdf, 'r-', linewidth=2) #self.fig.clear() #Doesnt work: clears the figure widget #self.draw_plot_frame() #Doesnt work: adds a NEW blank graph window canvas = self.fig.canvas canvas.draw() # Tried to replace the previous line with the following line #self.fig.canvas.draw() #Doesnt work: adds hist bins to existing figure def cheatmethod(self): canvas = self.fig.canvas self.remove_widget(canvas) self.draw_plot_frame() self.plot() class SampleApp(App): def build(self): return DrawPlot() if __name__ == '__main__': SampleApp().run()
#:kivy 1.9.1 <DrawPlot>: orientation: 'vertical' BoxLayout: orientation: 'vertical' size_hint: 1, None height: main_title.height Label: id: main_title text: "Plotting using Matplotlib in Kivy" font_size: '35sp' size_hint: 1, None height: self.height Label: size_hint_x: 0.8 source: root.draw_plot_frame() BoxLayout: orientation: 'horizontal' size_hint: 1, None height: playbutton.height Button: id: playbutton text: 'play' size_hint: 1, None height: self.height on_press: root.cheatmethod() #<==== redraw everything on every click!! Button: text: 'reset' size_hint: 1, None Button: text: 'quit' size_hint: 1, None
The first screen has an empty plot.
The next screen is after the first click on the 'play' button.
On the next click, the graph widget is redrawn.
And one more time.