top of page

Using Matplotlib for GIS Data Visualization and Mapping in Python

  • Writer: Anvita Shrivastava
    Anvita Shrivastava
  • Jun 12
  • 4 min read

Updated: Jul 2

GISs, or geographic information systems, are now standard tools for analyzing, managing, and visualizing spatial data across multiple industries (urban planning, environmental science, transportation, agriculture, military, and business intelligence). Python is currently the most powerful programming language used in GIS workflows due to the vast array of geospatial libraries that comprise Python's geospatial library ecosystem.


Although specialized GIS toolsets, including GeoServer, QGIS, ArcGIS, and web mapping frameworks, generally attract a larger share of media coverage, Matplotlib (a standard library used in Python for creating visual representations or 'mapping' images) is also a key library for generating visual representations of high-quality static geospatial maps. With its ability to easily create custom visual representations or 'maps' of geospatial data, combined with the fact that it is designed for easy integration with other GIS libraries such as GeoPandas, Rasterio, Shapely, and Cartopy, means that Matplotlib is an excellent tool to create and distribute publication-ready geographic visualizations.


Matplotlib for GIS Data Visualization and Mapping in Python
Matplotlib for GIS Data Visualization and Mapping in Python

Why Use Matplotlib for GIS Visualization?


Despite not being created specifically for visualizing GIS, there are many reasons to use Matplotlib:


  • You have complete authority over how your map looks (environment, aesthetics).

  • You can make high-quality (publication-ready) visualizations.

  • Matplotlib works with both NumPy and Pandas.

  • Can utilize several major libraries dealing with geospatial data.

  • Matplotlib allows users to create highly layered & spatially/temporally complex visualizations.

  • Matplotlib has considerable functionality with respect to annotations and labelling.

  • You can save your visualizations for submission to Scientific journals and other reports.


Matplotlib is the rendering engine for many GIS-related visualizations within the Python language.


GIS Data Types Supported by Matplotlib


There are generally two types of GIS data:


  1. Vector Data


Vector Data consists of discrete geographic features:

  • Points (cities, sensors, landmarks)

  • Lines (roads, rivers, pipelines)

  • Polygons (countries, states, parcels of land)


Some common types of vector data file formats include:

  • Shapefile (.shp)

  • GeoJSON

  • KML

  • GPKG (GeoPackage)


  1. Raster Data


Raster Data consists of continuous geographic surfaces:


Common types of Raster Data file formats include:

  • GeoTIFF

  • JPEG2000

  • NetCDF

  • IMG


Matplotlib will visualize the majority of vector and raster data, using the various GIS-specific libraries.


Visualizing Vector Data with GeoPandas and Matplotlib


GeoPandas integrates directly with Matplotlib.


Loading a Shapefile

import geopandas as gpd
import matplotlib.pyplot as plt

world = gpd.read_file(
    gpd.datasets.get_path('naturalearth_lowres')
)

print(world.head())

Creating a Basic Map

fig, ax = plt.subplots(figsize=(12, 8))

world.plot(
    ax=ax,
    color='lightgray',
    edgecolor='black'
)

plt.title("World Map")
plt.show()

This generates a simple polygon map showing country boundaries.


Creating Choropleth Maps


Choropleth maps visualize attribute values using color gradients.


Population-Based Visualization

fig, ax = plt.subplots(figsize=(14, 8))

world.plot(
    column='pop_est',
    cmap='viridis',
    legend=True,
    ax=ax
)

plt.title("Population Distribution")
plt.show()

Plotting Point Data


Suppose we have geographic coordinates for monitoring stations.

import pandas as pd
import geopandas as gpd
from shapely. geometry import Point

df = pdDataFrame({
    'city': ['New York', 'Chicago', 'Los Angeles'],
    'lon': [-74.0060, -87.6298, 118.2437],
    'lat': [40.7128, 41.8781, 34.0522]
})

geometry = [
    Point(xy)
    for xy in zip(df.lon, df.lat)
]

gdf = gpdGeoDataFrame(
    df,
    geometry=geometry,
    crs='EPSG:4326'
)

Visualize Points

