Skip to content
Andrea Cuttone edited this page Feb 25, 2017 · 8 revisions

Table of Contents

A first script

A hello world script for geoplotlib looks as follows:

import geoplotlib
thedata = geoplotlib.utils.read_csv('helloworld.csv')
geoplotlib.dot(thedata)
geoplotlib.show()

This will launch the geoplotlib window and plot the points on OpenStreetMap tiles, also allowing zooming and panning. geoplotlib automatically handles the data loading, the map projection, downloading the map tiles and the graphics rendering with OpenGL.

The geoplotlib API is inspired by the matplotlib programming model. The visualization canvas is initially empty, and each command adds a new layer of graphics. The actual rendering happens when the show method is called so the geoplotlib window is displayed.

The geoplotlib package provides several built-in visualizations:

  • dot generates a dot density map
  • markers allows to place custom markers on the map
  • hist produces a two-dimensional histogram of the data
  • kde generates a kernel density estimation for the data points. The kernel density estimation can be generated using statsmodels KDEMultivariate, or using a gaussian-smoothed histogram approximation
  • graph generates a graph connecting pairs of points
  • voronoi produces a voronoi tessellation of the data points using scipy. Optionally the voronoi cells can be shaded proportionally to their area
  • delaunay produces a delaunay triangulation of the data points using scipy. Optionally the triangulation edges can be shaded proportionally to their length
  • convexhull renders computes and renders a convex hull for the data points
  • shapefiles can read and render geographical shapes in the shapefiles format. Optionally a mouseover tooltip can be attached to each shape

Keyboard controls

  • P: take a screenshot named with the current timestamp and save it in the current python working directory
  • M: toggle base tiles map rendering
  • L: toggle layers rendering
  • I/O: zoom in/out
  • A/D: pan left/right
  • W/S: pan up/down
  • R: force invalidating all layers

Loading data

geoplotlib provides a DataAccessObject class which is the fundamental interface between the raw data and all the visualizations. A DataAccessObject is conceptually similar to a table with one column for each field and one row for each sample. This paradigm is very common in data analysis terminology, and is equivalent to ndarrays in numpy, and dataframes in pandas and R.

A DataAccessObject can be initialized by reading a comma-separated values (csv) file with the built-in read_csv method, or can be constructed from a python dict in the form {'field_name': [value1, value2, ...], ...}, or from a pandas dataframe.

The only two fields required are lat and lon corresponding to the geographic coordinates. Most of the built-in visualization implicitly refer to these two fields to locate entities in space. DataAccessObject also provides a few method for basic data wrangling, such as filtering, grouping, renaming and deleting rows and columns.

Tiles providers

By default, geoplotlib uses map tiles from CartoDB Positron, but any OpenStreetMap tile server can be configured using the tiles_provider method. A number of common free tiles providers are supported, including Stamen Watercolor, Stamen Toner, Stamen Toner Lite, CartoDB Positron and DarkMatter. Please make sure to check the tile usage policy for the server you use, and make sure to provide attribution as needed.

To change provider use the tiles_provider method and one of the following: toner, toner-lite, watercolor, positron, darkmatter, mapquest

Defining custom layers

In addition of providing built-in visualizations for the commonly used geographical data visualization, geoplotlib allows to define complex data visualizations by defining custom layers.

In order to generate a custom visualization, a new class extending BaseLayer must be defined. The custom layer must at least define an invalidate and a draw methods.

The invalidate method is called each time the map projection must be recalculated, which typically happens each time that the map zoom level changes. The invalidate method receives a Projection object, which provides methods for transforming the data points from the geographic coordinates to screen coordinates. The screen coordinates can then be passed to a BatchPainter object for the rendering. A BatchPainter allows to draw OpenGL primitives such as points, lines and polygons with high performance.

The draw method is called at each frame, and typically calls the batch_draw method of the painter prepared during invalidate. The following is a complete example of a custom layer, which simply draws samples as points:

class CustomLayer(BaseLayer):

    def __init__(self, data):
        self.data = data

	def invalidate(self, proj):
		x, y = proj.lonlat_to_screen(self.data['lon'], self.data['lat'])
		self.painter = BatchPainter()
		self.painter.points(x, y)

	def draw(self, proj, mouse_x, mouse_y, ui_manager):
		self.painter.batch_draw()

The final step needed is to add the layer to the visualization using add_layer, then call show:

geoplotlib.add_layer(CustomLayer(mydata))
geoplotlib.show()

Animation

A custom layer can be also used for creating animated visualizations. Each time the draw method is called, the custom layer can update its state to the next frame. Let us imagine to have some data containing the position of an object over time. A simple animation can use a frame counter, and at each frame render only the datapoint at the current position:

class AnimatedLayer(BaseLayer):

    def __init__(self, data):
        self.data = data
	  self.frame_counter = 0

	def invalidate(self, proj):
		self.x, self.y = proj.lonlat_to_screen(self.data['lon'], self.data['lat'])
		

	def draw(self, proj, mouse_x, mouse_y, ui_manager):
		self.painter = BatchPainter()
		self.painter.points(self.x[self.frame_counter],
					  self.y[self.frame_counter])
		self.painter.batch_draw()
		self.frame_counter += 1

Notice that in this case we do not initialize the BatchPainter inside invalidate, but we create a new one at each frame. We also keep track of the current frame with the frame_counter variable. Even this very simple code allows to visualize a non-trivial animation of an object moving over time. Screenshots can be taken using the GeoplotlibApp.screenshot method, for example to combine the individual frames into a movie.

Colormaps

Colormaps are used to convert real values to colors. Colormaps are used in some of the built-in visualizations such as histogram and kernel density, and can be used in custom layers as well. geoplotlib supports both continuous and categorical colormaps. The continuous color scales are generated from matplotlib colormaps.

The ColorMap class provides a to_color method that maps a real value to a color either in linear, log, and square root scales. Categorical colormaps can be generated using create_set_cmap and colorbrewer.

Controlling the map view

The view of the map is determined by the projection parameters: the latitude offset, the longitude offset and the zoom level. By default, the projection is chosen by fitting as close as possible all the points in the dataset.

The view can changed to a specific portion of the map by passing a BoundingBox object to the set_bbox method. A BoundingBox object defines the map view boundaries, and can be constructed in multiple ways. The most direct way is to specify two ranges of latitudes and longitudes. Alternatively, a BoundingBox can be constructed to fit a subset of points using the from_points methods. Finally, it can be also retrieved using the Nominatim reverse-geolocation webservice with the from_nominatim method.

Adding interactivity to layers

geoplotlib provides a basic support for rendering and interacting with a user interface. The draw method received a UiManager object, which allows to render on screen information.

Support for tooltips is provided by the HotspotManager class. A HotspotManager object can be initialized with screen regions connected with tooltips, which will appear on mouseover. Layers can be configured to react to specific key presses by defining a on_key_release method, which is called when a key is released. This allows to accept user input and create interactive visualizations.

API reference

Please refer to https://andrea-cuttone.github.io/geoplotlib/