Lightsource enhancements

Currently, `colors.LightSource` preforms "hillshading" through methods that appear visually unrealistic in some cases (particularly topographic surfaces).   This pull request:
  1. Refactors `LightSource` to allow the hillshade method to be called independently so that illumination maps can be produced.
  2. Adds support for common parameters such as vertical exaggeration and x/y spacing so that topographically accurate illumination can be calculated. (Or so that the effect of topography can be exaggerated or subdued in the final result.)
  3. Adds support for multiple blend modes to combine the illumination map with the rgb data.  `blend_mode='overlay'` and `blend_mode='soft'` are both more visually appealing for complex surfaces than the default mode.  Effectively, the other blend modes make the surface appear less "shiny".

All of the changes made should be fully backwards-compatible and none of the defaults have been changed.  This also adds a 170Kb example data file of some SRTM elevation data (public domain) to the sample data.

As a quick example of the effect of some of the changes:

```
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.cbook import get_sample_data
from matplotlib.colors import LightSource

dem = np.load(get_sample_data('jacksboro_fault_dem.npz'))
z = dem['elevation']

# Shade from the northwest, with the sun 45 degrees from horizontal
ls = LightSource(azdeg=315, altdeg=45)
cmap = plt.cm.gist_earth

fig, axes = plt.subplots(nrows=4, ncols=3, figsize=(8, 9))
plt.setp(axes.flat, xticks=[], yticks=[])

# Vary vertical exaggeration and blend mode and plot all combinations
for col, ve in zip(axes.T, [0.01, 0.1, 10]):
    # Show the hillshade intensity image for each vert. exag.
    col[0].imshow(ls.hillshade(z, vert_exag=ve), cmap='gray')
    for ax, mode in zip(col[1:], ['hsv', 'overlay', 'soft']):
        rgb = ls.shade(z, cmap=cmap, vert_exag=ve, blend_mode=mode)
        ax.imshow(rgb)

# Label rows and columns
for ax, ve in zip(axes[0], [0.01, 0.1, 10]):
    ax.set_title('{}'.format(ve), size=18)
for ax, mode in zip(axes[:,0], ['Hillshade', 'hsv', 'overlay', 'soft']):
    ax.set_ylabel(mode, size=18)

# Group labels...
axes[0,1].annotate('Vertical Exaggeration', (0.5, 1), xytext=(0, 30), 
                   textcoords='offset points', xycoords='axes fraction', 
                   ha='center', va='bottom', size=20)
axes[2,0].annotate('Blend Mode', (0, 0.5), xytext=(-30, 0), 
                   textcoords='offset points', xycoords='axes fraction', 
                   ha='right', va='center', size=20, rotation=90)
fig.subplots_adjust(bottom=0.05, right=0.95)

plt.show()
```
![figure_3](https://cloud.githubusercontent.com/assets/906803/3667916/01f3bc9c-120f-11e4-873f-53a3bda91a4a.png)

it wouldn't be `dem.close()`, because it is a dictionary of numpy arrays.
It is the cbook.get_sample_data() that returns a file object. So
numpy.load() needs to do the closing, I think.


On Sat, Jul 26, 2014 at 5:21 AM, Jens H Nielsen <notifications@github.com>
wrote:

> In lib/matplotlib/tests/test_colors.py:
>
> > +@image_comparison(baseline_images=['light_source_shading_topo'],
> > +                  extensions=['png'])
> > +def test_light_source_topo_surface():
> > +    """Shades a DEM using different v.e.'s and blend modes."""
> > +    dem = np.load(cbook.get_sample_data('jacksboro_fault_dem.npz'))
> > +
> > +    # Get the true cellsize in meters for accurate vertical exaggeration
> > +    #   Convert from decimal degrees to meters
> > +    dx, dy = dem['dx'], dem['dy']
> > +    dx = 111320.0 * dx * np.cos(dem['ymin'])
> > +    dy = 111320.0 * dy
> > +
> > +    ls = mcolors.LightSource(315, 45)
> > +    elev = dem['elevation']
> > +    cmap = cm.gist_earth
> > +
>
> The test raises a unclosed file warning on python3. Could you add a
> dem.close() statement here when you are done with the file. We are trying
> to reduce the number of warnings in the test suite.
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/matplotlib/matplotlib/pull/3291/files#r15432988>.
>