| 
 | 1 | +"""  | 
 | 2 | +Demonstrates the visual effect of varying blend mode and vertical exaggeration  | 
 | 3 | +on "hillshaded" plots.  | 
 | 4 | +
  | 
 | 5 | +Note that the "overlay" and "soft" blend modes work well for complex surfaces  | 
 | 6 | +such as this example, while the default "hsv" blend mode works best for smooth  | 
 | 7 | +surfaces such as many mathematical functions.  | 
 | 8 | +
  | 
 | 9 | +In most cases, hillshading is used purely for visual purposes, and *dx*/*dy*  | 
 | 10 | +can be safely ignored. In that case, you can tweak *vert_exag* (vertical  | 
 | 11 | +exaggeration) by trial and error to give the desired visual effect. However,  | 
 | 12 | +this example demonstrates how to use the *dx* and *dy* kwargs to ensure that  | 
 | 13 | +the *vert_exag* parameter is the true vertical exaggeration.  | 
 | 14 | +"""  | 
 | 15 | +import numpy as np  | 
 | 16 | +import matplotlib.pyplot as plt  | 
 | 17 | +from matplotlib.cbook import get_sample_data  | 
 | 18 | +from matplotlib.colors import LightSource  | 
 | 19 | + | 
 | 20 | +dem = np.load(get_sample_data('jacksboro_fault_dem.npz'))  | 
 | 21 | +z = dem['elevation']  | 
 | 22 | + | 
 | 23 | +#-- Optional dx and dy for accurate vertical exaggeration --------------------  | 
 | 24 | +# If you need topographically accurate vertical exaggeration, or you don't want  | 
 | 25 | +# to guess at what *vert_exag* should be, you'll need to specify the cellsize  | 
 | 26 | +# of the grid (i.e. the *dx* and *dy* parameters).  Otherwise, any *vert_exag*  | 
 | 27 | +# value you specify will be realitive to the grid spacing of your input data  | 
 | 28 | +# (in other words, *dx* and *dy* default to 1.0, and *vert_exag* is calculated  | 
 | 29 | +# relative to those parameters).  Similarly, *dx* and *dy* are assumed to be in  | 
 | 30 | +# the same units as your input z-values.  Therefore, we'll need to convert the  | 
 | 31 | +# given dx and dy from decimal degrees to meters.  | 
 | 32 | +dx, dy = dem['dx'], dem['dy']  | 
 | 33 | +dy = 111200 * dy  | 
 | 34 | +dx = 111200 * dx * np.cos(np.radians(dem['ymin']))  | 
 | 35 | +#-----------------------------------------------------------------------------  | 
 | 36 | + | 
 | 37 | +# Shade from the northwest, with the sun 45 degrees from horizontal  | 
 | 38 | +ls = LightSource(azdeg=315, altdeg=45)  | 
 | 39 | +cmap = plt.cm.gist_earth  | 
 | 40 | + | 
 | 41 | +fig, axes = plt.subplots(nrows=4, ncols=3, figsize=(8, 9))  | 
 | 42 | +plt.setp(axes.flat, xticks=[], yticks=[])  | 
 | 43 | + | 
 | 44 | +# Vary vertical exaggeration and blend mode and plot all combinations  | 
 | 45 | +for col, ve in zip(axes.T, [0.1, 1, 10]):  | 
 | 46 | +    # Show the hillshade intensity image in the first row  | 
 | 47 | +    col[0].imshow(ls.hillshade(z, vert_exag=ve, dx=dx, dy=dy), cmap='gray')  | 
 | 48 | + | 
 | 49 | +    # Place hillshaded plots with different blend modes in the rest of the rows  | 
 | 50 | +    for ax, mode in zip(col[1:], ['hsv', 'overlay', 'soft']):  | 
 | 51 | +        rgb = ls.shade(z, cmap=cmap, blend_mode=mode,  | 
 | 52 | +                       vert_exag=ve, dx=dx, dy=dy)  | 
 | 53 | +        ax.imshow(rgb)  | 
 | 54 | + | 
 | 55 | +# Label rows and columns  | 
 | 56 | +for ax, ve in zip(axes[0], [0.1, 1, 10]):  | 
 | 57 | +    ax.set_title('{}'.format(ve), size=18)  | 
 | 58 | +for ax, mode in zip(axes[:,0], ['Hillshade', 'hsv', 'overlay', 'soft']):  | 
 | 59 | +    ax.set_ylabel(mode, size=18)  | 
 | 60 | + | 
 | 61 | +# Group labels...  | 
 | 62 | +axes[0,1].annotate('Vertical Exaggeration', (0.5, 1), xytext=(0, 30),  | 
 | 63 | +                   textcoords='offset points', xycoords='axes fraction',  | 
 | 64 | +                   ha='center', va='bottom', size=20)  | 
 | 65 | +axes[2,0].annotate('Blend Mode', (0, 0.5), xytext=(-30, 0),  | 
 | 66 | +                   textcoords='offset points', xycoords='axes fraction',  | 
 | 67 | +                   ha='right', va='center', size=20, rotation=90)  | 
 | 68 | +fig.subplots_adjust(bottom=0.05, right=0.95)  | 
 | 69 | + | 
 | 70 | +plt.show()  | 
0 commit comments