title: different colormaps for different ranges of values in 2d array
body: <p>I have a 2d array that I am trying to plot. Im currently using imshow and matplotlib. The array contains values from -4000 to 1. There are no zeros (and nothing closer to zero than 1). Basically it can be imagined as a relief/topography, negative values for beneath ocean level, positive for land.</p>
  <p>Now I would like to plot all negative values with a blue colormap (something like the 'Blues' colormap in matplotlib <a href="https://matplotlib.org/stable/tutorials/colors/colormaps.html" rel="nofollow noreferrer">https://matplotlib.org/stable/tutorials/colors/colormaps.html</a> ) and something like 'Oranges' for positive values. So the desired result is an image with all negative values blue, the darker the more negative, and all positive values colored orange with a clear distinction in color, i.e. if possible the cmap should not go all the way to white like 'Blues' but only to a light blue.</p>
  <p>I have tried this <a href="https://stackoverflow.com/questions/23994020/colorplot-that-distinguishes-between-positive-and-negative-values">Colorplot that distinguishes between positive and negative values</a> but I was not able to achieve the desired result. I also checked this <a href="https://matplotlib.org/stable/gallery/color/custom_cmap.html#sphx-glr-gallery-color-custom-cmap-py" rel="nofollow noreferrer">https://matplotlib.org/stable/gallery/color/custom_cmap.html#sphx-glr-gallery-color-custom-cmap-py</a> but again it did not result in what I wanted. Another solution I had in mind was turning my array into two arrays, one for positive and one for negative values, and then plot them in the same fig with different cmaps but it always takes the same cmap.</p>
  <p>Edit: Here are a few snippets of my attempts, incl. the two suggestions by Jody Klymak and JohanC. The two suggested solutions work pretty well, the only problem I am still getting is that contiguous regions of land=1 are not filled with one color but have white squares in them or are only dotted with orange.</p>
  <pre><code>current_cmap = mpl.cm.get_cmap('Blues_r').copy()  
  new_cmap = current_cmap
  maee = np.ma.masked_where(GD1 == 1, GD1)
  new_cmap.set_bad(color='brown')
  plt.imshow(maee, cmap=blue_red3, interpolation='bilinear')
  plt.colorbar()
  plt.show()
  plt.clf()
  
  norm = colors.TwoSlopeNorm(vmin=-4000., vcenter=0., vmax=1)
  cmap1 = mpl.cm.get_cmap('Blues_r').copy()
  cmap1.set_over(color='brown')
  plt.imshow(GD1, cmap=cmap1, interpolation='bilinear', vmax=-5)
  plt.colorbar()
  plt.show()
  plt.clf()
  
  cmap = LinearSegmentedColormap.from_list('custom blue', ['blue','lightblue'], N=256)
  cmap.set_over('brown')
  plt.imshow(GD1, cmap=cmap, vmax=-5)
  plt.colorbar()
  plt.show()
  plt.clf()
  
  plt.contourf(GD1, cmap=cmap1, vmax=-5)
  plt.colorbar()
  plt.show()
  plt.clf()
  
  GD1[GD1 == 1] = 4000
  plt.imshow(GD1, cmap='RdBu_r', vmax=4000, vmin=-4000, interpolation='bilinear')
  plt.colorbar()
  plt.show()
  plt.clf()
  
  m1 = np.ma.masked_where(GD1 &gt; 0, GD1)
  cmap2 = mpl.cm.get_cmap('Blues_r').copy()
  cmap2.set_bad('brown')
  plt.imshow(m1, cmap=cmap2, interpolation='bilinear', norm=norm)
  plt.colorbar()
  plt.show()
  plt.clf()
  </code></pre>
  <p>My data comes from datasets that are then put into an array. Sort of along these lines (this can not reproduce my problem):</p>
  <pre><code>shape = (180, 360)
  
  # a = np.random.randint(-4000,1,shape).astype(float)
  # a[a&gt;-3500] = np.nan
  a=np.empty(shape)
  a[:] = np.nan
  a[0:10,0:360] = 1
  a[10:75,100:250] = 1
  a[50:75,100:125] = np.nan
  a[10:100,50:51] = -4000
  a[100:150,60:65] = -500
  a[150:152,100:300] = -500
  
  
  plt.imshow(a,interpolation='nearest')
  plt.colorbar()
  plt.show()
  
  array = np.ma.masked_invalid(a)
  
  x = np.arange(0, array.shape[1])
  y = np.arange(0, array.shape[0])
  
  xx, yy = np.meshgrid(x, y)
  x1 = xx[~array.mask]
  y1 = yy[~array.mask]
  newarr = array[~array.mask]
  
  GD1 = interpolate.griddata((x1, y1), newarr.ravel(), (xx, yy), method='linear')
  </code></pre>
  <p>(interpolation taken from <a href="https://stackoverflow.com/questions/37662180/interpolate-missing-values-2d-python">interpolate missing values 2d python</a>). I also had the thought that the interpolation was the problem and not the plotting but when I save the array as a csv and go through the said regions, they don't have any holes, i.e. the regions are filled contiguously with 1s.</p>