Skip to content

Commit 0ec4c98

Browse files
Tutorial: Adding a dataset on top of a topographic surface via "drapegrid" of "Figure.grdview" (#3316)
Co-authored-by: Dongdong Tian <[email protected]>
1 parent c54d72f commit 0ec4c98

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
"""
2+
Draping a dataset on top of a topographic surface
3+
==================================================
4+
5+
It can be visually appealing to "drape" a dataset over a topographic surface. This can
6+
be accomplished using the ``drapegrid`` parameter of :meth:`pygmt.Figure.grdview`.
7+
8+
This tutorial consists of two examples:
9+
10+
1. Draping a grid
11+
12+
2. Draping an image
13+
"""
14+
15+
# %%
16+
17+
# Load the required packages
18+
import pygmt
19+
import rasterio
20+
import xarray as xr
21+
22+
# %%
23+
# 1. Drapping a grid
24+
# ------------------
25+
#
26+
# In the first example, the seafloor crustal age is plotted with color-coding on top of
27+
# the topographic map of an area of the Mid-Atlantic Ridge.
28+
29+
# Define the study area in degrees East or North
30+
region_2d = [-50, 0, 36, 70] # [lon_min, lon_max, lat_min, lat_max]
31+
32+
# Download elevation and crustal age grids for the study region with a resolution of 10
33+
# arc-minutes and load them into xarray.DataArrays
34+
grd_relief = pygmt.datasets.load_earth_relief(resolution="10m", region=region_2d)
35+
grd_age = pygmt.datasets.load_earth_age(resolution="10m", region=region_2d)
36+
37+
# Determine the 3-D region from the minimum and maximum values of the relief grid
38+
region_3d = [*region_2d, grd_relief.min().to_numpy(), grd_relief.max().to_numpy()]
39+
40+
# %%
41+
# The topographic surface is created based on the grid passed to the ``grid`` parameter
42+
# of :meth:`pygmt.Figure.grdview`; here we use a grid of the Earth relief. To add a
43+
# color-coding based on *another* grid we have to pass a second grid to the
44+
# ``drapegrid`` parameter; here we use a grid of the crustal age. In this case the
45+
# colormap specified via the ``cmap`` parameter applies to the grid passed to
46+
# ``drapegrid``, not to ``grid``. The azimuth and elevation a the 3-D plot are set via
47+
# the ``perspective`` parameter.
48+
49+
fig = pygmt.Figure()
50+
51+
# Set up colormap for the crustal age
52+
pygmt.config(COLOR_NAN="lightgray")
53+
pygmt.makecpt(cmap="batlow", series=[0, 200, 1], reverse=True, overrule_bg=True)
54+
55+
fig.grdview(
56+
projection="M12c", # Mercator projection with a width of 12 centimeters
57+
region=region_3d,
58+
grid=grd_relief, # Use elevation grid for z values
59+
drapegrid=grd_age, # Use crustal age grid for color-coding
60+
cmap=True, # Use colormap created for the crustal age
61+
surftype="i", # Create an image plot
62+
# Use an illumination from the azimuthal directions 0° (north) and 270°
63+
# (west) with a normalization via a cumulative Laplace distribution for
64+
# the shading
65+
shading="+a0/270+ne0.6",
66+
perspective=[157.5, 30], # Azimuth and elevation for the 3-D plot
67+
zsize="1.5c",
68+
plane="+gdarkgray",
69+
frame=True,
70+
)
71+
72+
# Add colorbar for the crustal age
73+
fig.colorbar(frame=["x+lseafloor crustal age", "y+lMyr"], position="+n")
74+
75+
fig.show()
76+
77+
78+
# %%
79+
# 2. Draping an image
80+
# -------------------
81+
#
82+
# In the second example, the flag of the European Union (EU) is plotted on top of a
83+
# topographic map of northwest Europe. This example is modified from
84+
# :gmt-docs:`GMT example 32 </gallery/ex32.html>`.
85+
# We have to consider the dimension of the image we want to drap. The image we will
86+
# download in this example has 1000 x 667 pixels, i.e. a aspect ratio of 3 x 2.
87+
88+
# Define the study area in degrees East or North, with an extend of 6 degrees for
89+
# the longitude and 4 degrees for the latitude
90+
region_2d = [3, 9, 50, 54] # [lon_min, lon_max, lat_min, lat_max]
91+
92+
# Download elevation grid for the study region with a resolution of 30 arc-seconds and
93+
# pixel registration and load it into an xarray.DataArray
94+
grd_relief = pygmt.datasets.load_earth_relief(resolution="30s", region=region_2d)
95+
96+
# Determine the 3-D region from the minimum and maximum values of the relief grid
97+
region_3d = [*region_2d, grd_relief.min().to_numpy(), grd_relief.max().to_numpy()]
98+
99+
# Download an PNG image of the flag of the EU using rasterio and load it into a
100+
# xarray.DataArray
101+
url_to_image = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b7/Flag_of_Europe.svg/1000px-Flag_of_Europe.svg.png"
102+
with rasterio.open(url_to_image) as dataset:
103+
data = dataset.read()
104+
drapegrid = xr.DataArray(data, dims=("band", "y", "x"))
105+
106+
# %%
107+
# Again we create a 3-D plot with :meth:`pygmt.Figure.grdview` and passe an Earth relief
108+
# grid to the ``grid`` parameter to create the topographic surface. But now we pass the
109+
# PNG image which was loaded into an :class:`xarray.DataArray` to the ``drapgrid``
110+
# parameter.
111+
112+
fig = pygmt.Figure()
113+
114+
# Set up a colormap with two colors for the EU flag: blue (0/51/153) for the background
115+
# (value 0 in the nedCDF file -> lower half of 0-255 range) and yellow (255/204/0) for
116+
# the stars (value 255 -> upper half)
117+
pygmt.makecpt(cmap="0/51/153,255/204/0", series=[0, 256, 128])
118+
119+
fig.grdview(
120+
projection="M12c", # Mercator projection with a width of 12 centimeters
121+
region=region_3d,
122+
grid=grd_relief, # Use elevation grid for z values
123+
drapegrid=drapegrid, # Drap image grid for the EU flag on top
124+
cmap=True, # Use colormap defined for the EU flag
125+
surftype="i", # Create an image plot
126+
# Use an illumination from the azimuthal directions 0° (north) and 270° (west) with
127+
# a normalization via a cumulative Laplace distribution for the shading
128+
shading="+a0/270+ne0.6",
129+
perspective=[157.5, 30], # Define azimuth, elevation for the 3-D plot
130+
zsize="1c",
131+
plane="+gdarkgray",
132+
frame=True,
133+
)
134+
135+
fig.show()
136+
137+
# sphinx_gallery_thumbnail_number = 2

0 commit comments

Comments
 (0)