Introduction to GeoPandas#
Outline#
What is GeoPandas
Exercises
What is GeoPandas#
GeoPandas extends the functionalities of Pandas to geospatial data, which is time-based data that is related to a location on the surface of Earth.
#@title Connect to Google Drive {display-mode:"form"}
CONNECT_TO_DRIVE = False #@param {type:"boolean"}
import os
if CONNECT_TO_DRIVE:
from google.colab import drive
# Mount Google Drive
drive.mount('/content/drive')
# Define the desired working directory path
working_dir = '/content/drive/MyDrive/hello-pypsa'
# Create the directory if it doesn't exist
if not os.path.exists(working_dir):
os.makedirs(working_dir)
print(f"Directory '{working_dir}' created.")
else:
print(f"Directory '{working_dir}' already exists.")
# Change the current working directory
os.chdir(working_dir)
print(f"Current working directory: {os.getcwd()}")
else:
print("Not connecting to Google Drive.")
#@title Install Packages {display-mode:"form"}
INSTALL_PACKAGES = False #@param {type:"boolean"}
import os
# Check if packages have already been installed in this session to prevent re-installation
if INSTALL_PACKAGES and not os.environ.get('PYPSA_PACKAGES_INSTALLED'):
!pip install pypsa pypsa[excel] folium mapclassify cartopy
!pip install git+https://github.com/PriyeshGosai/pypsa_network_viewer.git
os.environ['PYPSA_PACKAGES_INSTALLED'] = 'true'
elif not INSTALL_PACKAGES:
print("Skipping package installation.")
else:
print("PyPSA packages are already installed for this session.")
Clone the repo.
# !git clone https://github.com/PriyeshGosai/energylab-foundational-pypsa.git
How to import GeoPandas#
!pip install geopandas
Requirement already satisfied: geopandas in C:\Users\PriyeshGosai\anaconda3\envs\pypsa-training-env-new\Lib\site-packages (1.1.2)
Requirement already satisfied: numpy>=1.24 in C:\Users\PriyeshGosai\anaconda3\envs\pypsa-training-env-new\Lib\site-packages (from geopandas) (2.4.2)
Requirement already satisfied: packaging in C:\Users\PriyeshGosai\anaconda3\envs\pypsa-training-env-new\Lib\site-packages (from geopandas) (26.0)
Requirement already satisfied: pandas>=2.0.0 in C:\Users\PriyeshGosai\anaconda3\envs\pypsa-training-env-new\Lib\site-packages (from geopandas) (3.0.1)
Requirement already satisfied: shapely>=2.0.0 in C:\Users\PriyeshGosai\anaconda3\envs\pypsa-training-env-new\Lib\site-packages (from geopandas) (2.1.2)
Requirement already satisfied: python-dateutil>=2.8.2 in C:\Users\PriyeshGosai\anaconda3\envs\pypsa-training-env-new\Lib\site-packages (from pandas>=2.0.0->geopandas) (2.9.0.post0)
Requirement already satisfied: tzdata in C:\Users\PriyeshGosai\anaconda3\envs\pypsa-training-env-new\Lib\site-packages (from pandas>=2.0.0->geopandas) (2025.3)
Requirement already satisfied: six>=1.5 in C:\Users\PriyeshGosai\anaconda3\envs\pypsa-training-env-new\Lib\site-packages (from python-dateutil>=2.8.2->pandas>=2.0.0->geopandas) (1.17.0)
import geopandas as gpd
Data structure#
The basic data structure provided by GeoPandas are GeoSeries and GeoDataFrame. A GeoDataFrame is a subclass of Pandas DataFrame, that can store geometry columns and perform spatial operations. The basic structure of GeoDataFrame is shown below

