Pikir dan Rasa

cogito ergo sum

Blog Entry: Matplotlib and PyGTK app

leave a comment »


Blog Entry

Matplotlib and PyGTK app

About this tutorial

In this tutorial we will create a little application written in PyGTK and we will use Glade to create the graphical use interface (GUI). Another feature of this tutorial is that we will create a bar chart with Matplotlib. Eventually it should look like something depicted below.


final1 final2


What is PyGTK?

PyGTK provides a convenient wrapper for the GTK library for use in Python programs, and takes care of many of the boring details such as managing memory and type casting. More details here.

What is Glade?

Glade is a free user interface builder for GTK+ and GNOME, released under the GNU GPL License.
The user interfaces designed in Glade are saved as XML, and by using the libglade library these can be loaded by applications dynamically as needed.By using libglade, Glade XML files can be used in numerous programming languages including C, C++, Java, Perl, Python, C#, Pike, Ruby, Haskell, Objective Caml and Scheme. More about Glade here.

…and what about Matplotlib?

Matplotlib is a python 2D plotting library which produces publication quality figures using in a variety of hardcopy formats and interactive GUI environments across platforms. matplotlib can be used in python scripts, interactively from the python shell (ala matlab or mathematica), in web application servers generating dynamic charts, or embedded in GUI applications; see backends. More about this incredible library here.

Part One: create the GUI using Glade

Working with Glade is pretty straightforward because you use drag and drop to create a user interface. An important aspect of using PyGTK/Glade is the use of boxes, they are the containers for you widgets such as buttons, labels and list views. Thus they more or less determine the layout (and therefore the usability) of your application.
Now, create a new project in Glade and select a window from the Palette. This new window is the main window of your application, the parent. Select a notebook from the palette and drop it on the main window, the notebook book should hold 3 pages. Use the Properties window to change the amount of pages. By now you are probably aware of the enormous power of glade, it is really very intuitive to build GUI’s like this. Every page of the notebook has boxes to contain the various widgets used in our little tutorial. This is illustrated below, it is a screenshot of the Widget Tree and the Properties window.


I hope that the illustrations are self explanatory enough, though I should explain the last 7 items in the Widget Tree because we haven’t encountered them before. So what are they, I hear you ask. Well my dear friends of the Python Kingdom, these are Dialogs. Dialogs are usually detached from the main windows and used for messages like “Are you sure you want to whatever”, Yes, No, Cancel. We will use them later in this tutorial.
Another important element of Glade are Signals because they connect a user action (eg. clicked) to a callback (or function). Add a button to hbox1 as shown in the Widget Tree depicted above. After you’ve added the button (which will be named button1 by default), click on it and the Properties of button1 will pop up. Now click on the Signals tab of the Properties window and add the signal “clicked”, the handler “on_button1_clicked” is suggested by Glade, leave it as is.


Now, I believe it is time for you to explore Glade, so take a look at the XML code generated by Glade . Name it “project2.glade” if you want to use it in the next part of this tutorial.

Connect Glade to Python

Now, that’s a very nice interface but apart from being nice there is not much you can do with it and this part of the tutorial will tell you how. But first, let’s take a look at the required libraries (or modules if you prefer) to run our little app:

  • sys, to be able to use sys.exit(1) terminates Python in midflight if some requirements regarding GTK are not met
  • some functions that use a database to store and retrieve data (in this case DBStuff, it uses MySQLdb)
  • matplotlib, to create them beautiful plots
  • pygtk

The next part shows how the modules are loaded:

  1. !/usr/bin/env python  
  2. import sys  
  3. import DBStuff  
  5. import matplotlib   
  6. matplotlib.use(‘GTK’)   
  7. from matplotlib.figure import Figure   
  8. from matplotlib.axes import Subplot   
  9. from matplotlib.backends.backend_gtk import FigureCanvasGTK, NavigationToolbar   
  10. from matplotlib.numerix import arange, sin, pi   
  12. try:   
  13.     import pygtk   
  14.     pygtk.require(“2.0”)   
  15. except:   
  16.     pass   
  17. try:   
  18.     import gtk   
  19.     import gtk.glade   
  20. except:   
  21.     sys.exit(1)  

Everything apart from the DBStuff module are modules you can download and install from the internet. The DBStuff is a personal module I use for my own MySQL database and because it contains passwords and the like I will not publish it here. Hope you’ll understand… The next part is where we connect Glade’s XML file to this Python file and where you are being introduced to signals (that is signals, not singles…).

  1. class appGui:   
  2.     def __init__(self):   
  3.         gladefile = “project2.glade”   
  4.         self.windowname = “gtkbench”   
  5.         self.wTree = gtk.glade.XML(gladefile, self.windowname)   
  6.         dic = {“on_window1_destroy” : gtk.main_quit,   
  7.             “on_button1_clicked” : self.submitDB,   
  8.             “on_button3_clicked” : self.fillTree,   
  9.             “on_notebook1_switch_page” : self.selectNotebookPage,   
  10.             “on_treeview1_button_press_event” : self.clickTree,   
  11.             “on_button2_clicked” : self.createProjectGraph   
  12.             }  
  13.         self.wTree.signal_autoconnect(dic)  

