|
| 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