A slice is a subregion, a mask is a map of a condition, a gradient is terrain slope.
| File | Source | Coverage | Used for |
|---|---|---|---|
| synthetic_temperature_grid.csv | Course-generated, seed 4100 | 50 × 50 cells over 10 × 8 km | Reshaping, masks, colour maps |
| synthetic_elevation_grid.csv | Course-generated, seed 4100 | 50 × 50 cells over 10 × 8 km | Gradients, slope, the lapse-rate fit |
Earth data arrive as a flat column and have to be given back their shape.
Python
elevation = elev["elevation_m"].to_numpy().reshape(50, 50) elevation.shape # (50, 50) elevation[0, 0] # one corner cell elevation[25, :] # row 25: a west-east profile elevation[:, 10] # column 10: a south-north profile
Python
# elevation[row, col] and NOT (x, y) elevation[0, 0] # south-west corner cell elevation[-1, -1] # north-east corner cell elevation[:25, :] # southern half (25, 50) elevation[25:, :] # northern half (25, 50) elevation[:, :10] # western strip (50, 10) elevation[10:15, 20:25].shape # (5, 5) window
The plotting habit of (x, y) fights this all week; say row-column out loud.
Python
temp_f = temp_c * 9 / 5 + 32 # whole 50x50 grid, one line elevation.mean() # one number for the map elevation.mean(axis=0) # 50 column means: a profile elevation.max() - elevation.min() # total relief
?
A flat column of 2,500 values becomes reshape(50, 50). Where does value number 51 land?
A boolean array is a map of where something is true.
Python
high = elevation > np.percentile(elevation, 75) high.sum() # 625 cells high.mean() # 0.25 of the area temperature[high].mean() # 23.5 C, only where high
Python
t25 = np.percentile(temperature, 25) # 22.71 C e75 = np.percentile(elevation, 75) # 247.7 m cool_high = (temperature < t25) & (elevation > e75) either = (temperature < t25) | (elevation > e75) not_cool = ~(temperature < t25) cool_high.sum() # 80 cells 100 * cool_high.mean() # 3.2 % of the map elevation[cool_high].mean() # 250.4 m
Two classic grid mistakes, and the spacing that slope depends on.
Python
fig, ax = plt.subplots(figsize=(6, 5))
image = ax.imshow(elevation, origin="lower", cmap="terrain")
ax.set_xlabel("Grid column")
ax.set_ylabel("Grid row")
fig.colorbar(image, ax=ax, label="Elevation (m)")Python
dx_m = 204.1 # from the x_km column dy_m = 163.3 # from the y_km column, and it differs from dx dz_dy, dz_dx = np.gradient(elevation, dy_m, dx_m) slope = np.sqrt(dz_dx**2 + dz_dy**2) # m per m slope_pct = 100 * slope # percent slope_deg = np.degrees(np.arctan(slope)) # degrees
Without spacing arguments the units are meters per grid cell: physically meaningless.
?
Your slope map has values near 40. Percent, degrees, or meters per cell? How do you know?
Does temperature follow elevation on this grid?
50 x 50 synthetic elevation and temperature grids on the same coordinates.
Flatten both with .ravel(), fit a line with np.polyfit, plot scatter plus fit.
Slope times 100 = an apparent lapse rate in deg C per 100 m, sign included.
This synthetic field warms with height, +0.91 C per 100 m, so the sign is the discussion.
A slice is a subregion of the map: elevation[25:, :] is the north half.
A mask is a map of a condition: where is it steep, high, or cold?
A gradient with real spacing is terrain slope with real units.
| This week | Next week | Bridge idea |
|---|---|---|
| Grids indexed by position | Pandas time series | From cells in space to days in time: the index becomes a date |
?
Name one gridded dataset from your own field. What would a mask of it show, and what would its gradient mean?