Varlor
Varlor

Reputation: 1471

Python Logarithmic Colormap/palette

I want to use a colormap where the color difference for high values is high and for the rest of my values not differing a lot. I think a logarithmic colormap would be the best way to do it. I want to plot a heatmap, not matter if in matplotlib, seaborn, plotly.

The examples for creating a logarithmic colormap like here are always creating a meshgrid, and getting something for X and Y, but I just have a 2d array(which represents an image). : https://matplotlib.org/3.1.0/gallery/images_contours_and_fields/pcolor_demo.html#sphx-glr-gallery-images-contours-and-fields-pcolor-demo-py:

N = 100
X, Y = np.mgrid[-3:3:complex(0, N), -2:2:complex(0, N)]

# A low hump with a spike coming out.
# Needs to have z/colour axis on a log scale so we see both hump and spike.
# linear scale only shows the spike.
Z1 = np.exp(-(X)**2 - (Y)**2)
Z2 = np.exp(-(X * 10)**2 - (Y * 10)**2)
Z = Z1 + 50 * Z2

fig, (ax0, ax1) = plt.subplots(2, 1)

c = ax0.pcolor(X, Y, Z,
               norm=LogNorm(vmin=Z.min(), vmax=Z.max()), cmap='PuBu_r')
fig.colorbar(c, ax=ax0)

c = ax1.pcolor(X, Y, Z, cmap='PuBu_r')
fig.colorbar(c, ax=ax1)

plt.show()

Also like in this post : Second example for logaithmic colormap

So what would be the way to do it if I just have an image/2d array like a=np.array([[0,2,3],[4,5,6],[7,8,9]]) for example?

Upvotes: 0

Views: 6133

Answers (1)

Diziet Asahi
Diziet Asahi

Reputation: 40697

a = np.array([[1,2,3],[4,5,6],[7,8,9]])
plt.imshow(a, norm=matplotlib.colors.LogNorm(vmin=a.min(), vmax=a.max()))
plt.colorbar()

enter image description here

If you have values that are not strictly positive, you need to mask them first, here replacing them by nan:

a = np.array([[-1,0,1],[4,5,6],[7,8,9]])
b = np.where(a>0,a,np.nan)

cmap = plt.cm.get_cmap("viridis")
cmap.set_bad("magenta")

plt.imshow(b, norm=matplotlib.colors.LogNorm(vmin=np.nanmin(b), vmax=np.nanmax(b)), cmap=cmap)
plt.colorbar()

enter image description here

Upvotes: 4

Related Questions