There are two main models (i.e. a simplified version of the represented objects) for storing geospatial data
vector
raster
Vector#
A vector data model stores locations as discrete geometric objects. The ones available are shown in the image below taken from this link. For example, a POINT() is represented by a longitude and latitude coordinate pair, whereas a POLYGON is a set of POINT() that delimit a closed area.
Areas are occasionally represented with a centroid, which is the point that is mathematically equidistant from all points of the area.
Raster#
Raster data is instead stored on a grid of pixels. Each pixel encodes the necessary properties that characterize the given area, as elevation or temperature.
Working with geospatial information#
Geospatial information are usually contained in files with format GeoPackage, GeoJSON or Shapefile. Such files can be read in with the command below. The command detects the filetype and reads the data into a GeoDataFrame. The file below contains the shapes of the countries that belong to the Eastern Africa Power Pool.
import pathlib
file_path = pathlib.Path(pathlib.Path.cwd(), "shapes", "lao_admin1.geojson")
country_shapes = gpd.read_file(file_path)
country_shapes#.head(1)
| adm1_name | adm1_name1 | adm1_name2 | adm1_name3 | adm1_pcode | adm0_name | adm0_name1 | adm0_name2 | adm0_name3 | adm0_pcode | ... | area_sqkm | cod_version | lang | lang1 | lang2 | lang3 | adm1_ref_name | center_lat | center_lon | geometry | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Attapeu | ອັດຕະປື | None | None | LA17 | Lao People's Democratic Republic | ສາທາລະນະລັດ ປະຊາທ | None | None | LA | ... | 10233.593328 | V_01 | en | lo | None | None | Attapeu | 14.791038 | 107.101424 | POLYGON ((107.1181 15.30727, 107.10683 15.3131... |
| 1 | Bokeo | ບໍ່ແກ້ວ | None | None | LA05 | Lao People's Democratic Republic | ສາທາລະນະລັດ ປະຊາທ | None | None | LA | ... | 6782.282249 | V_01 | en | lo | None | None | Bokeo | 20.306804 | 100.707712 | POLYGON ((100.61233 20.84302, 100.61225 20.843... |
| 2 | Bolikhamxai | ບໍລິຄຳໄຊ | None | None | LA11 | Lao People's Democratic Republic | ສາທາລະນະລັດ ປະຊາທ | None | None | LA | ... | 15392.737280 | V_01 | en | lo | None | None | Bolikhamxai | 18.494826 | 104.015334 | POLYGON ((104.28142 19.11985, 104.28052 19.119... |
| 3 | Champasack | ຈຳປາສັກ | None | None | LA16 | Lao People's Democratic Republic | ສາທາລະນະລັດ ປະຊາທ | None | None | LA | ... | 14902.868533 | V_01 | en | lo | None | None | Champasack | 14.695812 | 105.871056 | POLYGON ((105.98645 15.4433, 105.98604 15.4509... |
| 4 | Houaphan | ຫົວພັນ | None | None | LA07 | Lao People's Democratic Republic | ສາທາລະນະລັດ ປະຊາທ | None | None | LA | ... | 17201.240990 | V_01 | en | lo | None | None | Houaphan | 20.294550 | 103.921595 | POLYGON ((104.11592 20.97375, 104.11408 20.975... |
| 5 | Khammouan | ຄຳມ່ວນ | None | None | LA12 | Lao People's Democratic Republic | ສາທາລະນະລັດ ປະຊາທ | None | None | LA | ... | 16746.901762 | V_01 | en | lo | None | None | Khammouan | 17.584080 | 105.243732 | POLYGON ((105.32209 18.2649, 105.32182 18.2651... |
| 6 | Louangnamtha | ຫຼວງນ້ຳທາ | None | None | LA03 | Lao People's Democratic Republic | ສາທາລະນະລັດ ປະຊາທ | None | None | LA | ... | 9467.077999 | V_01 | en | lo | None | None | Louangnamtha | 20.919773 | 101.053815 | POLYGON ((101.1537 21.56447, 101.15314 21.5645... |
| 7 | Louangphabang | ຫຼວງພະບາງ | None | None | LA06 | Lao People's Democratic Republic | ສາທາລະນະລັດ ປະຊາທ | None | None | LA | ... | 19931.244341 | V_01 | en | lo | None | None | Louangphabang | 20.073659 | 102.610144 | POLYGON ((102.8746 21.1454, 102.87323 21.14482... |
| 8 | Oudomxai | ອຸດົມໄຊ | None | None | LA04 | Lao People's Democratic Republic | ສາທາລະນະລັດ ປະຊາທ | None | None | LA | ... | 12053.643990 | V_01 | en | lo | None | None | Oudomxai | 20.518757 | 101.873957 | POLYGON ((101.85468 21.21134, 101.85273 21.213... |
| 9 | Phongsaly | ຜົ້ງສາລີ | None | None | LA02 | Lao People's Democratic Republic | ສາທາລະນະລັດ ປະຊາທ | None | None | LA | ... | 15493.626654 | V_01 | en | lo | None | None | Phongsaly | 21.667021 | 102.221271 | POLYGON ((101.76364 22.50803, 101.76317 22.508... |
| 10 | Salavan | ສາລະວັນ | None | None | LA14 | Lao People's Democratic Republic | ສາທາລະນະລັດ ປະຊາທ | None | None | LA | ... | 10110.946890 | V_01 | en | lo | None | None | Salavan | 15.914160 | 106.331281 | POLYGON ((106.84721 16.54548, 106.84651 16.545... |
| 11 | Savannakhet | ສະຫວັນນະເຂດ | None | None | LA13 | Lao People's Democratic Republic | ສາທາລະນະລັດ ປະຊາທ | None | None | LA | ... | 21302.574323 | V_01 | en | lo | None | None | Savannakhet | 16.495446 | 105.718008 | POLYGON ((105.1753 17.10599, 105.17525 17.1059... |
| 12 | Sekong | ເຊກອງ | None | None | LA15 | Lao People's Democratic Republic | ສາທາລະນະລັດ ປະຊາທ | None | None | LA | ... | 8281.975985 | V_01 | en | lo | None | None | Sekong | 15.606358 | 107.011911 | POLYGON ((107.16065 16.16771, 107.16034 16.167... |
| 13 | Vientiane | ວຽງຈັນ | None | None | LA10 | Lao People's Democratic Republic | ສາທາລະນະລັດ ປະຊາທ | None | None | LA | ... | 12494.048877 | V_01 | en | lo | None | None | Vientiane | 18.614572 | 102.222354 | POLYGON ((102.21145 19.40468, 102.21034 19.406... |
| 14 | Vientiane Capital | ນະຄອນຫຼວງວຽງຈັນ | None | None | LA01 | Lao People's Democratic Republic | ສາທາລະນະລັດ ປະຊາທ | None | None | LA | ... | 3637.202258 | V_01 | en | lo | None | None | Vientiane Capital | 18.122770 | 102.650912 | POLYGON ((102.12306 18.43918, 102.1227 18.4391... |
| 15 | Xaignabouly | ໄຊຍະບູລີ | None | None | LA08 | Lao People's Democratic Republic | ສາທາລະນະລັດ ປະຊາທ | None | None | LA | ... | 15493.383725 | V_01 | en | lo | None | None | Xaignabouly | 18.701963 | 101.532502 | POLYGON ((101.73373 19.892, 101.73398 19.89247... |
| 16 | Xaisomboon | ໄຊສົມບູນ | None | None | LA18 | Lao People's Democratic Republic | ສາທາລະນະລັດ ປະຊາທ | None | None | LA | ... | 7956.089433 | V_01 | en | lo | None | None | Xaisomboon | 18.868533 | 103.036783 | POLYGON ((102.5675 19.27522, 102.56678 19.2764... |
| 17 | Xiengkhouang | ຊຽງຂວາງ | None | None | LA09 | Lao People's Democratic Republic | ສາທາລະນະລັດ ປະຊາທ | None | None | LA | ... | 12923.678835 | V_01 | en | lo | None | None | Xiengkhouang | 19.418695 | 103.356708 | POLYGON ((103.76667 20.0367, 103.76597 20.0377... |
18 rows × 22 columns
A Coordinate Reference System (CRS) is a framework used to precisely measure locations on the surface of Earth as coordinates. This website provides a comparison and further information on the main CRS. The CRS used in the GeoDataFrame can be viewed with
country_shapes.crs
<Geographic 2D CRS: EPSG:4326>
Name: WGS 84
Axis Info [ellipsoidal]:
- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)
Area of Use:
- name: World.
- bounds: (-180.0, -90.0, 180.0, 90.0)
Datum: World Geodetic System 1984 ensemble
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich
The snippet below changes (technically speaking re-projects) the GeoDataFrame content to a different CRS
#country_shapes = country_shapes.set_index("name")
country_shapes = country_shapes.to_crs(3857)
country_shapes.crs
<Projected CRS: EPSG:3857>
Name: WGS 84 / Pseudo-Mercator
Axis Info [cartesian]:
- X[east]: Easting (metre)
- Y[north]: Northing (metre)
Area of Use:
- name: World between 85.06°S and 85.06°N.
- bounds: (-180.0, -85.06, 180.0, 85.06)
Coordinate Operation:
- name: Popular Visualisation Pseudo-Mercator
- method: Popular Visualisation Pseudo Mercator
Datum: World Geodetic System 1984 ensemble
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich
The snippet below computes the area and the centroid of each country
country_shapes["area"] = country_shapes.area
country_shapes["centroid"] = country_shapes.centroid
To plot the areas
country_shapes.plot("area", legend=True)
<Axes: >
To plot the centroids instead
ax = country_shapes["geometry"].plot()
country_shapes["centroid"].plot(ax=ax, color="black")
<Axes: >
Finally it is possible to compute the distances between two centroids. The snippet below computes the distances of all centroids from the one of Ruanda. Finally the code sorts the GeoDataFrame in ascending order by the distance. Indeed the centroid of Lybia is the farthest away from the reference one.
rw_centroid = country_shapes["centroid"].iloc[0]
country_shapes["distance"] = country_shapes["centroid"].distance(rw_centroid)
country_shapes.sort_values(by=["distance"])
| adm2_name | adm2_name1 | adm2_name2 | adm2_name3 | adm2_pcode | adm1_name | adm1_name1 | adm1_name2 | adm1_name3 | adm1_pcode | ... | lang1 | lang2 | lang3 | adm2_ref_name | center_lat | center_lon | geometry | area | centroid | distance | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Add | ມ. ແອດ | None | None | LA0708 | Houaphan | ຫົວພັນ | None | None | LA07 | ... | lo | None | None | Add | 20.730699 | 103.900457 | POLYGON ((11577832.906 2380901.04, 11577604.64... | 1.179908e+09 | POINT (11564216.804 2359488.203) | 0.000000 |
| 145 | Xiengkhor | ມ. ຊຽງຄໍ້ | None | None | LA0702 | Houaphan | ຫົວພັນ | None | None | LA07 | ... | lo | None | None | Xiengkhor | 20.825112 | 104.218032 | POLYGON ((11619280.712 2370462.417, 11619179.0... | 9.147069e+08 | POINT (11597928.482 2370922.417) | 35598.011930 |
| 129 | Xamneua | ມ. ຊຳເໜືອ | None | None | LA0701 | Houaphan | ຫົວພັນ | None | None | LA07 | ... | lo | None | None | Xamneua | 20.371930 | 103.830856 | POLYGON ((11591439.765 2353213.888, 11591368.4... | 3.614137e+09 | POINT (11570337.74 2318019.637) | 41917.869809 |
| 109 | Sopbao | ມ. ສົບເບົາ | None | None | LA0707 | Houaphan | ຫົວພັນ | None | None | LA07 | ... | lo | None | None | Sopbao | 20.650774 | 104.391927 | POLYGON ((11619798.583 2329208.198, 11620065.4... | 1.186526e+09 | POINT (11620355.277 2349222.713) | 57069.329432 |
| 146 | Xon | ມ. ຊ່ອນ | None | None | LA0710 | Houaphan | ຫົວພັນ | None | None | LA07 | ... | lo | None | None | Xon | 20.488615 | 103.351029 | POLYGON ((11541144.237 2351172.032, 11541261.6... | 2.356671e+09 | POINT (11510495.693 2335809.55) | 58708.060978 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 102 | Sanxay | ມ. ຊານໄຊ | None | None | LA1704 | Attapeu | ອັດຕະປື | None | None | LA17 | ... | lo | None | None | Sanxay | 15.036413 | 107.209647 | POLYGON ((11969026.191 1693632.083, 11969041.1... | 3.062521e+09 | POINT (11934053.284 1696464.5) | 759196.583880 |
| 140 | Xaysetha | ມ. ໄຊເສດຖາ | None | None | LA1701 | Attapeu | ອັດຕະປື | None | None | LA17 | ... | lo | None | None | Xaysetha | 14.975115 | 106.900929 | POLYGON ((11961636.775 1659529.142, 11961557.7... | 1.394776e+09 | POINT (11920331.993 1673837.323) | 772615.789156 |
| 54 | Moonlapamok | ມ. ມູນລະປະໂມກ | None | None | LA1609 | Champasack | ຈຳປາສັກ | None | None | LA16 | ... | lo | None | None | Moonlapamok | 14.311816 | 105.538690 | POLYGON ((11784018.006 1626251.839, 11783865.1... | 2.482105e+09 | POINT (11751131.304 1608947.428) | 773465.244957 |
| 33 | Khong | ມ. ໂຂງ | None | None | LA1610 | Champasack | ຈຳປາສັກ | None | None | LA16 | ... | lo | None | None | Khong | 14.225926 | 105.927019 | POLYGON ((11818500.848 1614551.168, 11818490.9... | 2.085887e+09 | POINT (11795967.669 1597322.804) | 796620.712045 |
| 95 | Phouvong | ມ. ພູວົງ | None | None | LA1705 | Attapeu | ອັດຕະປື | None | None | LA17 | ... | lo | None | None | Phouvong | 14.517791 | 106.942927 | POLYGON ((11857901.616 1625646.768, 11857956.3... | 3.638877e+09 | POINT (11910131.589 1637220.73) | 800829.158789 |
148 rows × 30 columns
Additional source of geospatial data#
The package geodatasets offers ready-to-use geospatial datasets. The package can be installed with the command
!pip install geodatasets
Requirement already satisfied: geodatasets in C:\Users\PriyeshGosai\anaconda3\envs\pypsa-training-env-new\Lib\site-packages (2026.1.0)
Requirement already satisfied: pooch in C:\Users\PriyeshGosai\anaconda3\envs\pypsa-training-env-new\Lib\site-packages (from geodatasets) (1.9.0)
Requirement already satisfied: platformdirs>=2.5.0 in C:\Users\PriyeshGosai\anaconda3\envs\pypsa-training-env-new\Lib\site-packages (from pooch->geodatasets) (4.9.2)
Requirement already satisfied: packaging>=20.0 in C:\Users\PriyeshGosai\anaconda3\envs\pypsa-training-env-new\Lib\site-packages (from pooch->geodatasets) (26.0)
Requirement already satisfied: requests>=2.19.0 in C:\Users\PriyeshGosai\anaconda3\envs\pypsa-training-env-new\Lib\site-packages (from pooch->geodatasets) (2.32.5)
Requirement already satisfied: charset_normalizer<4,>=2 in C:\Users\PriyeshGosai\anaconda3\envs\pypsa-training-env-new\Lib\site-packages (from requests>=2.19.0->pooch->geodatasets) (3.4.5)
Requirement already satisfied: idna<4,>=2.5 in C:\Users\PriyeshGosai\anaconda3\envs\pypsa-training-env-new\Lib\site-packages (from requests>=2.19.0->pooch->geodatasets) (3.11)
Requirement already satisfied: urllib3<3,>=1.21.1 in C:\Users\PriyeshGosai\anaconda3\envs\pypsa-training-env-new\Lib\site-packages (from requests>=2.19.0->pooch->geodatasets) (2.6.3)
Requirement already satisfied: certifi>=2017.4.17 in C:\Users\PriyeshGosai\anaconda3\envs\pypsa-training-env-new\Lib\site-packages (from requests>=2.19.0->pooch->geodatasets) (2026.2.25)
and imported with the command
import geodatasets as gds
A dataset (for example the one from nepal) can be accessed with the snippet below
path_to_data = gds.get_path("geoda nepal")
gdf_nepal = gpd.read_file(path_to_data)
gdf_nepal.head(2)
| id | name_1 | name_2 | district | depecprov | povindex | pcinc | pcincppp | pcincmp | malkids | ... | HEALTDAMT | HUMDAMT | INDDAMT | MULTDAMT | SOCDAMT | TOURDAMT | TRANDAMT | WATDAMT | TOTDAMT | geometry | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | NaN | Dhaualagiri | Baglung | 27.01 | 27.33 | 354 | 573 | 25613 | 42.9 | ... | 3584409 | 172736 | 369324 | 8050858 | 1308661 | 0 | 15421 | 1996315 | 32542286 | POLYGON ((83.10834 28.6202, 83.1056 28.60976, ... |
| 1 | 2 | NaN | Dhaualagiri | Mustang | 31.51 | 31.16 | 1189 | 1922 | 85957 | 54.7 | ... | 2253911 | 172736 | 0 | 3712798 | 633763 | 0 | 15421 | 0 | 14427364 | POLYGON ((83.99726 29.31675, 84 29.31576, 84 2... |
2 rows × 62 columns
gdf_nepal = gdf_nepal.set_index("district")
gdf_nepal = gdf_nepal.to_crs(3857)
Exercises#
Exercise 1 - write a program that computes the area of the districts of nepal. Plot the results afterwards.
# please provide your code here
# please provide your code here
Exercise 2 - write a program that computes the centroid of the districts of nepal. Plot the results afterwards.
# please provide your code here
# please provide your code here
Exercise 3 - write a program that computes the distances of the centroids from a reference centroid (choose one).
# please provide your code here