How to add a colorbar for a hist2d plot

Question:

Well, I know how to add a colour bar to a figure, when I have created the figure directly with matplotlib.pyplot.plt.

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

# normal distribution center at x=0 and y=5
x = np.random.randn(100000)
y = np.random.randn(100000) + 5

# This works
plt.figure()
plt.hist2d(x, y, bins=40, norm=LogNorm())
plt.colorbar()

But why does the following not work, and what would I need to add to the call of colorbar(..) to make it work.

fig, ax = plt.subplots()
ax.hist2d(x, y, bins=40, norm=LogNorm())
fig.colorbar()
# TypeError: colorbar() missing 1 required positional argument: 'mappable'

fig, ax = plt.subplots()
ax.hist2d(x, y, bins=40, norm=LogNorm())
fig.colorbar(ax)
# AttributeError: 'AxesSubplot' object has no attribute 'autoscale_None'

fig, ax = plt.subplots()
h = ax.hist2d(x, y, bins=40, norm=LogNorm())
plt.colorbar(h, ax=ax)
# AttributeError: 'tuple' object has no attribute 'autoscale_None'
Asked By: Thomas Möbius

||

Answers:

You are almost there with the 3rd option. You have to pass a mappable object to colorbar so it knows what colormap and limits to give the colorbar. That can be an AxesImage or QuadMesh, etc.

In the case of hist2D, the tuple returned in your h contains that mappable, but also some other things too.

From the docs:

Returns:
The return value is (counts, xedges, yedges, Image).

So, to make the colorbar, we just need the Image.

To fix your code:

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

# normal distribution center at x=0 and y=5
x = np.random.randn(100000)
y = np.random.randn(100000) + 5

fig, ax = plt.subplots()
h = ax.hist2d(x, y, bins=40, norm=LogNorm())
fig.colorbar(h[3], ax=ax)

Alternatively:

counts, xedges, yedges, im = ax.hist2d(x, y, bins=40, norm=LogNorm())
fig.colorbar(im, ax=ax)
Answered By: tmdavison
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.