Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Visualisation

Authors
Affiliations
TU Wien
TU Wien
TU Wien
Binder

This notebook presents useful Python libraries for geospatial visualisation. We use OSM intersection features and GTFS stop features for the same Vienna area, but we keep them on separate maps and charts. Overlaying both sources on one figure hides patterns in each dataset.

Why visualisation matters

Visualisation is not only useful for presenting final results, but also for validating and debugging spatial data throughout the whole processing pipeline. Interactive maps might help identify errors like incorrect coordinate reference systems (CRS), missing or duplicated geometries, outliers or gaps in coverage.

Therefore, by visually inspecting data often and early, many processing errors can be detected before expensive analysis steps are performed. This makes visualisation a powerful tool that should not be neglected.

Imports and Configuration

Now we load the two feature tables from earlier notebooks. intersections.csv is one point per OSM intersection (with type, number of arms, and delta). gtfs_stops.csv is one point per transit stop in the Vienna GTFS sample (with trip counts and a primary mode). Later cells plot each table on its own map or chart.

Loaded 8155 OSM intersections and 395 GTFS stops

Folium

What is Folium?

Folium is a Python library that makes it easy to visualise data on an interactive Leaflet.js map. It allows us to take our spatial Python data and plot it directly on the map as markers, heatmaps, or choropleth grids. Unlike static plots, Folium maps are interactive, allowing users to zoom, pan, and toggle layers to explore complex spatial relationships in detail. Because Folium is built on top of Leaflet.js, maps can also easily be exported as standalone HTML files and shared easily.

There are multiple different tile providers for Folium available (think of it as the background map), like OpenStreetMap or CartoDB. For the visualisations in this cookbook, we have been using “CartoDB positron” tiles because they are simple and minimalist in style and therefore don’t distract visually from the data we’ve been plotting while still giving that visual spatial reference. CARTO requires CARTO_API_KEY on those tile requests; get_base_map reads it from the environment or from .env. For other applications and use-cases, different tiles might be better suited or preferable.

OSM intersections

This map shows points, not streets.

  • Each marker is one intersection from intersections.csv (a node where at least three relevant OSM ways meet).

  • Colour is i_tpe: Path (walk only), Car (drive only), Road (both). Click a marker for osm_id, number of arms (num_ways), and delta.

  • The hexagon and rectangle layers (off by default) are the same aggregation grids as in the segmentation notebook. They are not part of OSM.

The CartoDB tiles in the background are only for orientation.

Loading...

GTFS stops

This map shows stop locations from the Vienna GTFS sample, not routes and not the OSM street network.

  • Each marker is one stop_id in gtfs_stops.csv.

  • Colour is primary_mode: the mode that appears most often on trips serving that stop in this sample (Tram, Subway, Bus, Rail). It is not a ridership share.

  • The popup is the stop name. Service intensity (trip_count) is not drawn here; it appears in the histogram below.

We keep this map separate from the intersection map so stop clusters stay readable.

Loading...

Statistical plots (Matplotlib and Seaborn)

Matplotlib is the base plotting library in Python. Seaborn sits on top of it and is better for statistical graphics.

Simple category totals (for example three intersection types) do not need a chart. Below we plot distributions of continuous features: how irregular intersections are, and how many sample trips call at each stop.

OSM intersection irregularity (delta)

delta comes from feature engineering. It measures how far the incoming way bearings deviate from a regular intersection of the same number of arms (for three arms, a symmetric Y with 120 degree gaps). Smaller is more regular. Larger is more skewed.

The histogram’s x-axis is that delta value. The y-axis is how many intersections fall in each bin. It is not a map and not a count of intersection types.

<Figure size 700x400 with 1 Axes>

GTFS trip counts per stop

trip_count is the number of distinct trip_ids in this Vienna GTFS sample that visit the stop. It is not passengers, not vehicles per hour in the real city, and not the full Wiener Linien network: only what is in the sample feed.

The histogram’s x-axis is that trip count. The y-axis is how many stops have a count in each bin. A tall bar near zero means many stops are served by few sample trips; a long tail means a few stops are served by many trips.

<Figure size 700x400 with 1 Axes>

Iplotx

What is iplotx?

iplotx draws network graphs (nodes and edges) with matplotlib. When node coordinates are map positions, we can draw the graph on a Vienna CartoDB basemap.

OSM intersection neighbourhood

The figure is a neighbourhood graph of intersections on a Vienna basemap.

Each light-blue point is one intersection from intersections.csv. Each black line joins two intersections that sit next to each other at city-block scale: we build a Delaunay triangulation of the points and keep edges shorter than 140 m.

OSM graph: 8155 nodes, 21720 edges
<Figure size 1000x800 with 1 Axes>

GTFS consecutive-stop graph

This figure is a transit stop graph, not streets and not GTFS shapes.txt route geometry.

  • Coloured points: stops that appear in at least one trip pair. Colour is primary_mode (same meaning as on the Folium map).

  • Grey lines: a straight line between two stops that follow each other in stop_times (stop_sequence on the same trip_id). If many trips use the same pair, we still draw one undirected edge.

  • The line is not the path the vehicle drives. Isolated stops (no neighbour in stop_times) are omitted so the plot shows only the connected sample.

Again, the tiles are only a Vienna backdrop.

GTFS graph: 387 stops, 460 trip links
<Figure size 1000x800 with 1 Axes>

How to decide which visualisation library to use?

When choosing a visualisation library for geospatial data, the decision depends on the type of analysis and the level of interactivity required.

  • Folium is best for interactive maps of point features (intersections by type, stops by mode). Use a separate map per source when the layers would crowd each other.

  • Matplotlib and Seaborn are for statistical charts of attributes (delta, trip_count), not for replacing a map.

  • iplotx is for graphs: an intersection-neighbourhood graph (geometric links, not streets) and a consecutive-stop transit graph (schedule links, not route shapes).

Therefore, Folium is typically preferred for interactive mapping, Matplotlib and Seaborn for analytical charts, and iplotx for networks.

Summary

In this notebook you learned:

  • Why visualisation is an important step in a geospatial data handling pipeline

  • How to map OSM intersections and GTFS stops on separate Folium maps, and what the colours mean

  • How to read a delta histogram and a trip_count histogram (distributions, not maps)

  • How to draw two different iplotx graphs on a Vienna basemap: intersection neighbourhood links versus consecutive GTFS stops, and how those differ from real streets and route shapes