Mel Starrs tweeted a week or so ago about using GIS software to do mapping and energy analysis. I wanted to do the something similar but for sub-metered zones in a multi-tenanted office building.

Rather than go down the route of learning a new package, I remembered a chapter on creating choropleth maps in Nathan Yau’s fantastic Visualize This. This post walks you through the process of creating the image above and the code draws heavily on the code in the book.

Organising the data – Excel

The first step is to gather your energy data. The Python script below requires this to be in a CSV file, organised into two columns. The first column holds the names of all your zones and the second column contains the energy data you want to visualise. In the example above this is kWh/m2/yr. Just create the file in Excel and save as CSV.

Creating the base image – Inkscape

I used Inkscape (free SVG editing software) to create the outlines of the zones in the building, but you could use Illustrator or any other vector graphics editor that produces SVG files. Not having used this type of software before, this is what took the most time for me. If you want to use this technique for mapping you’ll probably be able to track down a vector graphic of the geographical areas your interested in which will save you quite a bit of time.

To create the image I imported a JPG plan of the building, knocked the opacity down, and then traced over it with the Draw Bezier curves and straight lines tool (shortcut Shift+F6). Then I named each of the zones. Right-click on the path > Object Properties > Change the Id field to match the zones name in your CSV file.

A couple of tips learned the hard way:

1) Text is really odd in this software. After you’ve typed it in, you then have to convert it to paths by selecting it and hitting Ctrl+Shift+C. If you don’t do this it will show up in a random font, if it shows up at all. Even then, it doesn’t seem to line up as well in the browser as it does in the editor.

2) It’s pretty hard to get things to line up. I just couldn’t seem to get the snapping to work. In the end I found a solution was to draw the shapes quite roughly then use the Edit path by nodes tool (shortcut F2), select a vertex or a edge, and manually enter the XY values to match up with the adjacent zone.

Data wrangling – Python

The Python module does the real work. It needs you to have Python installed and BeautifulSoup which is used to parse the XML (SVG files are a form of XML – try opening one up in a text editor to see if you haven’t done so before).

You’ll need to change one or two things. First, you’ll need to set the folder variable to the directory where you want to save the finished file. Second, you may want to change the formula which decides what colours correspond to what values.

My data had quite a lot of small values and a few larger ones so I used an exponential formula. If your data is more evenly distributed then a linear formula might work better.

Python code

The result


And that’s it. Just run the Python code, either from an IDE or from the command line, pick your CSV and SVG files when prompted, enter a name for your file and you’re done.

You can view your finished SVG file in a web browser, which means you can easily upload it and share it around.

Jamie Bull | jamiebull1@gmail.com

Related Posts

WiGLE is a popular platform which can be used for finding the location of a device using the names of WiFi networks in its vicinity. I’ve written about this before, and wrote some Python code to interact with their API. This API has since been retired and replaced with a new one, as of December […]

Just a quick post to point out a couple of really useful tools.The first is a web-based tool for finding weather files for a location of interest. It’s similar to the Excel EPW finder tool we created a few years back, but much more modern looking. It is however missing a few of the useful […]

Eppy is a really useful library which I’ve written about several times, since before I really had anything to offer in terms of contributing code. Over the past year or so though, I’ve started to contribute back some of the changes and additions I’ve made while using eppy on academic and commercial projects.This post is […]

3 Comments on “Heat maps with Python and Inkscape”

  • JuanPi says:

    Hi,
    Thanks for the post! This is useful in many ways for those using Inkscape as an aid for scientific visualization.

    I read the troubles you had and that you solved the hard way. What version of Inkscape were you using?
    – Text: Text is treated as an special object in Inkscape and the interface is the usual interface you get with text in most programs. You set font time, size, weight, etc… and you can edit it back at any time meanwhile you keep it as text. By converting it to curves you made the text a “drawing” and then it can’t be edited anymore… anyway. I hope these issues were solved in the newer version (btw, I never had this problem in Inkscape 0.47 or later under Linux)
    – Grid: Again, this may be a version problem, but if you get .48 you can even set your own grids and the snapping works perfectly (File->Document Properties->Grids, activate deactivate snapping SHIFT-5). Also, do you know you can set Guidelines where ever you want and rotate them to any angle you like? This is very useful for tracing also. To get a guideline click and drag one of the rules in the borders of your drawing screen. Again, you activate/deactivate snapping with the same key combination as before.

    Thanks again!
    I hope you keep using free software and share your discoveries with the community 😀

  • Gurpreet says:

    Is there an alternative to python and beautiful soup or is this is the only way??
    By the way, a very informative post!!… Thanks 🙂

    • Jamie Bull says:

      Hi Gurpreet, thanks for the feedback. If you prefer not to use Python you could use Java with jsoup, or pretty much any other scripting language. I find Python by far the easiest to work with though.

Leave a Reply

Your email address will not be published. Required fields are marked *