0

While I managed to put a plot inside a plot (see the question here), I am finding trouble putting a colorbar to the larger (outside) plot. The code below is as simple as it gets, but for some reason it places the colorbar in the wrong axis:

import numpy as np
from numpy import random
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable

# Canvas
fig, ax1 = plt.subplots(figsize=(12, 10))
left, bottom, width, height = [0.65, 0.15, 0.32, 0.30]
ax2 = fig.add_axes([left, bottom, width, height])

# Labels
xlabel = 'x'
ylabel = 'y'
cbarlabel = 'Color'
cmap = plt.get_cmap('turbo')

# Data
x, y, z = np.random.rand(3,200)

# Plotting
sc = ax1.scatter(x, y, marker='o', c=z, cmap=cmap)
ax2.scatter(x, y, c=z, cmap=cmap)
#
ax1.set_xlabel(xlabel)
ax1.set_ylabel(ylabel)
ax1.legend(fontsize=12, loc='upper left')
plt.tight_layout()

# Colormap
ax1 = plt.gca()
divider = make_axes_locatable(plt.gca())
cax = divider.append_axes("right", "2%", pad="1%")
cbar = plt.colorbar(sc, cax=cax)  # Colorbar
cbar.set_label(cbarlabel, rotation=270, labelpad=30)
sc.set_clim(vmin=min(z), vmax=max(z))
#
plt.show()

Result

I have also tried inset_axes as in the documentation example, to no avail.

cwasdwa
  • 63
  • 10

1 Answers1

1

The trick is to actually set active axes with plt.sca(ax1) and then create colorbar. I also simplified a code little bit.

Here is modified code putting colormap to the large plot:

import matplotlib.pyplot as plt
import numpy as np
from numpy import random

# Canvas
fig, ax1 = plt.subplots(figsize=(12, 10))
left, bottom, width, height = [0.45, 0.15, 0.32, 0.30]
ax2 = fig.add_axes([left, bottom, width, height])

# Labels
xlabel = 'x'
ylabel = 'y'
cbarlabel = 'Color'
cmap = plt.get_cmap('turbo')

# Data
x, y, z = np.random.rand(3,200)

# Plotting
sc = ax1.scatter(x, y, marker='o', c=z, cmap=cmap)
ax2.scatter(x, y, c=z, cmap=cmap)

# Set active axes
plt.sca(ax1)
cbar = plt.colorbar(sc)  # Colorbar
cbar.set_label(cbarlabel, rotation=270, labelpad=30)
sc.set_clim(vmin=min(z), vmax=max(z))

#
ax1.set_xlabel(xlabel)
ax1.set_ylabel(ylabel)
ax1.legend(fontsize=12, loc='upper left')
plt.tight_layout()

plt.show()

Resulting in: colorbar

Domarm
  • 2,360
  • 1
  • 5
  • 17
  • Works flawlessl :) Why `ax1 = plt.gca()` does not yield the same result? – cwasdwa Mar 07 '22 at 11:22
  • 1
    Because `plt.gca()` without any parameter `Get the current Axes instance`, which is the last axes added: `ax2`. So after You call `ax1 = plt.gca()`, You've got `ax2`, not `ax1` as You want. That's why You have to set ax1 as active axes with `plt.sca(ax1)`. – Domarm Mar 07 '22 at 11:28