How to create a heat-map with multiple colormaps?

笑着哭i 提交于 2021-01-27 19:05:23

问题


As illustrated below, I am looking for an easy way to combine two or more heat-maps into one, i.e., a heat-map with multiple colormaps.

The idea is to break each cell into multiple sub-cells. I couldn't find any python library with such a visualization function already implemented. Anybody knows something (at least) close to this?


回答1:


The heatmaps can be drawn column by column. White gridlines can mark the cell borders.

import numpy as np
from matplotlib import pyplot as plt

a = np.random.random((5, 6))
b = np.random.random((5, 6))
vmina = a.min()
vminb = b.min()
vmaxa = a.max()
vmaxb = b.max()

fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(10,3), gridspec_kw={'width_ratios':[1,1,2]})

ax1.imshow(a, cmap='Reds', interpolation='nearest', origin='lower', vmin=vmina, vmax=vmaxa)
ax1.set_xticks(np.arange(.5, a.shape[1]-1, 1), minor=True)
ax1.set_yticks(np.arange(.5, a.shape[0]-1, 1), minor=True)

ax2.imshow(b, cmap='Blues', interpolation='nearest', origin='lower', vmin=vminb, vmax=vmaxb)
ax2.set_xticks(np.arange(.5, a.shape[1]-1, 1), minor=True)
ax2.set_yticks(np.arange(.5, a.shape[0]-1, 1), minor=True)

for i in range(a.shape[1]):
    ax3.imshow(a[:,i:i+1], extent=[2*i-0.5, 2*i+0.5, -0.5, a.shape[0]-0.5 ],
               cmap='Reds', interpolation='nearest', origin='lower', vmin=vmina, vmax=vmaxa)
    ax3.imshow(b[:,i:i+1], extent=[2*i+0.5, 2*i+1.5, -0.5, a.shape[0]-0.5 ],
               cmap='Blues', interpolation='nearest', origin='lower', vmin=vminb, vmax=vmaxb)
ax3.set_xlim(-0.5, 2*a.shape[1] -0.5 )
ax3.set_xticks(np.arange(1.5, 2*a.shape[1]-1, 2), minor=True)
ax3.set_yticks(np.arange(.5, a.shape[0]-1, 1), minor=True)

for ax in (ax1, ax2, ax3):
    ax.grid(color='white', which='minor', lw=2)
    ax.set_xticks([])
    ax.set_yticks([])
    ax.tick_params(axis='both', which='both', size=0)

plt.show()

PS: If brevity were an important factor, all embellishments, details and comparisons could be left out:

# import numpy as np
# from matplotlib import pyplot as plt

a = np.random.random((5, 6))
b = np.random.random((5, 6))
norma = plt.Normalize(vmin=a.min(), vmax=a.max())
normb = plt.Normalize(vmin=b.min(), vmax=b.max())

for i in range(a.shape[1]):
    plt.imshow(a[:, i:i + 1], extent=[2*i-0.5, 2*i+0.5, -0.5, a.shape[0]-0.5], cmap='Reds', norm=norma)
    plt.imshow(b[:, i:i + 1], extent=[2*i+0.5, 2*i+1.5, -0.5, a.shape[0]-0.5], cmap='Blues', norm=normb)
plt.xlim(-0.5, 2*a.shape[1]-0.5)
# plt.show()



回答2:


You can restructure your arrays to have empty columns between you actual data then create a masked array to plot heatmaps with transparency. Here's one method (maybe not the best) to add empty columns:

arr1 = np.arange(20).reshape(4, 5)
arr2 = np.arange(20, 0, -1).reshape(4, 5)
filler = np.nan * np.zeros((4, 5))

c1 = np.vstack([arr1, filler]).T.reshape(10, 4).T
c2 = np.vstack([filler, arr2]).T.reshape(10, 4).T
c1 = np.ma.masked_array(c1, np.isnan(c1))
c2 = np.ma.masked_array(c2, np.isnan(c2))

plt.pcolormesh(c1, cmap='bone')
plt.pcolormesh(c2, cmap='jet')

You can also use np.repeat and mask every other column as @JohanC notes

c1 = np.ma.masked_array(np.repeat(arr1, 2, axis=1), np.tile([True, False], arr1.size))
c2 = np.ma.masked_array(np.repeat(arr2, 2, axis=1), np.tile([False, True], arr2.size))



来源:https://stackoverflow.com/questions/61036609/how-to-create-a-heat-map-with-multiple-colormaps

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!