Draw great-circle maps from large sets of coordinate pairs
Python
Permalink
Failed to load latest commit information.
gcmap draw lines to edge Jun 24, 2013
MANIFEST.in packaged up Jun 24, 2013
README.rst fix #1 by documenting aggdraw installatin Mar 20, 2014
example.png renamed example image Jun 24, 2013
setup.py fixed readme Jun 24, 2013

README.rst

Great Circle Maps for Python

This is a Python rewrite of the code used to create the Visualizing Facebook Friends visualization in 2010.

The original code was written in R and was built specifically around the Facebook dataset. This rewrite is as a Python module and is built to work on top of any dataset.

If you are looking to visualize a few (<10,000) coordinate pairs, matplotlib with basemap will be more flexible. The visualization implemented by this module is useful when the data alone are sufficient to show the geography.

The algorithm uses a heuristic which attempts to visualize the structure of the pairs rather than their relative importance. In interpreting the results, you should not come to any conclusions about the relative importance of different coordinate pairs.

The OpenFlights dataset visualized with gcmap (source code):

https://raw.github.com/paulgb/gcmap/master/example.png

Installation

gcmap requires the Python package `aggdraw <http://www.effbot.org/zone/aggdraw-index.htm>`__ which must first be installed manually.

Once AggDraw is installed you can install gcmap with pip:

# pip install gcmap

Usage

The module supplies two classes, GCMapper and Gradient. GCMapper is the main class for rendering great-circle maps. Gradient is used when you would like to customize the color gradient used to render the map.

GCmapper

First, import GCMapper and instantiate it:

>>> from gcmap import GCMapper
>>> gcm = GCMapper()

The GCMapper() constructor can take a number of arguments:

  • width the height of the output image
  • height the width of the output image; defaults to half the width, which fits the world completely for the default projection (equidistant cylindrical)
  • bgcol the background color as an (r, g, b) triple, eg. (255, 0, 0) for red
  • cols a Gradient object or other function from a fraction an (r, g, b) triple
  • proj the projection to use as a string, passed to pyproj. See pyproj for a list of projections
  • line_width the width of the lines draw, in pixels
  • gc_resolution the number of straight line segments used to approximate each great-circle curve

Normally you would load the coordinate pairs from a file. For this example I'll simply code in the data:

>>> lons1 = [-79.4, -73.9, -122.4, -123.1, -0.1  ]
>>> lats1 = [ 43.7,  40.7,   37.8,   49.2,  51.5 ]
>>> lons2 = lons1[1:] + lons1[:1]    # this creates a cycle through the points
>>> lats2 = lats1[1:] + lats1[:1]

The data can also be a numpy array.

Then, give the data to the GCMapper instance:

>>> gcm.set_data(lons1, lats1, lons2, lats2)

Now, we can generate the image:

>>> img = gcm.draw()

img is just a Python Image Library Image object, which we can save in any supported format:

>>> img.save('output.png')

Gradient

Gradients are instantiated with one parameter, a list of two or more gradient "stops". Stops are RGB colors located at a fractional position along the gradient. The color at any point on the gradient is a weighted blend of the stops nearest to that point in either direction.

For example, let's define a gradient from white to red to black:

>>> from gcmap import Gradient
>>> #             (stop,   red, green,  blue)
>>> g = Gradient([(   0,   255,   255,   255),
...               ( 0.4,   255,     0,     0),
...               (   1,     0,     0,     0)])

Note that red the stop is at 0.4, or four tenths of the gradient.

The gradient g now acts as a function when it is called. When it is called with a stop which was explicitly specified at construction, it returns the (r, g, b) triple at that stop:

>>> g(0)
(255, 255, 255)
>>> g(0.4)
(255, 0, 0)
>>> g(1)
(0, 0, 0)

When g is called with fractions that are not stops, it blends the nearest stops in either direction to create a new color:

>>> g(0.1)
(255, 191, 191)
>>> g(0.2)
(255, 127, 127)
>>> g(0.3)
(255, 63, 63)
>>> g(0.5)
(212, 0, 0)
>>> g(0.6)
(170, 0, 0)
>>> g(0.7)
(127, 0, 0)
>>> g(0.8)
(84, 0, 0)
>>> g(0.9)
(42, 0, 0)

License

zlib-style as follows:

Copyright (C) 2013 Paul Butler

This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.

Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution.