I am trying to add shading to a map of some data by calculating the gradient of the data and using it to set alpha values.
I start by loading my data (unfortunately I cannot share the data as it is being used in a number of manuscripts in preparation. EDIT - December, 2020: the published paper is available with open access on the Society of Exploration Geophysicists library, and the data is available with an accompanying Jupyter Notebook):
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
from pylab import imread, imshow, gray, mean
import matplotlib.colors as cl
%matplotlib inline
data = np.loadtxt('data.txt')
plt.imshow(data, cmap='cubehelix')
plt.show()
gets me a plot of the data:
Then I calculate the total horizontal gradient and normalize it to use for shading:
dx,dy = np.gradient(data, 1, 1)
tdx=np.sqrt(dx*dx + dy*dy)
tdx_n=(tdx-tdx.min())/(tdx.max()-tdx.min())
tdx_n=1-tdx_n
which looks as I expected:
plt.imshow(tdx_n[4:-3,4:-3], cmap='bone')
plt.show()
To create the shading effect I thought I would get the colour from the plot of the data, then replace the opacity with the gradient so as to have dark shading proportional to the gradient, like this:
img_array = plt.get_cmap('cubehelix')(data[4:-3,4:-3])
img_array[..., 3] = (tdx_n[4:-3,4:-3])
plt.imshow(img_array)
plt.show()
But the result is not what I expected:
This is what I am looking for (created in Matlab, colormap is different):
Any suggestion as to how I may modify my code?
UPDATEDWith Ran Novitsky's method, using the code suggested in the answer by titusjan, I get this result:
which gives the effect I was looking for. In terms of shading though I do like titusjan's own suggestion of using HSV, which gives this result:
.
However, I could not get the colormap to be cubehelix, even though I called for it:
from matplotlib.colors import rgb_to_hsv, hsv_to_rgb
hsv = rgb_to_hsv(img_array[:, :, :3])
hsv[:, :, 2] = tdx_n
rgb = hsv_to_rgb(hsv)
plt.imshow(rgb[4:-3,4:-3], cmap='cubehelix')
plt.show()