fig, ax = plt.subplots(figsize=(10, 6))

world.plot(ax=ax, color='lightgray')

gdf.plot(
    ax=ax,
    color='red',
    markersize=80
)

plt.show()

Visualizing Line Features


Line geometries are commonly used for:

  • Transportation networks

  • Rivers

  • Utility infrastructure

  • Flight routes

roads = gpd.read_file("roads.shp")

fig, ax = plt.subplots(figsize=(12, 8))

roads. plot(
    ax=ax,
    color='blue',
    linewidth=1.2
)

plt.show()

Raster Visualization with Rasterio


Raster datasets require Rasterio.


Load a GeoTIFF

import rasterio
from rasterio. plot import show

dataset = rasterioopen(
    "elevation.tif"
)

Display Raster Data

fig, ax = plt.subplots(figsize=(12, 8))

show(dataset, ax=ax)

plt.title("Elevation Model")
plt.show()

Applying Custom Color Maps

band = datasetread(1)

plt.figure(figsize=(12, 8))

plt.imshow(
    band,
    cmap='terrain'
)

plt.colorbar(
    label="Elevation (m)."
)

plt.show()

This approach is frequently used for:


Overlaying Vector and Raster Layers


GIS workflows often combine multiple datasets.

fig, ax = plt.subplots(figsize=(14, 8))

show(dataset, ax=ax)

roads. plot(
    ax=ax,
    color='black',
    linewidth=0.5
)

cities. plot(
    ax=ax,
    color='red',
    markersize=50
)

plt.show()

Layer stacking improves spatial context and analytical insights.


Adding Basemaps with Contextily


Contextily provides access to web tile services.

import contextily as ctx

ax = gdf.to_crs(
    epsg=3857
).plot(
    figsize=(12,8),
    alpha=0.7
)

ctx.add_basemap(
    ax,
    source=ctx.providersOpenStreetMap. OpenStreetMapMapnik
)

plt.show()

This adds:

  • Roads

  • Buildings

  • Labels

  • Terrain information

behind your GIS layers.


Advanced Cartographic Styling


Professional GIS maps require thoughtful design.


Adding Titles and Labels

plt.title(
    "US Population Density",
    fontsize=18,
    fontweight='bold'
)

plt.xlabel("Longitude")
plt.ylabel("Latitude")

Adding Annotations

ax. annotate(
    "New York",
    xy=(-74, 40.7),
    xytext=(-80, 45),
    arrowprops=dict(
        arrowstyle="->"
    )
)

Custom Legends

from matplotliblines import Line2D

legend_elements = [
    Line2D(
        [0],
        [0],
        marker='o',
        color='w',
        label='Cities',
        markerfacecolor='red',
        markersize=10
    )
]

ax.legend(handles=legend_elements)

Creating Heat Maps


Spatial density can be visualized using heat maps.

import numpy as np

plt.hexbin(
    x_coordinates,
    y_coordinates,
    gridsize=50,
    cmap='inferno'
)

plt.colorbar()
plt.show()

Common use cases:

  • Crime analysis

  • Traffic patterns

  • Population density

  • Customer location analysis


Matplotlib has continued to be a very powerful and flexible option for visualizing GIS datasets in Python, as it can be utilized in conjunction with other Python libraries such as GeoPandas, Rasterio, Cartopy, and Contextily, allowing users to create high-quality geospatial map products, thematic visualizations, raster analyses (i.e., satellite imagery analysis), and publication-ready cartographic products.


As you develop environmental models, assess transportation systems, illustrate demographic trends, or build spatial data science applications, Matplotlib gives you the ability to provide both the flexibility and precision necessary for the professional GIS mapping process from start to finish. Developing your ability to use these techniques will empower developers, data scientists, and GIS analysts to take raw geographic data and turn it into meaningful insights for use in tactical and strategic decision-making, while providing full control over both visualization design and analytical results.


To learn more about Matplotlib and its geospatial capabilities, click here.


For more information or any questions regarding the LizardTech suite of products, please don't hesitate to contact us at:



USA (HQ): (720) 702–4849


(A GeoWGS84 Corp Company)



Comments


bottom of page