Abacus
Abacus

Reputation: 77

Shared colorbar for one row of subplots

import matplotlib.pyplot as plt
import numpy as np

fig, axs = plt.subplots(2, 2)
plt.subplot(2,2,1)
plt.imshow(np.random.random((100, 100)), cmap=plt.cm.BuPu_r)
plt.subplot(2,2,2)
plt.imshow(np.random.random((100, 100)), cmap=plt.cm.BuPu_r)
plt.subplot(2,2,3)
plt.imshow(np.random.random((100, 100)), cmap=plt.cm.BuPu_r)
plt.subplot(2,2,4)
plt.imshow(np.random.random((100, 100)), cmap=plt.cm.BuPu_r)

plt.subplots_adjust(bottom=0.1, right=0.8, top=0.9)
cax = plt.axes([0.85, 0.1, 0.075, 0.8])
plt.colorbar(cax=cax)
plt.show()

enter image description here

The above code provides a shared colorbar for all 4 plots. How can I best amend this if I only wanted the colorbar to apply to the subplots in the top row? I would like the colorbar to only take up space in the top row of the subplots; the second row of subplots would then take up the space vacated by the smaller colorbar.

I hope this makes sense, many thanks in advance.

Upvotes: 1

Views: 2737

Answers (3)

Jody Klymak
Jody Klymak

Reputation: 5932

Alternately, you can use the new subfigures functionality if you really want the two rows to have different width axes:

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure(constrained_layout=True)
sfig0, sfig1 = fig.subfigures(2, 1)

axs = sfig0.subplots(1, 2)
cmap = plt.cm.viridis
for ax in axs.flat:
    pc = ax.pcolormesh(np.random.random((100, 100)), 
                       cmap=cmap)
sfig0.colorbar(pc, ax=axs)

axs = sfig1.subplots(1, 2)
cmap = plt.cm.BuPu_r
for ax in axs.flat:
    pc = ax.pcolormesh(np.random.random((100, 100)), 
                       cmap=cmap)

enter image description here

Upvotes: 1

Jody Klymak
Jody Klymak

Reputation: 5932

This is the easy way to do it. Note ax is the kwarg, not cax, for this to work.

import matplotlib.pyplot as plt
import numpy as np

fig, axs = plt.subplots(2, 2, constrained_layout=True)
pc = [None] * 4
for nn, ax in enumerate(axs.flat):
    if nn > 1:
        cmap = plt.cm.BuPu_r
    else:
        cmap = plt.cm.viridis
    pc[nn] = ax.imshow(np.random.random((100, 100)), 
                       cmap=cmap)
fig.colorbar(pc[0], ax=axs[0, :])
fig.colorbar(pc[2], ax=axs[1, :])
plt.show()

enter image description here

Upvotes: 2

Coup
Coup

Reputation: 750

Changing size and position of colorbar with matplotlib

mpl.pyplot.colorbar(mappable=None, cax=None, ax=None, **kw) places the colorbar on an axis made specifically for it (cax) or an axis with room to place the colorbar (ax). mpl.axes(arg) makes a new axis at a 4 tuple location. The 4 tuple indicates distance from bottom, distance from left, bar width, and bar height (bottom, left, width, height).

cax = plt.axes([0.85, 0.1, 0.075, 0.8])

You can solve your problem by simply making the axis you place the colorbar shorter and positioned higher from the bottom.

enter image description here

import matplotlib.pyplot as plt
import numpy as np

fig, axs = plt.subplots(2, 2)
plt.subplot(2,2,1)
plt.imshow(np.random.random((100, 100)), cmap=plt.cm.BuPu_r)
plt.subplot(2,2,2)
plt.imshow(np.random.random((100, 100)), cmap=plt.cm.BuPu_r)
plt.subplot(2,2,3)
plt.imshow(np.random.random((100, 100)), cmap=plt.cm.BuPu_r)
plt.subplot(2,2,4)
plt.imshow(np.random.random((100, 100)), cmap=plt.cm.BuPu_r)

plt.subplots_adjust(bottom=0.1, right=0.8, top=0.9)
cax = plt.axes([0.8, 0.575, 0.035, 0.3])
plt.colorbar(cax=cax)

Upvotes: 0

Related Questions