hexbin log bins and colorbar

OK, at least now we are running the sample example :slight_smile:

The problem is that the LogFormatter has a default which is
"decadeOnly=True" and in the first case which "worked" three of the
tick locations coincidentally came down on decades (0, 1, 2 -> 1, 10,
100). In the case you were working with, only one of the ticks mapped
to the decade.

So for this case we want a locator that returns integers 0,1,2... that
will then get mapped via Eric's custom formatter to the 10^i formats.
Unfortunately, there is no easy way to set the locator for the
colorbar. An easy workaround *for this case* is to simply set the
tick locations

聽聽cb = plt.colorbar(format=LogFormatterHB(), ticks=[0,1,2])

but in general you may not know the decade span that you need. It
does all feel a bit kludgy. The problem as you noted in one of your
earlier posts is that the data is log scaled before being passed into
the PolyCollection and the fact that it is log scaled is then lost to
the colorbar. It seems everything would fit together more naturally
if we passed in raw scalar data to the PolyCollection and set the norm
to be colors.LogNorm, and then also set norm=colors.LogNorm on the
colorbar

I tried:

聽聽polycol = plt.hexbin(data['jetMomentum'][cut] / 1000,
data['deltaR'][cut],gridsize=50, norm=colors.LogNorm())
聽聽cb = plt.colorbar(norm=colors.LogNorm())

but this appears to be broken:

msierig@...2993...:Downloads> python test.py
Traceback (most recent call last):
聽聽File "test.py", line 29, in <module>
聽聽聽聽cb = plt.colorbar()
聽聽File "/home/msierig/dev/lib/python2.6/site-packages/matplotlib/pyplot.py",
line 1356, in colorbar
聽聽聽聽ret = gcf().colorbar(mappable, cax = cax, ax=ax, **kw)
聽聽File "/home/msierig/dev/lib/python2.6/site-packages/matplotlib/figure.py",
line 1103, in colorbar
聽聽聽聽cb = cbar.Colorbar(cax, mappable, **kw)
聽聽File "/home/msierig/dev/lib/python2.6/site-packages/matplotlib/colorbar.py",
line 690, in __init__
聽聽聽聽ColorbarBase.__init__(self, ax, **kw)
聽聽File "/home/msierig/dev/lib/python2.6/site-packages/matplotlib/colorbar.py",
line 242, in __init__
聽聽聽聽self.draw_all()
聽聽File "/home/msierig/dev/lib/python2.6/site-packages/matplotlib/colorbar.py",
line 260, in draw_all
聽聽聽聽self._config_axes(X, Y)
聽聽File "/home/msierig/dev/lib/python2.6/site-packages/matplotlib/colorbar.py",
line 332, in _config_axes
聽聽聽聽self.update_ticks()
聽聽File "/home/msierig/dev/lib/python2.6/site-packages/matplotlib/colorbar.py",
line 271, in update_ticks
聽聽聽聽ticks, ticklabels, offset_string = self._ticker()
聽聽File "/home/msierig/dev/lib/python2.6/site-packages/matplotlib/colorbar.py",
line 458, in _ticker
聽聽聽聽b = np.array(locator())
聽聽File "/home/msierig/dev/lib/python2.6/site-packages/matplotlib/ticker.py",
line 1173, in __call__
聽聽聽聽vmin = self.axis.get_minpos()

路路路

On Mon, Feb 22, 2010 at 3:42 PM, Jan Strube <curiousjan@...287...> wrote:

Hi John,
the attachment may not make it to the list. However, please run the modified
test.py that I have attached.
It requires the attached input file.
Then change it to read the original input file.
In my case:
The broken case:

I committed some changes to support this -- the following now works:

聽聽polycol = plt.hexbin(data['jetMomentum'][cut] / 1000,
data['deltaR'][cut],gridsize=50, norm=colors.LogNorm())

聽聽cb = plt.colorbar(norm=polycol.norm)

Eric - I was surprised the colorbar does not use the mappable norm by
default (if passed norm=None). Instead it uses ::

聽聽norm = colors.Normalize()

is this a feature?

JDH

路路路

On Mon, Feb 22, 2010 at 4:33 PM, John Hunter <jdh2358@...287...> wrote:

polycol = plt.hexbin(data['jetMomentum'][cut] / 1000,
data['deltaR'][cut],gridsize=50, norm=colors.LogNorm())
cb = plt.colorbar(norm=colors.LogNorm())

but this appears to be broken:

John Hunter wrote:

polycol = plt.hexbin(data['jetMomentum'][cut] / 1000,
data['deltaR'][cut],gridsize=50, norm=colors.LogNorm())
cb = plt.colorbar(norm=colors.LogNorm())

but this appears to be broken:

I committed some changes to support this -- the following now works:

聽聽polycol = plt.hexbin(data['jetMomentum'][cut] / 1000,
data['deltaR'][cut],gridsize=50, norm=colors.LogNorm())

聽聽cb = plt.colorbar(norm=polycol.norm)

Eric - I was surprised the colorbar does not use the mappable norm by
default (if passed norm=None). Instead it uses ::

聽聽norm = colors.Normalize()

is this a feature?

Yes. You are looking at ColorbarBase, which does not have an associated mappable. The derived Colorbar class does grab the cmap and norm from the mappable used in the initialization. Is this somehow not working? Did you really need to specify the norm explicitly?

Eric

路路路

On Mon, Feb 22, 2010 at 4:33 PM, John Hunter <jdh2358@...287...> wrote:

JDH

Hi John,

thanks for keeping at it. I have updated from svn

But this script

import matplotlib

matplotlib.use(鈥楢gg鈥)

import matplotlib.pyplot as plt

import numpy as np

from matplotlib.ticker import LogFormatter

from matplotlib import colors

class LogFormatterHB(LogFormatter):

def call(self, v, pos=None):

vv = self._base ** v

print vv

return LogFormatter.call(self, vv, pos)

data = np.load(鈥榙eltaR_parton_jet_109370.npz鈥)