The signals are put in a dictionary, the key being the handle, the value is the callback. We will look at the callbacks later in this tutorial. The line self.wTree.signal_autoconnect(dic) connects the signals to our interface.
The next part will display a Matplotlib bar chart on the first page of the notebook. Now how, you might wonder, does this bar chart know where it should be displayed? Examine the code:

  1. # setup matplotlib stuff on first notebook page (empty graph)   
  2. self.figure = Figure(figsize=(6,4), dpi=72)   
  3. self.axis = self.figure.add_subplot(111)   
  4. self.axis.set_xlabel(‘Yepper’)   
  5. self.axis.set_ylabel(‘Flabber’)   
  6. self.axis.set_title(‘An Empty Graph’)   
  7. self.axis.grid(True)   
  8. self.canvas = FigureCanvasGTK(self.figure) # a gtk.DrawingArea   
  9. self.canvas.show()   
  10. self.graphview = self.wTree.get_widget(“vbox1”)   
  11. self.graphview.pack_start(self.canvas, TrueTrue)  

The answer is in the last two lines, “vbox1” is where the bar chart will be displayed.
The next thing we want to do is setting up a listview on the second page of the notebook. A listview consists of columns and rows to store data similar to Calc and Excel. We want to do several things: fill the cells of the listview with data, click on the column header to sort the data and click on the header to create a graph. Below you will find the code to create the first column, please take a look at the link to the source code at the end of this tutorial for the next three columns.

  1. self.listview = self.wTree.get_widget(“treeview1”)   
  2. self.listmodel = gtk.ListStore(str, int, int, str, str)   
  3. self.listview.set_model(self.listmodel)   
  4. renderer = gtk.CellRendererText()   
  5. column = gtk.TreeViewColumn(“Name”,renderer, text=0)   
  6. column.set_clickable(True)   
  7. column.set_sort_column_id(0)   
  8. column.connect(“clicked”self.createDBGraph)   
  9. column.set_resizable(True)   
  10. self.listview.append_column(column)  

There are several things of interest in this code fragment. Perhaps the most interesting here is the ability to click on the header of a column (setclickable(True)) and perform a sort (setsortcolumnid) but also connect a user action (clicked) to a function (callback) that (re)displays the bar chart after a sort has been performed.
Let’s examine this callback in the next lines of code:

  1. def createDBGraph(self, widget):   
  2.     self.axis.clear()  

This clears the x and y axis when it is redrawn.

  1. self.axis.set_xlabel(‘Samples (n)’)   
  2. self.axis.set_ylabel(‘Value (-)’)   
  3. self.axis.set_title(‘Another Graph (click on the columnheader to sort)’)   
  4. self.axis.grid(True)   
  5. # get columns from listmodel   
  6. age = []   
  7. for row in self.listmodel:  
  8.     age.append(row[1])   
  9. size = []   
  10. for row in self.listmodel:   
  11.     size.append(row[2])   

The labels for the x and y axis are set (‘Samples (n)’ and ‘Value (-)’) and also the title of the graph. The data to create the bar graph is taken from the listview and stored inside a Python list (age = [], size = []).

  1. # get number of rows   
  2. N = len(age)   
  3. ind = arange(N) # the x locations for the groups   
  4. width = 0.35 # the width of the bars  

The variable N refers to the number of bars in the bar graph, this is the same as the number of rows so we use the Python len() function to retrieve the number of items in the list we created earlier.

  1. p1 = self.axis.bar(ind, age, width, color=‘b’)   
  2. p2 = self.axis.bar(ind+width, size, width, color=‘r’)   

This is where we actually create the bars that will be drawn inside the graph (p1 and p2).

  1. # destroy graph if it already exists   
  2. while True:   
  3.     try:   
  4.         self.canvas2.destroy()   
  5.         break   
  6.     except:   
  7.         print “nothing to destroy”   
  8.         break   
  9. self.canvas2 = FigureCanvasGTK(self.figure) # a gtk.DrawingArea   
  10. self.canvas2.show()   
  11. self.grahview = self.wTree.get_widget(“vbox2”)   
  12. self.grahview.pack_start(self.canvas2, TrueTrue)   

Every time the user clicks on the column header, the listview will be sorted and the plot will be destroyed and updated. We only have to destroy the plot when it already exists, that is why I use the while True … try … except … sequence here.


Posted on November 3, 2007


#1   clowersb, November 2, 2007 at 9:26 p.m.:Thanks for reposting the tutorial. Could you please post the files necessary to run the modules? Thanks.

#2   Decoy, December 4, 2008 at 2:02 p.m.:Thanks a lot for this tut!

#3   andy, April 11, 2009 at 5:06 p.m.:source files would be appreciated

#4   jyr_king, June 23, 2009 at 7:11 a.m.:A very good example, but could you offer the source codes?
or can mail to me: jyr.king@gmail.com 

Post a comment


Blandit consequat etiam–> Duis ultricies pharetra magna, donec accumsan malorci. Donec sit amet eros, sit amet. consectetuer adipiscing elit. Mauris et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio lorem ipsum dolor.–> –> Eiusmod tempor–> Incididunt ut labore–> Empor incididunt–> Dolor sit amet–> Eaque ipsa quae–> Iusmod tempor et–> Mpor incididunt ut–> Mempor incididunt–> –>

#pygtk #plot #graph

Written by sunupradana

September 1, 2011 at 12:37 pm

Posted in Komputer

Tagged with , , ,

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s

%d bloggers like this: