Remove colorbar from subplot along with onclick/event

I am creating fig with 2 subplots as below:

from matplotlib import pyplot as plt
import matplotlib as mtl
mtl.use('TkAgg')

fig, ax = plt.subplots(1, 2, figsize=(6, 18), dpi=200)
axes = ax.ravel()
axes[0].imshow(plateLabeled)
pcm = axes[0].pcolormesh(plateLabeled)#, cmap='msml2')
fig.colorbar(pcm, ax=axes[0], shrink=0.4, pad=0.1)

initially the first subplot has an image shown, then I click inside and then the second subplot display a graph. Then I am trying to change/update the first subplot based on some event(mouse click) in the second subplot. It works nicely except the colorbar is not updating with the update or removal of the previous contents in the first subplot.

def onclick(event):
    global pcm
    if event.button == 1 and event.inaxes == axes[0]:  # 'MouseButton.LEFT':
        xdata_, ydata_ = round(event.xdata), round(event.ydata)
        mz_, int_ = xvector, yvector
        spec, = axes[1].plot(mz_, int_, lw=0.5, alpha=0.5)
        axes[1].set_title("Plot window")
        axes[0].scatter(xdata_, ydata_, marker='.', c=spec.get_color(), edgecolors=spec.get_color(), s=1)
            # axes[0].text(xdata_, ydata_, (xdata_, ydata_))
    if event.button == 3 and event.dblclick and event.inaxes == axes[1]:
        # print("right button + double click + plot 2")
        axes[1].clear()
        for scatter in axes[0].collections:
            scatter.remove()
    if event.button == 1 and event.dblclick and event.inaxes == axes[1]: # doubleclick spectra window
        mz_value = event.xdata
        ymax_ = event.ydata
        tol_ = 10
        im = np.zeros(
            (dict['max count of pixels x'] + 1,
             dict['max count of pixels y'] + 1)
        )
        for i, (x, y, z_) in enumerate(coordinates):
            reduce_func = sum
            if z_ == 0:
                UserWarning("z coordinate = 0 present, if you're getting blank images ")
            if z_ == 1:
                #  codes that simply create an 
                #  image to display in axes[0]
                im[x, y] = reduce_func(ints[min_i:max_i + 1])  # y - 1, x - 1
        axes[1].axvspan(xmin=mz_value-tol_, xmax=mz_value+tol_, ymin=0, ymax=0.7, facecolor='g', alpha=0.3, zorder=2)
        axes[0].clear()
        # if axes[0].cb:
        #     axes[0].figure.delaxes(axes[0].figure.axes[1])
        # fig.delaxes(axes[0][1])
        # fig.colorbar(pcm, ax=axes[0]).clear()
        # fig.colorbar(pcm, ax=axes[0]).set_ticks([])
        # fig.clear()
        axes[0].imshow(im, cmap='msml2')
        axes[0].set_title("m/z: {:.4f}, tol: {}".format(mz_value, tol_))
        pcm = axes[0].pcolormesh(im, cmap='msml2')
        # fig.delaxes(axes[0])
        fig.colorbar(pcm, ax=axes[0], shrink=0.4, pad=0.1)
    plt.pause(0.1)
cid = fig.canvas.mpl_connect('button_press_event', onclick)
plt.show()

See the result below:


even axes[0] updates but the colobars from previous imshow remains…

How do I remove the colorbars following the codes above.

Colorbars steal space from existing Axes; they are not directly related to them. If you delete the Axes and want to delete the related colorbar, you should delete its Axes as well; matplotlib.colorbar — Matplotlib 3.7.1 documentation

Was an actual solution found for this? Here’s my similar problem.

# Demo to create 2 colorbars (one vertical, one horizontal) and on mouse-click, alternate
# between deleting and recreating the horiz one.

import sys
from PyQt5 import QtWidgets

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg 
from matplotlib.figure import Figure
from matplotlib import colormaps
from mpl_toolkits.axes_grid1.axes_divider import make_axes_locatable
import matplotlib.pyplot as plt
import numpy as np


class MplWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(MplWidget, self).__init__(parent)

        self.figure = plt.figure()
        self.canvas = FigureCanvasQTAgg(self.figure)

        vertical_layout = QtWidgets.QVBoxLayout(self)
        vertical_layout.addWidget(self.canvas)

        self.ax0 = self.figure.add_subplot(111, adjustable='box')   # in vis_tab.py
        self.ax0_divider = make_axes_locatable(self.ax0)

        # self.cax1 = None
        # self.cax2 = None
        self.cax1 = self.ax0_divider.append_axes("right", size="4%", pad="4%")
        self.cax2 = self.ax0_divider.append_axes("bottom", size="4%", pad="7%")

        self.flag = False

        self.plot_contours()
        self.plot_cells()

        self.canvas.mpl_connect("button_press_event", self.redraw)

    def plot_contours(self):
        x = np.arange(1, 10)
        y = x.reshape(-1, 1)
        h = x * y
        cplot = self.ax0.contourf(h)
        if self.cax1 is None:
            self.ax0_divider = make_axes_locatable(self.ax0)
            self.cax1 = self.ax0_divider.append_axes("right", size="4%", pad="4%")
        self.cbar1 = self.figure.colorbar(cplot, cax=self.cax1)
        self.cbar1.ax.set_ylabel('contour label')

    def plot_cells(self):
        cm = colormaps.get_cmap('RdYlBu')
        xv = range(8)
        # print("xv=",xv)
        yv = np.random.uniform(low=0.0, high=1.0, size=8)
        # print("yv.min(), max()= ",yv.min(),yv.max())
        z = yv
        self.flag = not self.flag
        if self.flag:   # show colorbar
            if self.cax2 is None:
            # if self.ax0_divider is None:
                # self.ax0_divider = make_axes_locatable(self.ax0)
                self.cax2 = self.ax0_divider.append_axes("bottom", size="4%", pad="7%")
                print("type(self.cax2)= ",type(self.cax2))
                print("type(self.ax0_divider)= ",type(self.ax0_divider))
                print("self.ax0_divider= ",self.ax0_divider)
                # self.cax2 = self.cax_horiz

            sc = self.ax0.scatter(xv, xv, c=z, vmin=yv.min(), vmax=yv.max(), s=35, cmap=cm)
            cbar = self.figure.colorbar(sc, orientation='horizontal', cax=self.cax2)
            cbar.ax.set_xlabel('cells colors')

        else:  # don't show colorbar
            if self.cax2 is not None:
                self.cax2.remove()
                self.cax2 = None
            sc = self.ax0.scatter(xv, xv, c=z, vmin=yv.min(), vmax=yv.max(), s=35)

    def redraw(self, event):
        # print("redraw()")
        self.ax0.cla()
        self.plot_contours()
        self.plot_cells()
        self.canvas.update()
        self.canvas.draw()

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = MplWidget()
    w.show()
    sys.exit(app.exec_())

Related, is make_axes_locatable even recommended? I’m not seeing anything here mpl_toolkits.axes_grid1.axes_divider.make_axes_locatable — Matplotlib 3.8.4 documentation

Example without PyQt5. I can remove a colorbar, but can’t recreate/redisplay it.

import sys
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.axes_grid1.axes_divider import make_axes_locatable
import numpy as np

vert_cbar = None
horiz_cbar = None

def on_press(event):
    global fig, vert_cbar, horiz_cbar, cax1,cax2, cset1
    # print('press', event.key)
    sys.stdout.flush()
    # if event.key == 'x':
    #     visible = xl.get_visible()
    #     xl.set_visible(not visible)
    #     fig.canvas.draw()
    if event.key == 'v':
        if vert_cbar is not None:
            vert_cbar.remove()
            vert_cbar = None
        else:
            vert_cbar = fig.colorbar(cset1, cax=cax1)
        fig.canvas.draw()

    elif event.key == 'h':
        if horiz_cbar is not None:
            horiz_cbar.remove()
            horiz_cbar = None
        else:
            horiz_cbar = fig.colorbar(cset1, cax=cax2, orientation='horizontal')
        fig.canvas.draw()


# fig, ax1 = plt.subplots(1, 1)

delta = 0.5
extent = (-3, 4, -4, 3)
x = np.arange(-3.0, 4.001, delta)
y = np.arange(-4.0, 3.001, delta)
X, Y = np.meshgrid(x, y)
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
Z = (Z1 - Z2) * 2

# Boost the upper limit to avoid truncation errors.
levels = np.arange(-2.0, 1.601, 0.4)

norm = cm.colors.Normalize(vmax=abs(Z).max(), vmin=-abs(Z).max())
cmap = cm.PRGn

fig, ax = plt.subplots(nrows=1, ncols=1)
fig.subplots_adjust(hspace=0.3)

cset1 = ax.contourf(X, Y, Z, levels, norm=norm,
                        cmap=cmap.resampled(len(levels) - 1))

ax1_divider = make_axes_locatable(ax)
# Add an Axes to the right of the main Axes.
cax1 = ax1_divider.append_axes("right", size="7%", pad="2%")
cax2 = ax1_divider.append_axes("bottom", size="7%", pad="7%")
vert_cbar = fig.colorbar(cset1, cax=cax1)
horiz_cbar = fig.colorbar(cset1, cax=cax2, orientation='horizontal')

fig.canvas.mpl_connect('key_press_event', on_press)
ax.set_title('h=toggle horiz cbar; v=toggle vertical cbar')

plt.show()