shadem documentation

The great Roger Miller once sang, As long as there's a hill there's a valley / Long as there's a valley then the river can flow free / As long as there's a Sun there's a shadow / As long as there's a shadow there's a place for you and me. While it's possible that he was referring to sneakin' around with some little lover, it's just as likely that he was singing praises of shadem, this hill-shading function for Matlab.

shadem adjusts lighting to give a sense of depth to the display of gridded elevation data. Although it was designed for use with the Matlab's Mapping Toolbox, this function can just as easily be used for pcolor or surface plots of any type and the Mapping Toolbox is not required.

Matlab's Mapping Toolbox is packaged with several sub-par functions that are intended to create shaded relief maps, but the built-in shading functions are difficult to use, create unattractive maps, and cannot be used with a colorbar.

Where surflsrm, surflm, shaderel, and meshlsrm each require an iterative process of guess-and-check to determine visually appealing lighting azimuth and elevation, shadem allows interaction with the map from the mouse and keyboard: Sunlight comes from wherever you click on your map, and intensity of the shading effect can be adjusted by pressing the up and down keys.

Back to Climate Data Tools Contents.

Contents

Syntax

shadem
shadem('ui')
shadem(...,LightAngle)
shadem(...,LightingType)
shadem(...,MaterialType)
shadem(...,gain)
shadem(...,'sun')
shadem(...,'obj',ObjectHandle)
[lighth,MaterialType,gain,LightingType,LightAngle] = shadem(...)
shadem('reset')

Description

shadem applies simple lighting to surfaces and patch objects on the current axes.

shadem('ui') illuminates the current axes and opens a user interface. When the user interface is running, controls are as follows

shadem(...,LightAngle) specifies LightAngle as a two-element array in the form [az el], where az is the azimuthal (horizontal) rotation of the light source and el is the vertical elevation of the light source. 0 azimuth lies at the six o'clock position on the map and positive degrees move counterclockwise around the map. An elevation of 90 degrees places light source directly above the map, creating a "high noon" type of shadow, whereas elevation angles closer to zero degrees create "sunrise" or "sunset" shadows. Interpretation of azimuth and elevation is the same as that of the view or lightangle commands. Default LightAngle is [90 45]. Any two-element array input to the shadem function is assumed to be a declaration of LightAngle.

shadem(...,LightingType) selects the algorithm used to calculate the effects of light objects on all surface and patch objects in the current axes. Options are

shadem(...,MaterialType) sets lighting characteristics of surface and patch objects. MaterialType can be

shadem(...,gain) specifies intensity of shading by exaggerating or minimizing the z component of the active surface. This is helpful when x and y coordinates of data mapping might range from -0.5 to 0.5 map units, while z data ranges from -4000 to 3000 meters. Default gain is 0. Negative gain values reduce the hillshading effect; positive values increase the effect. Any scalar input to shadem is interpreted as a gain value.

shadem(...,'sun') sets color of the lighting object as a function of light elevation angle to mimic the color of sunlight at sunrise/sunset, noon, or any angle in between.

shadem(...,'obj',ObjectHandle) specifies a surface object as a target when multiple surface objects exist in the current set of axes. This usage is a bit clunky, may result in strange maps, and is not fully endorsed by the author of the function. Nonetheless, the ability to specify an active surface sometimes helps the author of this function, and he thinks that maybe sometimes it could help you too.

[lighth,MaterialType,gain,LightingType,LightAngle] = shadem(...) returns a handle of the lightangle object lighth, MaterialType, gain value, LightingType, and LightAngle azimuth and elevation.

shadem('reset') resets shading by deleting light objects. Note that this may not completely undo all settings put in place by previous calls of shadem. In some cases this program alters z data values, and the 'reset' command does not return z values to their original state.

Example 1: 2D pcolor

Consider this gridded surface:

pcolor(repmat(peaks,2))
shading interp
colorbar

Use shadem to give the surface a sense of depth, and make it shiny:

shadem shiny

Example 2: 3D surf

This program also works with 3D data.

figure
surf(peaks)
shading interp

Apply shadem with Matlab's 'default' material propterties. Let light enter from 60 degrees in the horizontal at 50 degrees elevation:

shadem([60 50])

Example 3: Global topography, unprojected coordinates

For this example, use cdtgrid to make a quarter-degree global grid and topo_interp to get the corresponding topography. Set the colormap with cmocean:

% quarter-degree lat,lon grid:
[lat,lon] = cdtgrid(1/4);

% global topography:
z = topo_interp(lat,lon);
%
figure
pcolor(lon,lat,z)
shading interp
cmocean('topo','pivot') % sets the colormap

Add hillshade to the global topography map like this

shadem(-17,[225 80])

In the figure above, we used a gain value of -17. The amount of gain you use is related to how the units of x and y (in the case above, lon and lat) compare to the units of z. If x,y, and z are all in the same units, a gain value of zero might be appropriate.

Example 4: Adding another variable

Hillshade is great for providing context, so even when topography isn't the main point of a map, you can still use relief shading to show how a variable interacts with topography. Case in point: the plot above depicts topography both with hillshade, and with the cmocean topo colormap. But even if we take the colormap away, the relief shading is still evident. here's the same map as above, but setting the colormap to pure white:

colormap([1 1 1])

So perhaps you have some other variable you're really trying to put into perspective. For example, the distance to the nearest coast line, which can be obtained with dist2coast. For the same grid as Example 3, get the distances to the coast, and use island to set the land values to negative distances:

% Get distances to the coast for the grid from example 3:
D = dist2coast(lat,lon);

% Set land values to negative:
land = island(lat,lon);
D(land) = -D(land);

figure
surf(lon,lat,z,D)
shading interp
view(2)
axis tight
cmocean('balance','pivot')
cb = colorbar;
ylabel(cb,'distance to nearest coast (km)')

Now use shadem to put that map in the context of global topography:

shadem(-19)

Example 5: Global topography with Matlab's Mapping Toolbox

If you have Matlab's mapping toolbox, repeat Example 3, but for a worldmap:

figure
worldmap('world')
cla % removes grid lines
pcolorm(lat,lon,z)
cmocean('topo','pivot')
shadem(7,[225 75])

Known Issue

I have received feedback that the LightAngle cannot be adjusted when using the Mapping Toolbox with Matlab release R2014b. As I understand it, this bug only affects the Mapping Toobox release 2014b and has been fixed in R2015a.

Author Info

The shadem function and supporting documentation were created by Chad A. Greene of the University of Texas at Austin's Institute for Geophysics (UTIG). January 2015.