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).

main.py

"""
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()

sample.kv

#: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

Output
The first screen has an empty plot.
Opening window screenshot

The next screen is after the first click on the 'play' button.

histogram redraw screenshot

On the next click, the graph widget is redrawn.

histogram redraw2

And one more time.

histogram redraw 3

results matching ""

    No results matching ""