
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "users/explain/axes/colorbar_placement.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. meta::
        :keywords: codex

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_users_explain_axes_colorbar_placement.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_users_explain_axes_colorbar_placement.py:


.. _colorbar_placement:

.. redirect-from:: /gallery/subplots_axes_and_figures/colorbar_placement

=================
Placing colorbars
=================

Colorbars indicate the quantitative extent of image data.  Placing in
a figure is non-trivial because room needs to be made for them.

Automatic placement of colorbars
================================

The simplest case is just attaching a colorbar to each Axes.  Note in this
example that the colorbars steal some space from the parent Axes.

.. GENERATED FROM PYTHON SOURCE LINES 19-34

.. code-block:: Python

    import matplotlib.pyplot as plt
    import numpy as np

    # Fixing random state for reproducibility
    np.random.seed(19680801)

    fig, axs = plt.subplots(2, 2)
    cmaps = ['RdBu_r', 'viridis']
    for col in range(2):
        for row in range(2):
            ax = axs[row, col]
            pcm = ax.pcolormesh(np.random.random((20, 20)) * (col + 1),
                                cmap=cmaps[col])
            fig.colorbar(pcm, ax=ax)


.. GENERATED FROM PYTHON SOURCE LINES 35-38

The first column has the same type of data in both rows, so it may be
desirable to have just one colorbar. We do this by passing `.Figure.colorbar`
a list of Axes with the *ax* kwarg.

.. GENERATED FROM PYTHON SOURCE LINES 38-48

.. code-block:: Python


    fig, axs = plt.subplots(2, 2)
    cmaps = ['RdBu_r', 'viridis']
    for col in range(2):
        for row in range(2):
            ax = axs[row, col]
            pcm = ax.pcolormesh(np.random.random((20, 20)) * (col + 1),
                                cmap=cmaps[col])
        fig.colorbar(pcm, ax=axs[:, col], shrink=0.6)


.. GENERATED FROM PYTHON SOURCE LINES 49-52

The stolen space can lead to Axes in the same subplot layout
being different sizes, which is often undesired if the the
x-axis on each plot is meant to be comparable as in the following:

.. GENERATED FROM PYTHON SOURCE LINES 52-59

.. code-block:: Python


    fig, axs = plt.subplots(2, 1, figsize=(4, 5), sharex=True)
    X = np.random.randn(20, 20)
    axs[0].plot(np.sum(X, axis=0))
    pcm = axs[1].pcolormesh(X)
    fig.colorbar(pcm, ax=axs[1], shrink=0.6)


.. GENERATED FROM PYTHON SOURCE LINES 60-63

This is usually undesired, and can be worked around in various ways, e.g.
adding a colorbar to the other Axes and then removing it.  However, the most
straightforward is to use :ref:`constrained layout <constrainedlayout_guide>`:

.. GENERATED FROM PYTHON SOURCE LINES 63-69

.. code-block:: Python


    fig, axs = plt.subplots(2, 1, figsize=(4, 5), sharex=True, layout='constrained')
    axs[0].plot(np.sum(X, axis=0))
    pcm = axs[1].pcolormesh(X)
    fig.colorbar(pcm, ax=axs[1], shrink=0.6)


.. GENERATED FROM PYTHON SOURCE LINES 70-73

Relatively complicated colorbar layouts are possible using this
paradigm.  Note that this example works far better with
``layout='constrained'``

.. GENERATED FROM PYTHON SOURCE LINES 73-83

.. code-block:: Python


    fig, axs = plt.subplots(3, 3, layout='constrained')
    for ax in axs.flat:
        pcm = ax.pcolormesh(np.random.random((20, 20)))

    fig.colorbar(pcm, ax=axs[0, :2], shrink=0.6, location='bottom')
    fig.colorbar(pcm, ax=[axs[0, 2]], location='bottom')
    fig.colorbar(pcm, ax=axs[1:, :], location='right', shrink=0.6)
    fig.colorbar(pcm, ax=[axs[2, 1]], location='left')


.. GENERATED FROM PYTHON SOURCE LINES 84-91

Adjusting the spacing between colorbars and parent Axes
=======================================================

The distance a colorbar is from the parent Axes can be adjusted with the
*pad* keyword argument.  This is in units of fraction of the parent Axes
width, and the default for a vertical Axes is 0.05 (or 0.15 for a horizontal
Axes).

.. GENERATED FROM PYTHON SOURCE LINES 91-98

.. code-block:: Python


    fig, axs = plt.subplots(3, 1, layout='constrained', figsize=(5, 5))
    for ax, pad in zip(axs, [0.025, 0.05, 0.1]):
        pcm = ax.pcolormesh(np.random.randn(20, 20), cmap='viridis')
        fig.colorbar(pcm, ax=ax, pad=pad, label=f'pad: {pad}')
    fig.suptitle("layout='constrained'")


