2

I am doing a plot something like this:

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

fig = plt.gcf()
ax = plt.gca()
ax.pcolormesh(np.random.rand(10, 10))
fig.colorbar(mpl.cm.ScalarMappable(), ax=ax)

The last line adds a colorbar and a second axis

fig.axes
>>> [<AxesSubplot:>, <AxesSubplot:label='<colorbar>'>]

My question: Is there any relation between the two axes that can be used to get the axis of the colorbar (second in the list above) using only the axis returned by ax = plt.gca() (first returned in the list above)?

Zephyr
  • 11,891
  • 53
  • 45
  • 80
fabian
  • 103
  • 1
  • 7
  • Does this answer your question? [How to retrieve colorbar instance from figure in matplotlib](https://stackoverflow.com/questions/19816820/how-to-retrieve-colorbar-instance-from-figure-in-matplotlib) including my answer, which I think works well and is quite generic. – Vincenzooo Nov 23 '22 at 18:03
  • Thanks for the hint, I did not now the ax.images property. But it does not work in my case. I am generating a subplot layout first, e.g., fig, `ax = plt.subplots(3,1)` and `ax[2]` will become a shared colorbar for the plots in `ax[0]` and `ax[2]`. For this case `im = ax[0].images` works but `cb = im[-1].colorbar` does not. – fabian Nov 25 '22 at 08:50
  • I believe in your case the colorbar is not linked to the last image of all images on the axis, so when you recall the last element `im[-1]` of the list im, you don't find the colorbar. However this must be linked to a mappable (this is needed to tell the colorbar how to map the colors). I think you need to find the right objects, but the principle works the same. It is hard to say more without a sample of the code. – Vincenzooo Feb 17 '23 at 10:07
  • Maybe this can also be relevant: https://stackoverflow.com/questions/74551664/how-to-distinguish-axes-between-image-line-plot-and-colorbar. Also these comments are more related to the linked question and might belong there. – Vincenzooo Feb 17 '23 at 10:08

1 Answers1

1

As far as I know, if you define pcolormesh and colorbar that way, no.
Anyway, you can define an ax for the pcolormesh and a cax for the colorbar beforehand. Then you can pass cax as parameter to matplotlib.pyplot.colorbar. In this way you can access to both axis ax and cax as you need.

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np


grid_kws = {'width_ratios': (0.9, 0.05), 'wspace': 0.2}
fig, (ax, cax) = plt.subplots(1, 2, gridspec_kw = grid_kws, figsize = (10, 8))
ax.pcolormesh(np.random.rand(10, 10))
plt.colorbar(mpl.cm.ScalarMappable(), cax=cax)

plt.show()

enter image description here


In general, focusing on your code:

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

fig = plt.gcf()
ax = plt.gca()
ax.pcolormesh(np.random.rand(10, 10))
fig.colorbar(mpl.cm.ScalarMappable(), ax=ax)

starting from ax, you can get its figure with ax.figure. From there, you can get the list of all figure axes with ax.figure.axes. So, if you want to get colobar's axis using only pcolormesh' axis, you should use:

ax.figure.axes[1]

The parent figure, as far as I know, is the only relation between the two axes.

Zephyr
  • 11,891
  • 53
  • 45
  • 80
  • Thanks for the response. I was aware of that possibility but was looking for the specific solution of obtaining the colorbar axis in a bigger context – fabian Sep 01 '21 at 12:36
  • 1
    Thanks again. While using ```ax.figure.axes[1]``` works for the simple cases. It is likely to fail for more complex subplot layouts. So there no general solution to the problem except for manually keeping track of both axis. – fabian Sep 02 '21 at 12:39