01
Apr
07

Plotting with MatPlotLib, PyGTK and Glade

The matplotlib is a plotting library for python which uses a syntax based on matlab. It is quite powerful: there are a large sets of 2D and 3D graphs available, it suports most of windowing toolkits (GTK, Tkinter, Qt, and wxWindows) for embedded GUI applications as well as interfacing with the python shell (see IPython).

See other python plotting solutions and compare.
http://wiki.python.org/moin/NumericAndScientific/Plotting

Bellow we describe an example of embedded PyGTK with Glade application that uses matplotlib. It just draws a barchart graph. The code is based on the matplotlib examples, serpia pygtk tutorial and matplotlib cookbook.

#!/usr/bin/env python
# Licence: GPLv2.0

import sys

import pygtk
pygtk.require("2.0")

import matplotlib
matplotlib.use('GTK')

import gtk
import gtk.glade

from matplotlib.figure import *
from matplotlib.axes import *
from matplotlib.backends.backend_gtk import *
from pylab import *

class app:
    target = ""
    def __init__(self):
        self.init_app()

    def init_app(self):
        gladefile = "plot.glade"
        windowname = "win"
        self.wTree = gtk.glade.XML (gladefile,windowname)
        dic = { "on_btn_draw_clicked" : self.draw }
        self.wTree.signal_autoconnect(dic)

        self.figure = Figure(figsize=(6,4), dpi=60)
        self.axis = self.figure.add_subplot(111)

        self.axis.set_xlabel('X')
        self.axis.set_ylabel('Y')
        self.axis.set_title('Graph')
        self.axis.grid(True)

        self.canvas = FigureCanvasGTK(self.figure)
        self.canvas.show()
        self.graphview = self.wTree.get_widget("vbox")
        self.graphview.pack_start(self.canvas, True, True)  

    def draw(self, widget):
        while True:
            try:
                a1 = self.wTree.get_widget("entry_a1").get_text()
                b1 = self.wTree.get_widget("entry_b1").get_text()
                a2 = self.wTree.get_widget("entry_a2").get_text()
                b2 = self.wTree.get_widget("entry_b2").get_text()
                a3 = self.wTree.get_widget("entry_a3").get_text()
                b3 = self.wTree.get_widget("entry_b3").get_text()                       

                a = (int(a1), int(a2), int(a3))
                b = (int(b1), int(b2), int(b3))
                ind = arange(3)  # groups
                width = 0.15 

                ga = self.axis.bar(ind, a, width, color='r')
                gb = self.axis.bar(ind+width, b, width, color='b')

                self.axis.legend((ga[0], gb[0]), ("A", "B"), shadow = True)
                self.axis.set_xlim(-width,len(ind))

                self.canvas.destroy()
                self.canvas = FigureCanvasGTK(self.figure)
                self.canvas.show()
                self.grahview = self.wTree.get_widget("vbox")
                self.grahview.pack_start(self.canvas, True, True)
                break

            except ValueError:
                print "Error: ", ValueError
                break
        return

app = app()
gtk.main()

And the “plog.glade” xml file.

<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">

<glade-interface>

<widget class="GtkWindow" id="win">
<property name="visible">True</property>
<property name="title" translatable="yes">Plot</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="default_width">600</property>
<property name="default_height">400</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>

<child>
<widget class="GtkVBox" id="vbox">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>

<child>
<widget class="GtkFrame" id="frame1">
<property name="width_request">246</property>
<property name="height_request">100</property>
<property name="visible">True</property>
<property name="label_xalign">0.00999999977648</property>
<property name="label_yalign">0</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>

<child>
<widget class="GtkAlignment" id="alignment1">
<property name="width_request">232</property>
<property name="height_request">20</property>
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">1</property>
<property name="yscale">1</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">12</property>
<property name="right_padding">0</property>

<child>
<widget class="GtkTable" id="table1">
<property name="border_width">5</property>
<property name="width_request">220</property>
<property name="height_request">10</property>
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">5</property>
<property name="homogeneous">False</property>
<property name="row_spacing">5</property>
<property name="column_spacing">5</property>

<child>
<widget class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="label" translatable="yes">  A</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>

<child>
<widget class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="label" translatable="yes">  B</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>

<child>
<widget class="GtkEntry" id="entry_a1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="y_options"></property>
</packing>
</child>

<child>
<widget class="GtkEntry" id="entry_b1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>

<child>
<widget class="GtkEntry" id="entry_a2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="y_options"></property>
</packing>
</child>

<child>
<widget class="GtkEntry" id="entry_b2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>

<child>
<widget class="GtkButton" id="btn_draw">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes"> Draw </property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_btn_draw_clicked"/>
</widget>
<packing>
<property name="left_attach">4</property>
<property name="right_attach">5</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>

<child>
<widget class="GtkEntry" id="entry_a3">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="y_options"></property>
</packing>
</child>

<child>
<widget class="GtkEntry" id="entry_b3">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
</child>
</widget>
</child>

<child>
<widget class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>

<child>
<placeholder/>
</child>
</widget>
</child>
</widget>

</glade-interface>

Another solution is to save the graph to a file and load it into a “GtkImage” object. I’ve done that and It sounds a good idea when you really want to separate GUI stuffs from code. Anyone have a better idea?

Advertisements

5 Responses to “Plotting with MatPlotLib, PyGTK and Glade”


  1. 1 Jose Luis
    September 6, 2009 at 18:16

    Thanks. I was looking this example on the internet to make a calculator in python. Good Post.

    Lima Peru

  2. 2 hamilyon
    November 2, 2009 at 09:46

    I was looking for exactly this kind of example. Domo Arigato.

  3. 3 Lou
    August 17, 2014 at 12:55

    Spot on with this write-up, I seriously feel this site needs a great deal more
    attention. I’ll probably be returning to read more, thanks for the advice!

  4. December 29, 2016 at 01:07

    Excellent post. I’m going through many of these issues as well..


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Quotes

"Don't worry about what anybody else is going to do. The best way to predict the future is to invent it. Really smart people with reasonable funding can do just about anything that doesn't violate too many of Newton's Laws!" -- Alan Kay in 1971

My Twitter

Error: Twitter did not respond. Please wait a few minutes and refresh this page.

My Delicious

RSS My Shared RSS

  • An error has occurred; the feed is probably down. Try again later.

Blog Stats

  • 73,640 hits

%d bloggers like this: