In [1]:
# IMPORT LIBRARIES
import sys
import pygmt
import rasterio
import xarray as xr
import numpy as np
# Show versions
print("Python version:", sys.version)
print("PyGMT version:", pygmt.__version__)
print("Rasterio version:", rasterio.__version__)
print("Xarray version:", xr.__version__)
print("NumPy version:", np.__version__)
Python version: 3.11.13 | packaged by conda-forge | (main, Jun 4 2025, 14:39:58) [MSC v.1943 64 bit (AMD64)] PyGMT version: v0.17.0 Rasterio version: 1.4.3 Xarray version: 2025.10.1 NumPy version: 2.3.3
In [2]:
#Sri Lanka bounding box
region = [79.0, 82.5, 5.0, 10.5]
# Download elevation grid
grid = pygmt.datasets.load_earth_relief(resolution="30s", region=region)
In [4]:
# FIRST FIGURE
fig = pygmt.Figure()
# Create 3-D perspective view with grdview
fig.grdview(
grid=grid,
shading=True, # Default shading
perspective=[130, 30], # Sets the view azimuth as 130 degrees, and the view angle as 30 degrees
frame=["xa", "ya", "SnE"], # Sets the x- and y-axis labels, and annotates the west, south, and east axes
projection="M12c", # Sets a Mercator projection on a 12-centimeter figure
zsize="2c", # Sets the height of the three-dimensional relief at 2 centimeters
surftype="s",
cmap="topo1",
contourpen="0.5p",
)
# Add a vertical colorbar to the right
fig.colorbar(
perspective=True,
position="JMR+v+w12c/0.5c+o1c/0c", # right side, vertical, width/height, offset
frame=["a1000", "x+lElevation (m)"],
)
#Add map scale
fig.basemap(perspective=True, map_scale="jBM+w300k+o0c/-11c+f+l")
# Shift origin for second plot
fig.shift_origin(xshift="25c")
# SECOND FIGURE
# Create Xarray DataArray from image of Sri Lanka so it is usable by PyGMT
flag_to_image = "Flag_of_Sri_Lanka_vertical.png"
with rasterio.open(flag_to_image) as dataset:
data = dataset.read()
drapegrid = xr.DataArray(data, dims=("band", "y", "x"))
# Flip the image on both axes so it is facing the viewer
drapegrid_rot180 = drapegrid.isel(y=slice(None, None, -1), x=slice(None, None, -1))
# Plot 3D flag draped over relief
fig.grdview(
projection="M12c",
region=region,
grid=grid,
drapegrid=drapegrid_rot180,
surftype="i", # "image" mode needed
perspective=[130, 30],
zsize="1.5c",
plane="+gdarkgray",
frame=True,
)
# Create a masked version of the elecation grid where values above 0 become NaN (transparent)
grid_masked = grid.where(grid <= 0, np.nan)
#Plot elevation grid on top of image, omitting Sri Lanka land area
fig.grdview(
projection="M12c",
shading=True,
region=region,
grid=grid_masked,
cmap=True,
surftype="s",
perspective=[130, 30],
zsize="1.5c",
plane="+gdarkgray",
frame=True,
)
#Show and save figure
#fig.show()
#fig.savefig("fountains_of_paradise.jpg")
C:\Users\timwu\anaconda3\envs\pygmt\Lib\site-packages\rasterio\__init__.py:356: NotGeoreferencedWarning: Dataset has no geotransform, gcps, or rpcs. The identity matrix will be returned. dataset = DatasetReader(path, driver=driver, sharing=sharing, **kwargs) C:\Users\timwu\anaconda3\envs\pygmt\Lib\site-packages\rasterio\__init__.py:366: NotGeoreferencedWarning: The given matrix is equal to Affine.identity or its flipped counterpart. GDAL may ignore this matrix and save no geotransform without raising an error. This behavior is somewhat driver-specific. dataset = writer(
In [ ]: