Using Matplotlib for GIS Data Visualization and Mapping in Python
- 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.

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:
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
GPKG (GeoPackage)
Raster Data
Raster Data consists of continuous geographic surfaces:
Elevation models
Landcover classification
Temperature maps
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:
Land Surface Temperature
Vegetation Indices (NDVI)
Hydrological Analysis
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:
Email: info@geowgs84.com
USA (HQ): (720) 702–4849
(A GeoWGS84 Corp Company)




Comments