title: Issue creating map shading in Matplotlib imshow by setting opacity to data gradient
body: <p>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.</p>
  <p>I start by loading my data (unfortunately I cannot share the data as it is being used in a number of manuscripts in preparation. <strong>EDIT - December, 2020: the published paper is available with open access on the Society of Exploration Geophysicists <a href="https://library.seg.org/doi/epdf/10.1190/tle34080948.1" rel="nofollow noreferrer">library</a>, and the <a href="https://github.com/seg/tutorials-2015/blob/master/1508_Mapping_and_validating_lineaments/continued.txt" rel="nofollow noreferrer">data is available</a> with an accompanying <a href="https://github.com/seg/tutorials-2015/blob/master/1508_Mapping_and_validating_lineaments/1508_Mapping_and_validating_lineaments.ipynb" rel="nofollow noreferrer">Jupyter Notebook</a>):</strong></p>
  <pre><code>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()
  </code></pre>
  <p>gets me a plot of the data:
  <img src="https://i.stack.imgur.com/HRIGU.png" alt="data" /></p>
  <p>Then I calculate the total horizontal gradient and normalize it to use for shading:</p>
  <pre><code>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
  </code></pre>
  <p>which looks as I expected:</p>
  <pre><code>plt.imshow(tdx_n[4:-3,4:-3],  cmap='bone')
  plt.show()
  </code></pre>
  <p><img src="https://i.stack.imgur.com/WieU1.png" alt="gradient" /></p>
  <p>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:</p>
  <pre><code>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()
  </code></pre>
  <p>But the result is not what I expected:
  <img src="https://i.stack.imgur.com/8tNAN.png" alt="shading" /></p>
  <p>This is what I am looking for (created in Matlab, colormap is different):
  <img src="https://i.stack.imgur.com/SDsJ9.png" alt="shading Matlab" /></p>
  <p>Any suggestion as to how I may modify my code?</p>
  UPDATED
  <p>With Ran Novitsky's method, using the code suggested in the answer by titusjan, I get this result:
  <img src="https://i.stack.imgur.com/VaAMV.png" alt="pegtop" /></p>
  <p>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:
  <img src="https://i.stack.imgur.com/8abNu.png" alt="titusjans" />.</p>
  <p>However, I could not get the colormap to be cubehelix, even though I called for it:</p>
  <pre><code>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()
  </code></pre>