ptcut = np.logical_and(data[鈥榡etMomentum鈥橾 < 300000, data[鈥榡etMomentum鈥橾>0)

deltaRCut = data[鈥榙eltaR鈥橾>0

cut = np.logical_and(ptcut, deltaRCut)

fig = plt.figure()

polycol = plt.hexbin(data[鈥榡etMomentum鈥橾[cut] / 1000, data[鈥榙eltaR鈥橾[cut],

gridsize=50, norm=colors.LogNorm())

plt.title(鈥榙eltaR between parton(eta<2.5) and jet(eta<2.5)鈥)

plt.xlabel(鈥榡et pt (GeV)鈥)

plt.ylabel(鈥榙eltaR鈥)

cb = plt.colorbar(norm=polycol.norm)

cb.set_label(鈥# entries鈥)

fig.savefig(鈥榟exbin_demo.png鈥, dpi=100)

#plt.show()

gives me an error:

python test.py

Traceback (most recent call last):

File 鈥渢est.py鈥, line 24, in

cb = plt.colorbar(norm=polycol.norm)

File 鈥/Users/Jan/PYTHON/lib/python2.6/site-packages/matplotlib-1.0.svn_r8037-py2.6-macosx-10.6-universal.egg/matplotlib/pyplot.py鈥, line 1356, in colorbar

ret = gcf().colorbar(mappable, cax = cax, ax=ax, **kw)

File 鈥/Users/Jan/PYTHON/lib/python2.6/site-packages/matplotlib-1.0.svn_r8037-py2.6-macosx-10.6-universal.egg/matplotlib/figure.py鈥, line 1104, in colorbar

cb = cbar.Colorbar(cax, mappable, **kw)

File 鈥/Users/Jan/PYTHON/lib/python2.6/site-packages/matplotlib-1.0.svn_r8037-py2.6-macosx-10.6-universal.egg/matplotlib/colorbar.py鈥, line 649, in init

ColorbarBase.init(self, ax, **kw)

File 鈥/Users/Jan/PYTHON/lib/python2.6/site-packages/matplotlib-1.0.svn_r8037-py2.6-macosx-10.6-universal.egg/matplotlib/colorbar.py鈥, line 240, in init

self.draw_all()

File 鈥/Users/Jan/PYTHON/lib/python2.6/site-packages/matplotlib-1.0.svn_r8037-py2.6-macosx-10.6-universal.egg/matplotlib/colorbar.py鈥, line 251, in draw_all

self._config_axes(X, Y)

File 鈥/Users/Jan/PYTHON/lib/python2.6/site-packages/matplotlib-1.0.svn_r8037-py2.6-macosx-10.6-universal.egg/matplotlib/colorbar.py鈥, line 278, in _config_axes

ticks, ticklabels, offset_string = self._ticker()

File 鈥/Users/Jan/PYTHON/lib/python2.6/site-packages/matplotlib-1.0.svn_r8037-py2.6-macosx-10.6-universal.egg/matplotlib/colorbar.py鈥, line 417, in _ticker

b = np.array(locator())

File 鈥/Users/Jan/PYTHON/lib/python2.6/site-packages/matplotlib-1.0.svn_r8037-py2.6-macosx-10.6-universal.egg/matplotlib/ticker.py鈥, line 1085, in call

vmin = self.axis.get_minpos()

AttributeError: DummyAxis instance has no attribute 鈥榞et_minpos鈥

Cheers,

Jan

路路路

On Tue, Feb 23, 2010 at 12:26 AM, John Hunter <jdh2358@鈥287鈥> wrote:

On Mon, Feb 22, 2010 at 4:33 PM, John Hunter <jdh2358@鈥287鈥> wrote:

polycol = plt.hexbin(data[鈥榡etMomentum鈥橾[cut] / 1000,

data[鈥榙eltaR鈥橾[cut],gridsize=50, norm=colors.LogNorm())

cb = plt.colorbar(norm=colors.LogNorm())

but this appears to be broken:

I committed some changes to support this 鈥 the following now works:

polycol = plt.hexbin(data[鈥榡etMomentum鈥橾[cut] / 1000,

data[鈥榙eltaR鈥橾[cut],gridsize=50, norm=colors.LogNorm())

cb = plt.colorbar(norm=polycol.norm)

Eric - I was surprised the colorbar does not use the mappable norm by

default (if passed norm=None). Instead it uses ::

norm = colors.Normalize()

is this a feature?

JDH

Hi John,
thanks for keeping at it. I have updated from svn
But this script
File
"/Users/Jan/PYTHON/lib/python2.6/site-packages/matplotlib-1.0.svn_r8037-py2.6-macosx-10.6-universal.egg/matplotlib/colorbar.py",
line 278, in _config_axes
ticks, ticklabels, offset_string = self._ticker()
File
"/Users/Jan/PYTHON/lib/python2.6/site-packages/matplotlib-1.0.svn_r8037-py2.6-macosx-10.6-universal.egg/matplotlib/colorbar.py",
line 417, in _ticker
b = np.array(locator())
File
"/Users/Jan/PYTHON/lib/python2.6/site-packages/matplotlib-1.0.svn_r8037-py2.6-macosx-10.6-universal.egg/matplotlib/ticker.py",
line 1085, in __call__
vmin = self.axis.get_minpos()
AttributeError: DummyAxis instance has no attribute 'get_minpos'

Take a look at the file name in the traceback: matplotlib-1.0.svn_r8037

The r8037 is the svn revision number. According the svn log, I made
my commit on r8149, so you are not running HEAD. You may have
multiple matplotlib's installed and are not picking up the right egg.
I recommend

聽聽> rm -rf /Users/Jan/PYTHON/lib/python2.6/site-packages/matplotlib*

and then doing a clean install from mpl svn r8149 or later.

JDH

路路路

On Tue, Feb 23, 2010 at 4:12 AM, Jan Strube <curiousjan@...287...> wrote:

No, I didn't test this, I just read the code (apparently the wrong
code) and concluded I needed it. I did just test w/o it and all is
well. Sorry for the noise.

JDH

路路路

On Mon, Feb 22, 2010 at 6:28 PM, Eric Firing <efiring@...202...> wrote:

Yes. You are looking at ColorbarBase, which does not have an associated
mappable. The derived Colorbar class does grab the cmap and norm from the
mappable used in the initialization. Is this somehow not working? Did you
really need to specify the norm explicitly?

Gentlemen!

Thanks a lot for your help.

This works now for me (with and without the norm in the colorbar() call)

Best,

Jan

路路路

On Tue, Feb 23, 2010 at 3:47 PM, John Hunter <jdh2358@鈥287鈥> wrote:

On Mon, Feb 22, 2010 at 6:28 PM, Eric Firing <efiring@鈥202鈥> wrote:

Yes. You are looking at ColorbarBase, which does not have an associated

mappable. The derived Colorbar class does grab the cmap and norm from the

mappable used in the initialization. Is this somehow not working? Did you

really need to specify the norm explicitly?

No, I didn鈥檛 test this, I just read the code (apparently the wrong

code) and concluded I needed it. I did just test w/o it and all is

well. Sorry for the noise.

JDH