I’ve found matplotlib to be a very nice tool. In particular, I’ve been using the LightSource class in colors.py.
However, LightSource.shade always uses the array min and max to set the minimum and maximum colormap values. I’d like to be able to manually set minimum and maximum values used in the colormap, and I’d also be like to limit the elevation for the shading algorithm. I have three use cases:
(1) comparing related images, which is much easier to do when the colormaps are constant
(2) cases where I have very high or very low values
(3) cases where I’ve used the set_over or set_under methods of the colormap because low and/or high values are significant.
Since it was fairly easy to modify this code myself, I did so. This modification might be useful to other people, too, so I was wondering if it would be possible to modify LightSource.shade similar to the code below.
def shade(self,data,cmap,vmin=None,vmax=None,limit_elevation=False):
"""
Take the input data array, convert to HSV values in the
given colormap, then adjust those color values
to given the impression of a shaded relief map with a
specified light source.
RGBA values are returned, which can then be used to
plot the shaded image with imshow.
Parameters
colors.py (44.4 KB)
shading2.py (1.38 KB)
shading3.py (1.5 KB)
shading4.py (1.66 KB)
···
----------
data Input data array
vmin Minimum data value for colormap. Default min(data).
vmax Maximum data value for colormap. Default max(data).
limit_elevation Limit the elevation in the shading routine? Default False.
If true, the elevation will be limited by vmin and vmax.
Returns
-------
rgb Shaded RGBA values, suitable for use with imshow.
"""
if (vmin is not None) or (vmax is not None):
limitschanged = True
else:
limitschanged = False
if vmin is None:
vmin = np.min(data)
if vmax is None:
vmax = np.max(data)
rgb0 = cmap((data-vmin)/(np.float(vmax-vmin)))
#avoid using extra memory if copy of array not needed
if limitschanged and limit_elevation:
d = data.copy()
d[d<vmin] = vmin
d[d>vmax] = vmax
rgb1 = self.shade_rgb(rgb0, elevation=d)
else:
rgb1 = self.shade_rgb(rgb0, elevation=data)
rgb0[:,:,0:3] = rgb1
return rgb0
I’ve attached a colors.py with a modified LightSource.shade and some examples (shading3.py and shading4.py) that use the modifications to shade.
This is the first time I’ve suggested a change to matplotlib, so please let me know if there was a better way to make this suggestion.
Regards,
Kathy