How to Read and Plot Shapefiles (.shp) in Python ?

How to Read and Plot a Shapefile (.shp) Using Python

Shapefiles are one of the most common formats for storing vector geographic data — points, lines, and polygons (for example, country borders, fire perimeters, or solar farm locations).

A shapefile actually consists of multiple files with the same base name but different extensions:

Extension Description
.shp Geometry (points, lines, polygons)
.shx Shape index
.dbf Attribute table (tabular data)
.prj Coordinate reference system (projection)

Install Required Libraries

Make sure you have these libraries installed:

1
pip install geopandas matplotlib

Read the Shapefile

Let’s assume your shapefile is named global_solar_panels.shp and stored in the same folder as your notebook or script.

1
2
3
4
5
6
7
8
import geopandas as gpd
import matplotlib.pyplot as plt

# Read shapefile
gdf = gpd.read_file("global_solar_panels.shp")

# Display the first few rows
print(gdf.head())

This command automatically loads the geometry and attributes (from the .dbf file).

Check the Coordinate Reference System (CRS)

It’s important to know the coordinate system (e.g., WGS84, EPSG:4326).

1
print(gdf.crs)

If your data doesn’t have a CRS defined, or it’s not in latitude/longitude (EPSG:4326), you can convert it:

1
2
if gdf.crs is None or gdf.crs.to_epsg() != 4326:
    gdf = gdf.to_crs(epsg=4326)

How to Visualize the Data

The way you plot a shapefile depends on the size of your dataset. Large shapefiles (e.g., global coverage) can slow down plotting, so it’s often useful to inspect a subset first.

Check the GeoDataFrame Size

Before plotting, it’s good practice to see how many features your shapefile contains:

1
print(f"Number of rows (features) in GeoDataFrame: {len(gdf)}")

This helps you decide whether to plot the full dataset or just a sample.

Create a Sample for Testing

If your shapefile is very large, you can plot a random subset to test your code or check data structure:

1
2
3
4
5
6
7
8
9
# Sample 1000 features (adjust as needed)
gdf_sample = gdf.sample(1000, random_state=42)

# Plot the sample
gdf_sample.plot(figsize=(10, 8), edgecolor='black', alpha=0.6)
plt.title("Sample of Shapefile Features")
plt.xlabel("Longitude")
plt.ylabel("Latitude")
plt.show()

Tip: Using a sample speeds up plotting and is useful for exploratory analysis without loading the full dataset.

How to Read and Plot Shapefiles (.shp) in Python
How to Read and Plot Shapefiles (.shp) in Python

Plot the Entire Shapefile

Once you’ve verified your data, you can plot the full dataset easily:

1
2
3
4
5
gdf.plot(figsize=(12, 10), edgecolor='gray', alpha=0.5)
plt.title("Full Shapefile Visualization")
plt.xlabel("Longitude")
plt.ylabel("Latitude")
plt.show()

Visualize Shapefile Data on a Satellite Map Using Folium

Install Required Libraries

Make sure you have the needed packages installed:

1
pip install geopandas folium

Load and Sample Your GeoDataFrame

For example:

1
2
3
4
5
6
7
import geopandas as gpd
import folium

gdf = gpd.read_file("global_solar_panels.shp")

# Take a small sample if the dataset is large
gdf_sample = gdf.sample(1000)

Create a Folium Map with a Satellite Basemap

You can use Esri World Imagery for a satellite background:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# Get the centroid to center the map
center = [gdf_sample.geometry.centroid.y.mean(), gdf_sample.geometry.centroid.x.mean()]

# Create the map again
m = folium.Map(
    location=[
        gdf_sample.geometry.centroid.y.mean(),
        gdf_sample.geometry.centroid.x.mean()
    ],
    zoom_start=5,
    tiles='https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
    attr='Esri World Imagery'
)

Add GeoDataFrame to the Map

You can easily overlay the geometries using Folium’s GeoJson layer:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# Get only non-geometry columns
tooltip_fields = [col for col in gdf_sample.columns if col != 'geometry']

# Use only up to 5 for clarity
tooltip_fields = tooltip_fields[:5]

folium.GeoJson(
    gdf_sample,
    name="Shapefile Sample",
    style_function=lambda x: {
        "color": "yellow",
        "weight": 2,
        "fillOpacity": 0.3
    },
    tooltip=folium.features.GeoJsonTooltip(fields=tooltip_fields)
).add_to(m)

folium.LayerControl().add_to(m)
m

(Optional) Save as an Interactive HTML Map

You can export the result as an interactive file viewable in any browser:

1
m.save("shapefile_sample_satellite.html")

(Optional) Use a Different Satellite or Basemap Provider

Folium supports several built-in tile providers via folium.TileLayer.
You can add multiple for comparison:

1
2
3
4
5
6
7
folium.TileLayer('OpenStreetMap').add_to(m)
folium.TileLayer('Stamen Terrain').add_to(m)
folium.TileLayer('Stamen Toner').add_to(m)
folium.TileLayer('CartoDB positron').add_to(m)

# Esri satellite (already added manually above)
folium.LayerControl().add_to(m)

Example Output

How to Read and Plot Shapefiles (.shp) in Python How to Read and Plot Shapefiles (.shp) in Python
How to Read and Plot Shapefiles (.shp) in Python

References

Links Site
https://geopandas.org/en/stable/docs/user_guide/io.html GeoPandas: Reading and Writing Files — official guide for loading shapefiles and GeoJSON data.
https://geopandas.org/en/stable/docs/user_guide/mapping.html GeoPandas: Plotting Maps — how to visualize geographic data using Matplotlib.
https://python-visualization.github.io/folium/ Folium Documentation — create interactive leaflet maps directly in Python notebooks.
https://contextily.readthedocs.io/en/latest/ Contextily — add basemaps (satellite, terrain, street maps) to GeoPandas plots.
https://epsg.io/4326 EPSG:4326 (WGS84) — standard latitude/longitude coordinate system reference.
https://matplotlib.org/stable/ Matplotlib Documentation — plotting library used by GeoPandas for static maps.
Image

of