Generate charts in Python with Google Charts API

02Jun10

As you may know, I am working in DeTraS Data Analyzer (also called Dazer). This web application, which is being written in Python using Django Framework, will allow you to view data tracked by DeTraS in a graphical way. I have chosen Google Charts API to show charts in Dazer because it is a powerful tool and it’s quite easy to use.

Google Charts is an API that gets an URL with a series of parameters and returns an image containing a graphic (usually a chart). In order to use this API in Python, you can manipulate Google Charts URLs by your own or you can use a wrapper that makes this work easier and more scalable. I have decided to use pygooglechart for this purpose.

Let’s see how to generate a chart with an example used in Dazer. This graphic is used to generate a chart showing most used applications by its usage time. Please notice that this is not the final version included in Dazer, but it’s almost equal.

In first place, you have to get data from a database or a file and store it in a suitable data structure. As you can see bellow, I saved data needed for this chart in a list of tuples called sdata.

win_etype = EventType.objects.get(name__iexact='window')
cursor = connection.cursor()
data = {}

cursor.execute( \
        "select ew.application, e.duration from events e, " + \
        "eventwindow ew where e.event_type = %s and " + \
        "ew.id = e.event and e.duration is not null and " + \
        "e.timestamp >= %s and e.timestamp <= %s " + \
        "order by e.duration", \
        [win_etype.id, idate, fdate])

for i in cursor.fetchall():
    app = i[0]
    duration = float(i[1])
    if app in data.keys():
        data[app] = data[app] + (duration / SECTOHOURS)
    else:
        data[app] = duration / SECTOHOURS

sdata = sorted(data.iteritems(), key=itemgetter(1), \
        reverse=True)[:numres]

Once we have the data, it’s time to generate the chart. As you can see, the following function gets the data taken from the database and the number of results the user want to view (up to 25).

def top_applications_by_time(sdata, numres):
    numelems = len(sdata)

    if numelems != numres:
        numres = numelems

    # Calculates the maximum x value I want to paint
    max_x = range(0, sdata[0][1] + 50, 50)[-1]

    # You can notice that chart height will depend on number of
    # results
    chart = GroupedHorizontalBarChart(600, \
            int(math.log(numres)*155),
            title='Top %s applications (by usage time)' % numres, \
            x_range=[0, max_x])

    xdata = [] # Stores number of hours
    ydata = [] # Stores applications names

    for i in sdata:
        ydata.insert(0, i[0])
        xdata.append(i[1])

    chart.add_data(xdata)

    # X-axis will have a step every 50 hours
    bottom_axis = range(0, max_x + 1, 50)
    chart.set_axis_labels(Axis.BOTTOM, bottom_axis)

    # Paint applications names on Y-axis
    chart.set_axis_labels(Axis.LEFT, ydata)

    # Paint a guide every 25 hours
    chart.set_grid((100*25)/float(max_x), 0, 2, 5)

    # Make smaller bar width if we have too many results
    if numres > 10:
        chart.set_bar_width(10)

    # It's important to indicate which data class we are using!
    return chart.get_url(data_class=TextData)

This is a screenshot of the chart result of the previous code:

Top applications by usage time

Top applications by usage time

And this is Google Chart URL generated URL:

http://chart.apis.google.com/chart?cht=bhg&chs=600×356&chd=t:75.1,71.9,52.1,38.6,20.5,9.5,5.7,4.8,3.5,2.2&chtt=Top%2010%20applications%20%28by%20usage%20time%29&chco=FFCC33&chxt=x,y&chxl=0:|0|50|1:|OpenOffice.org%203.0|Gedit|Emacs|VirtualBox|Gnome-terminal|Evince|Terminator|Chromium-browser|Google-chrome|Evolution&chg=50.0,0,2,5



No Responses Yet to “Generate charts in Python with Google Charts API”

  1. Leave a Comment

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


%d bloggers like this: