问题
I want to plot a heatmap of fold changes in matplotlib, where the colors are plotted on a log2 scale, and customize which ticks are shown in the colorbar. I tried the following:
import matplotlib.pylab as plt
import numpy as np
import matplotlib.colors
from matplotlib.colors import SymLogNorm, LogNorm
mat1 = np.clip(np.random.normal(20, 10, [20, 20]), a_min=0, a_max=500)
mat2 = np.clip(np.random.normal(10, 5, [20, 20]), a_min=0, a_max=500)
mat = np.clip(mat1 / mat2, a_min=0, a_max=500)
plt.figure()
print mat
cmap = plt.cm.get_cmap("seismic")
ticks = np.array([1/float(50), 1/float(20), 1, 20, 50])
# how to make these ticks spaced out on a log2 and not log10 scale?
plt.pcolormesh(mat, cmap=cmap, norm=SymLogNorm(linthresh=0.01, vmin=1/50., vmax=50.))
p = plt.colorbar(ticks=ticks)
plt.show()
I want fold change of 1 to appear as white so I used the seismic colormap.
Question: How can I make the colors spaced in log2 scale, and not log10? And also have the ticks show up as log2 values rather than the unlogged values?
If I try to use LogNorm
instead of SymLogNorm
then the tick labels and my ticks do not show up:
# This does not work -- ticks do not show
plt.pcolormesh(mat, cmap=cmap, norm=LogNorm(vmin=1/50., vmax=50.))
p = plt.colorbar(ticks=ticks)
I know SymLogNorm
is meant for negative data (which I don't have). I only used it because of this tick issue with LogNorm
回答1:
You could set the locator
of the colorbar
object to a LogLocator
with a base of 2. You then need to call p.update_ticks()
.
plt.pcolormesh(mat, cmap=cmap, norm=SymLogNorm(linthresh=0.01, vmin=1/50., vmax=50.))
p = plt.colorbar()
p.locator=ticker.LogLocator(base=2)
p.update_ticks()
来源:https://stackoverflow.com/questions/34949536/making-log2-scaled-heatmap-in-matplotlib