Question

My users sometimes wish to see log scaling of the values of a 2-d plot, even though the data spans less than one decade. I'm able to make plots using 'pcolormesh' or 'imshow' using the

norm=LogNorm(vmin=minimum,vmax=maximum)

parameter and accurately show log scaled 'intensity' values. I would like the 'colorbar' to show some minor ticks and tick labels, but when minimum and maximum span less than a decade, no matter what I do there is only one tick value displayed. I tried the suggestion in this SO posting:

Minor ticks in matplotlib's colorbar

As adapted in the following snippet:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm

# fill grid
x = np.linspace(1,10,10)
y = np.linspace(1,10,10)

X, Y = np.meshgrid(x,y)
Z = np.abs(X/10 + Y/10)

# plot
f, ax = plt.subplots()
p = plt.pcolormesh(X, Y, Z, norm=LogNorm(), vmin=2e-1, vmax=1)
cb = plt.colorbar(p, ax=ax)

cb.ax.minorticks_on()

plt.show()

But there are no minor ticks, labeled or otherwise:

Colorbar is Missing Minor Ticks

I have also tried the following:

from matplotlib.ticker import LogFormatterMathtext
from matplotlib.ticker import LogLocator
from matplotlib.ticker import LogFormatter
import numpy as nmp
import matplotlib.pyplot as pyp
'''
<snip>
'''
ccbb=pyp.colorbar(label='ohms')
ccbb.ax.yaxis.set_minor_locator(LogLocator(subs=nmp.arange(2,10)))
# AND/OR
# ccbb.ax.yaxis.set_minor_locator(LogLocator(subs=[0.2,0.5,1.0]))
ccbb.ax.yaxis.set_minor_formatter(LogFormatterMathtext())
ccbb.update_ticks()
'''
<snip>
'''

And several other things, which I haven't saved. All of which yield the same result with the colorbar missing any but the single decade tick / label. The documentation for the ticker class is pretty impenetrable:

http://matplotlib.org/api/ticker_api.html

Especially the following statement about LogFormatter parameter labelOnlyBase: "base is used to locate the decade tick, which will be the only one to be labeled if labelOnlyBase is False" Neither False nor True cause more than the base to be ticked, I suppose that's because this refers to the Major ticks, But why in the world can't I get the minor ticks or labels??

Any advice would be appreciated.

Was it helpful?

Solution

Matplotlib colorbars don't seem to do minor ticks in log scale. Using the method in this answer works, though it's a bit inconvenient - one day this will be automatic, but for now you have to organise the minor tick values by hand (np.arange(2, 10)/10. in this case, but you'd have to append np.arange(2, 10) if your values went up to 10)

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm

# fill grid
x = np.linspace(1,10,10)
y = np.linspace(1,10,10)

X, Y = np.meshgrid(x,y)
# Z = np.abs(X + Y)
Z = np.abs(X/10 + Y/10)

# plot
f, ax = plt.subplots()
p = plt.pcolormesh(X, Y, Z, norm=LogNorm(), vmin=2e-1, vmax=1)
cb = plt.colorbar(p, ax=ax)

# cb.ax.minorticks_on()

# We need to nomalize the tick locations so that they're in the range from 0-1...
minorticks = p.norm(np.arange(2, 10)/10.)
cb.ax.yaxis.set_ticks(minorticks, minor=True)

plt.show()

enter image description here

The minorticks_on() method wasn't doing anything, so I commented it out.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top