Matplotlib using kv language
Date: March 4th 2016
Last updated: March 4th 2016
Using the kv language to include a plot inside a widget was an absolute nightmare. It has taken me a number of days to get working. I had a breakthrough when I read this: https://mail.python.org/pipermail//matplotlib-users/2015-November/000168.html. The missing ingredient for me to convert my previous example to kv language was this: self.add_widget(canvas). In my original example, I included add_widget(canvas) in the build function. I was confused how I was going to translate this code into syntax that could be understood by the kv language. There is more information in main.py regarding this syntax.
# Import modules 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 draw_my_plot(self): fig, ax = plt.subplots() x = [gauss(100, 15) for i in range(100)] n, bins, patches = ax.hist(x, 50, normed=1, facecolor='white', alpha=0.3) pdf = mlab.normpdf(bins, 100, 15) ax.plot(bins, pdf, 'r-', linewidth=2) ax.set_xlim([0, 200]) canvas = FigureCanvas(figure=fig) # The '1' specifies the index position of the widget # I had issues with the positioning using kv language # This widget wouldnt adhere to the widget tree # That is, the figure would always come last! # Specifying index as 1 sets the position of this widget # in second place of a boxlayout with vertical orientation. self.add_widget(canvas, 1) class SampleApp(App): def build(self): return DrawPlot() if __name__ == '__main__': SampleApp().run()
There is only one line here that calls the plotting function. I could have used an Image widget instead of Label. They both give the same result.
#: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: source: root.draw_my_plot() BoxLayout: orientation: 'horizontal' size_hint: 1, None height: playbutton.height Button: id: playbutton text: 'play' size_hint: 1, None height: self.height Button: text: 'reset' size_hint: 1, None Button: text: 'quit' size_hint: 1, None