Skip to content

Commit 71cb786

Browse files
committed
Added more examples
1 parent bdbc7df commit 71cb786

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
"""
2+
Demonstrates a few common tricks with shaded plots.
3+
"""
4+
import numpy as np
5+
import matplotlib.pyplot as plt
6+
from matplotlib.colors import LightSource, Normalize
7+
8+
def display_colorbar():
9+
"""Display a correct numeric colorbar for a shaded plot."""
10+
y, x = np.mgrid[-4:2:200j, -4:2:200j]
11+
z = 10 * np.cos(x**2 + y**2)
12+
13+
cmap = plt.cm.copper
14+
ls = LightSource(315, 45)
15+
rgb = ls.shade(z, cmap)
16+
17+
fig, ax = plt.subplots()
18+
ax.imshow(rgb)
19+
20+
# Use a proxy artist for the colorbar...
21+
im = ax.imshow(z, cmap=cmap)
22+
im.remove()
23+
fig.colorbar(im)
24+
25+
ax.set_title('Using a colorbar with a shaded plot', size='x-large')
26+
27+
def avoid_outliers():
28+
"""Use a custom norm to control the displayed z-range of a shaded plot."""
29+
y, x = np.mgrid[-4:2:200j, -4:2:200j]
30+
z = 10 * np.cos(x**2 + y**2)
31+
32+
# Add some outliers...
33+
z[100, 105] = 2000
34+
z[120, 110] = -9000
35+
36+
ls = LightSource(315, 45)
37+
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(8, 4.5))
38+
39+
rgb = ls.shade(z, plt.cm.copper)
40+
ax1.imshow(rgb)
41+
ax1.set_title('Full range of data')
42+
43+
rgb = ls.shade(z, plt.cm.copper, norm=Normalize(-10, 10)) # Note the norm!!
44+
ax2.imshow(rgb)
45+
ax2.set_title('Manually set range')
46+
47+
fig.suptitle('Avoiding Outliers in Shaded Plots', size='x-large')
48+
49+
def shade_other_data():
50+
"""Demonstrates displaying different variables through shade and color."""
51+
y, x = np.mgrid[-4:2:200j, -4:2:200j]
52+
z1 = np.sin(x**2) # Data to hillshade
53+
z2 = np.cos(x**2 + y**2) # Data to color
54+
55+
norm=Normalize(z2.min(), z2.max())
56+
cmap = plt.cm.jet
57+
58+
ls = LightSource(315, 45)
59+
rgb = ls.shade_rgb(cmap(norm(z2)), z1)
60+
61+
fig, ax = plt.subplots()
62+
ax.imshow(rgb)
63+
ax.set_title('Shade by one variable, color by another', size='x-large')
64+
65+
display_colorbar()
66+
avoid_outliers()
67+
shade_other_data()
68+
plt.show()
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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

Comments
 (0)