Setting Discrete Colors in Matplotlib Imshow

Question:

I have seen numerous resources for establishing unique cmap color codes, such as:

i) Merge colormaps in matplotlib

ii) Python: Invalid RGBA argument 0.0 color points according to class

iii) Defining a discrete colormap for imshow in matplotlib

None of these quite answer my question. I have 900 rows and each row has 200 data points that are either 1 or 0. In the finished product, the top 20% of the chart should have blue spikes for 1’s and the bottom 80% should have red spikes for 1’s. So y-axis >=720== blue and y-axis <720 = red.

The imshow cmap codes for these colors are plt.cm.Blues and plt.cm.Red

It’s relatively easy to have all the spikes be coded blue:

img0 = raster[0].imshow(spikes, cmap=plt.cm.Blues, origin='lower', aspect="auto")

Spike raster for 900 neurons over 200 time steps

However, when I try to split the coding of cmap, I run into RGB errors related to the format of the input data. My code is below, and any help would be appreciated.

colors1 = plt.cm.Reds(np.linspace(0,1,int(200*900*.8)).reshape(int(900*.8),200))
colors2 = plt.cm.Blues(np.linspace(0,1,int(200*900*.2)).reshape(int(900*.2),200))
cmap = matplotlib.colors.LinearSegmentedColormap.from_list('mycmap', np.append(colors1,colors2))
img0 = raster[0].imshow(spikes, cmap=cmap, origin='lower', aspect="auto")

Final answer that works

img0 = raster[0].imshow(spikes[720:,:], cmap='Blues', extent=[0, 30, 720, 899], origin='lower', aspect="auto")
img0 = raster[0].imshow(spikes[:720,:], cmap='Reds', extent=[0, 30, 0, 719], origin='lower', aspect="auto")
raster[0].set_ylim(0, 900)

Asked By: da Bears

||

Answers:

Based on your comments, all you want is two images with different colormaps on the same axes:


import matplotlib.pyplot as plt
import numpy as np

data = np.random.rand(900, 30)

fig, ax = plt.subplots()
img0 = ax.imshow(data[:720,:], cmap='Blues', vmin=0, vmax=1,
                  extent=[0, 30, 0, 719],
                  origin='lower', aspect="auto")
img1 = ax.imshow(data[720:,:], cmap='Reds', vmin=0, vmax=1,
                  extent=[0, 30, 720, 899],
                  origin='lower', aspect="auto")
ax.set_ylim(0, 900)
plt.show()

enter image description here

Something like

import matplotlib.cm as cm
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import ListedColormap

data = np.random.rand(50, 30) * 900

bottom = cm.get_cmap('Blues', 204)
top = cm.get_cmap('Reds', 52)

newcolors = np.vstack((bottom(np.linspace(0, 1, 204)),
                       top(np.linspace(0, 1, 52))))
newcmp = ListedColormap(newcolors, name='RedBlue')
img0 = plt.imshow(data, cmap=newcmp, vmin=0, vmax= 900,
                        origin='lower', aspect="auto")
plt.colorbar()
plt.show()

enter image description here

Answered By: Jody Klymak
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.