Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4faa454

Browse files
committed
Added support for vertical exag and non-uniform spacing to LightSource
1 parent ee99cf5 commit 4faa454

1 file changed

Lines changed: 98 additions & 12 deletions

File tree

lib/matplotlib/colors.py

Lines changed: 98 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1516,6 +1516,16 @@ def hillshade(self, elevation, vert_exag=1, dx=1, dy=1, fraction=1.):
15161516
elevation : array-like
15171517
A 2d array (or equivalent) of the height values used to generate an
15181518
illumination map
1519+
vert_exag : number, optional
1520+
The amount to exaggerate the elevation values by when calculating
1521+
illumination. This can be used either to correct for differences in
1522+
units between the x-y coordinate system and the elevation
1523+
coordinate system (e.g. decimal degrees vs meters) or to exaggerate
1524+
or de-emphasize topographic effects.
1525+
dx : number, optional
1526+
The x-spacing (columns) of the input *elevation* grid.
1527+
dy : number, optional
1528+
The y-spacing (rows) of the input *elevation* grid.
15191529
fraction : number, optional
15201530
Increases or decreases the contrast of the hillshade. Values
15211531
greater than one will cause intermediate values to move closer to
@@ -1537,7 +1547,12 @@ def hillshade(self, elevation, vert_exag=1, dx=1, dy=1, fraction=1.):
15371547
az = np.radians(90 - self.azdeg)
15381548
alt = np.radians(self.altdeg)
15391549

1540-
dy, dx = np.gradient(elevation)
1550+
# Because most image and raster GIS data has the first row in the array
1551+
# as the "top" of the image, dy is implicitly negative. This is
1552+
# consistent to what `imshow` assumes, as well.
1553+
dy = -dy
1554+
1555+
dy, dx = np.gradient(vert_exag * elevation, dy, dx)
15411556
slope = 0.5 * np.pi - np.arctan(np.hypot(dx, dy))
15421557
aspect = np.arctan2(dx, dy)
15431558
intensity = (np.sin(alt) * np.sin(slope)
@@ -1552,30 +1567,101 @@ def hillshade(self, elevation, vert_exag=1, dx=1, dy=1, fraction=1.):
15521567
np.clip(intensity, 0, 1, intensity)
15531568
return intensity
15541569

1555-
def shade(self, data, cmap, norm=None, **kwargs):
1556-
"""
1557-
Take the input data array, convert to HSV values in the
1558-
given colormap, then adjust those color values
1559-
to give the impression of a shaded relief map with a
1560-
specified light source.
1561-
RGBA values are returned, which can then be used to
1562-
plot the shaded image with imshow.
1570+
def shade(self, data, cmap, norm=None, vert_exag=1, dx=1, dy=1, fraction=1,
1571+
**kwargs):
15631572
"""
1573+
Combine colormapped data values with an illumination intensity map
1574+
(a.k.a. "hillshade") of the values.
15641575
1576+
Parameters
1577+
----------
1578+
data : array-like
1579+
A 2d array (or equivalent) of the height values used to generate a
1580+
shaded map.
1581+
cmap : `~matplotlib.colors.Colormap` instance
1582+
The colormap used to color the *data* array. Note that this must be
1583+
a `~matplotlib.colors.Colormap` instance. For example, rather than
1584+
passing in `cmap='gist_earth'`, use
1585+
`cmap=plt.get_cmap('gist_earth')` instead.
1586+
norm : `~matplotlib.colors.Normalize` instance, optional
1587+
The normalization used to scale values before colormapping. If
1588+
None, the input will be linearly scaled between its min and max.
1589+
vert_exag : number, optional
1590+
The amount to exaggerate the elevation values by when calculating
1591+
illumination. This can be used either to correct for differences in
1592+
units between the x-y coordinate system and the elevation
1593+
coordinate system (e.g. decimal degrees vs meters) or to exaggerate
1594+
or de-emphasize topography.
1595+
dx : number, optional
1596+
The x-spacing (columns) of the input *elevation* grid.
1597+
dy : number, optional
1598+
The y-spacing (rows) of the input *elevation* grid.
1599+
fraction : number, optional
1600+
Increases or decreases the contrast of the hillshade. Values
1601+
greater than one will cause intermediate values to move closer to
1602+
full illumination or shadow (and clipping any values that move
1603+
beyond 0 or 1). Values less than one will cause full shadow or
1604+
full illumination to move closer to a value of 0.5, thereby
1605+
decreasing contrast. Note that this is not mathematically or
1606+
visually the same as increasing/decreasing the vertical
1607+
exaggeration.
1608+
Additional kwargs are passed on to the *blend_mode* function.
1609+
1610+
Returns
1611+
-------
1612+
rgba : ndarray
1613+
An MxNx4 array of floats ranging between 0-1.
1614+
"""
15651615
if norm is None:
15661616
norm = Normalize(vmin=data.min(), vmax=data.max())
15671617

15681618
rgb0 = cmap(norm(data))
1569-
rgb1 = self.shade_rgb(rgb0, elevation=data, **kwargs)
1570-
rgb0[:, :, 0:3] = rgb1
1619+
rgb1 = self.shade_rgb(rgb0, elevation=data, blend_mode=blend_mode,
1620+
vert_exag=vert_exag, dx=dx, dy=dy, **kwargs)
1621+
# Don't overwrite the alpha channel, if present.
1622+
rgb0[..., :3] = rgb1[..., :3]
15711623
return rgb0
15721624

1573-
def shade_rgb(self, rgb, elevation, fraction=1., **kwargs):
1625+
def shade_rgb(self, rgb, elevation, fraction=1., vert_exag=1, dx=1, dy=1,
1626+
**kwargs):
15741627
"""
15751628
Take the input RGB array (ny*nx*3) adjust their color values
15761629
to given the impression of a shaded relief map with a
15771630
specified light source using the elevation (ny*nx).
15781631
A new RGB array ((ny*nx*3)) is returned.
1632+
1633+
Parameters
1634+
----------
1635+
rgb : array-like
1636+
An MxNx3 RGB array, assumed to be in the range of 0 to 1.
1637+
elevation : array-like
1638+
A 2d array (or equivalent) of the height values used to generate a
1639+
shaded map.
1640+
fraction : number
1641+
Increases or decreases the contrast of the hillshade. Values
1642+
greater than one will cause intermediate values to move closer to
1643+
full illumination or shadow (and clipping any values that move
1644+
beyond 0 or 1). Values less than one will cause full shadow or
1645+
full illumination to move closer to a value of 0.5, thereby
1646+
decreasing contrast. Note that this is not mathematically or
1647+
visually the same as increasing/decreasing the vertical
1648+
exaggeration.
1649+
vert_exag : number, optional
1650+
The amount to exaggerate the elevation values by when calculating
1651+
illumination. This can be used either to correct for differences in
1652+
units between the x-y coordinate system and the elevation
1653+
coordinate system (e.g. decimal degrees vs meters) or to exaggerate
1654+
or de-emphasize topography.
1655+
dx : number, optional
1656+
The x-spacing (columns) of the input *elevation* grid.
1657+
dy : number, optional
1658+
The y-spacing (rows) of the input *elevation* grid.
1659+
Additional kwargs are passed on to :meth:`blend_hsv`.
1660+
1661+
Returns
1662+
-------
1663+
shaded_rgb : ndarray
1664+
An MxNx3 array of floats ranging between 0-1.
15791665
"""
15801666
intensity = self.hillshade(elevation, fraction=fraction)
15811667
return self.blend_hsv(rgb, intensity, **kwargs)

0 commit comments

Comments
 (0)