.. GENERATED FROM PYTHON SOURCE LINES 99-101

Note that if you do not use constrained layout, the pad command makes the
parent Axes shrink:

.. GENERATED FROM PYTHON SOURCE LINES 101-108

.. code-block:: Python


    fig, axs = plt.subplots(3, 1, figsize=(5, 5))
    for ax, pad in zip(axs, [0.025, 0.05, 0.1]):
        pcm = ax.pcolormesh(np.random.randn(20, 20), cmap='viridis')
        fig.colorbar(pcm, ax=ax, pad=pad, label=f'pad: {pad}')
    fig.suptitle("No layout manager")


.. GENERATED FROM PYTHON SOURCE LINES 109-124

Manual placement of colorbars
=============================

Sometimes the automatic placement provided by ``colorbar`` does not
give the desired effect.  We can manually create an Axes and tell
``colorbar`` to use that Axes by passing the Axes to the *cax* keyword
argument.

Using ``inset_axes``
--------------------

We can manually create any type of Axes for the colorbar to use, but an
`.Axes.inset_axes` is useful because it is a child of the parent Axes and can
be positioned relative to the parent.  Here we add a colorbar centered near
the bottom of the parent Axes.

.. GENERATED FROM PYTHON SOURCE LINES 124-131

.. code-block:: Python


    fig, ax = plt.subplots(layout='constrained', figsize=(4, 4))
    pcm = ax.pcolormesh(np.random.randn(20, 20), cmap='viridis')
    ax.set_ylim([-4, 20])
    cax = ax.inset_axes([0.3, 0.07, 0.4, 0.04])
    fig.colorbar(pcm, cax=cax, orientation='horizontal')


.. GENERATED FROM PYTHON SOURCE LINES 132-135

`.Axes.inset_axes` can also specify its position in data coordinates
using the *transform* keyword argument if you want your Axes at a
certain data position on the graph:

.. GENERATED FROM PYTHON SOURCE LINES 135-142

.. code-block:: Python


    fig, ax = plt.subplots(layout='constrained', figsize=(4, 4))
    pcm = ax.pcolormesh(np.random.randn(20, 20), cmap='viridis')
    ax.set_ylim([-4, 20])
    cax = ax.inset_axes([7.5, -1.7, 5, 1.2], transform=ax.transData)
    fig.colorbar(pcm, cax=cax, orientation='horizontal')


.. GENERATED FROM PYTHON SOURCE LINES 143-148

Colorbars attached to fixed-aspect-ratio Axes
---------------------------------------------

Placing colorbars for Axes with a fixed aspect ratio pose a particular
challenge as the parent Axes changes size depending on the data view.

.. GENERATED FROM PYTHON SOURCE LINES 148-163

.. code-block:: Python


    fig, axs = plt.subplots(2, 2,  layout='constrained')
    cmaps = ['RdBu_r', 'viridis']
    for col in range(2):
        for row in range(2):
            ax = axs[row, col]
            pcm = ax.pcolormesh(np.random.random((20, 20)) * (col + 1),
                                cmap=cmaps[col])
            if col == 0:
                ax.set_aspect(2)
            else:
                ax.set_aspect(1/2)
            if row == 1:
                fig.colorbar(pcm, ax=ax, shrink=0.6)


.. GENERATED FROM PYTHON SOURCE LINES 164-168

We solve this problem using `.Axes.inset_axes` to locate the Axes in "axes
coordinates" (see :ref:`transforms_tutorial`).  Note that if you zoom in on
the parent Axes, and thus change the shape of it, the colorbar will also
change position.

.. GENERATED FROM PYTHON SOURCE LINES 168-184

.. code-block:: Python


    fig, axs = plt.subplots(2, 2, layout='constrained')
    cmaps = ['RdBu_r', 'viridis']
    for col in range(2):
        for row in range(2):
            ax = axs[row, col]
            pcm = ax.pcolormesh(np.random.random((20, 20)) * (col + 1),
                                cmap=cmaps[col])
            if col == 0:
                ax.set_aspect(2)
            else:
                ax.set_aspect(1/2)
            if row == 1:
                cax = ax.inset_axes([1.04, 0.2, 0.05, 0.6])
                fig.colorbar(pcm, cax=cax)


.. GENERATED FROM PYTHON SOURCE LINES 185-191

.. seealso::

 :ref:`axes_grid` has methods for manually creating colorbar Axes as well:

 - :ref:`demo-colorbar-with-inset-locator`
 - :ref:`demo-colorbar-with-axes-divider`


.. _sphx_glr_download_users_explain_axes_colorbar_placement.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: colorbar_placement.ipynb <colorbar_placement.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: colorbar_placement.py <colorbar_placement.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: colorbar_placement.zip <colorbar_placement.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
