...now browsing by tag


A random note on programming with Gtk2Hs.

Monday, January 19th, 2009

Gtk has quite a few conventions that are entirely unintuitive and make for some very interesting bugs in your app if you’re not aware of them.  For instance, calling a redraw function inside an event handler is wrong.  You wouldn’t know that, because no-one really says it anywhere, but let’s say you have a Gtk window that holds an OpenGL scene or a Cairo scene.  If you call your render function at the end of a Gtk mouse button handler, then you stand a small chance, especially if your app is multithreaded of the whole thing coming crashing down with an unintelligible error.  Instead, you should so something like this:

mouseMotionHandler :: UIState a => MVar a -> Gtk.Event -> IO Bool
mouseMotionHandler uistate_mvar event = do
    state <- takeMVar uistate_mvar
    putMVar uistate_mvar
        $ setMousePosition (Point (Gtk.eventX event) (Gtk.eventY event)) state
    dwin <- Gtk.widgetGetDrawWindow . fromJust . drawing $ state
    Gtk.drawWindowGetPointer dwin
    Gtk.drawWindowInvalidateRect dwin (Gtk.Rectangle 0 0 (round . sizeX $ state) (round . sizeY $ state)) False
    return False

The important code here is in the next to last line, Gtk.drawWindowInvalidateRect.  This code tells the Gtk main loop that the window area in dwin is dirty and that an “expose” event needs to occur.  The sizeX and sizeY of the rectangle should be the width and height of the window.  The dwin is obtained by calling Gtk.widgetGetDrawWindow on any widget with a drawing window (this is a Window, a DrawingArea, or a GLDrawingArea). Then your expose handler will look like this:

Gtk.onExpose canvas $ evt -> renderer state scene >> return True

where renderer is the name of the function that actually draws your scene on the drawing window.  Once you’ve setup your event handlers like this, you can switch to a multithreaded app, and at least your event handlers won’t cause your program to die.

ProteinVis: Visualizing a large tree in Haskell and OpenGL

Sunday, January 18th, 2009

The following is a screenshot of ProteinVis, a tree viewer for hierarchical clusterings of proteins in the human Genome.  I did this project a while back with a colleague, Xiaojun Guan, and a professor of biology at UNC Chapel Hill, Dr William Kaufman.  Clicking on a node in the tree builds a set (actually, these are lazily computed from sets that are declared to be part of the tree at load time) of proteins that share Gene Ontology terms.

ProteinVis: A viewer for clusterings of human proteins

Click for a larger view

The basic idea is to look at the Gene Ontology terms that have been assigned to individual proteins in context of other similar proteins to see if the Gene Ontolog terms make sense in context. This was one of my first visualizations in OpenGL using Haskell, and so the code isn’t what I’d call pretty.  In any case, I’m releasing the source code here under Renci’s open source license, which is included in the source distribution.  I don’t really expect it to be of much interest, though, except to see what I did to get the visualization up and running.  These days I’m writing much better code.

ProteinVis, for win32 environments

ProteinVis, for Linux x86_64 environments

ProteinVis darcs repository

iBiblio traffic, search engine hits, and cross-traffic

Saturday, January 17th, 2009

Here’s a visualization concept I came up with a while back to look at the way search engines and word-of-mouth affects hit frequency on the iBiblio web-traffic log.  iBiblio consists of around 420 sites.   Each one of the circles you see represents one of the websites.  The size of each pie slice inside grows with respect to the number of hits by individual search engines (see the legend for which ones).  The size of the circle grows with respect to the overall number of hits by people other than search engines.  Hits are counted by number of unique incoming IP addresses per day.  Links get drawn between cliques of websites where more than 1/4th of the unique IP addresses are the same on that day, meaning, more or less, that those sites often share traffic.

This viz was developed entirely using Haskell and Cairo to crunch the weblogs and draw the data.  The total amount of data was around 10TB (yes, terabytes), and the visualization took about a day to process into a static animation.  Note that these are both size-compressed.  The original is meant to run on a wall-sized (16′x9′) or on our specialized visualization dome.  If you click on the image, you can see the original size.

A month in the life of iBiblio

A day in the life of iBiblio

A day in the life of iBiblio

Beautiful Code, Compelling Evidence

Friday, January 16th, 2009

Beautiful Code, Compelling Evidence. Purely Functional Information Visualization

This is a tutorial I presented at ICFP last year on visualization and graphics in Haskell.  It talks at length about why functional programming is a good idea for graphics, and then presents the basic tools that exist today.

I’m continuing that work right now with an interest in developing declarative systems that provide a graphics as a transformational layer from pure data.  Non basic tools that don’t yet exist today.  In other words, you don’t draw graphics based on data — the graphics are a function on the data and user interactions on the data.  Hopefully, this will lead to better, easier ways of building visualizations and will also lead to code that is directly understandable and predictable in terms of the data.