def plot_precip_field(
    precip,
    ptype="intensity",
    ax=None,
    geodata=None,
    units="mm/h",
    bbox=None,
    colorscale="pysteps",
    probthr=None,
    title=None,
    colorbar=True,
    axis="on",
    cax=None,
    map_kwargs=None,
    colormap_config=None,
):
    """
    Function to plot a precipitation intensity or probability field with a
    colorbar.

    .. _Axes: https://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes

    .. _SubplotSpec: https://matplotlib.org/api/_as_gen/matplotlib.gridspec.SubplotSpec.html

    Parameters
    ----------
    precip: array-like
        Two-dimensional array containing the input precipitation field or an
        exceedance probability map.
    ptype: {'intensity', 'depth', 'prob'}, optional
        Type of the map to plot: 'intensity' = precipitation intensity field,
        'depth' = precipitation depth (accumulation) field,
        'prob' = exceedance probability field.
    geodata: dictionary or None, optional
        Optional dictionary containing geographical information about
        the field. Required is map is not None.

        If geodata is not None, it must contain the following key-value pairs:

        .. tabularcolumns:: |p{1.5cm}|L|

        +-----------------+---------------------------------------------------+
        |        Key      |                  Value                            |
        +=================+===================================================+
        |    projection   | PROJ.4-compatible projection definition           |
        +-----------------+---------------------------------------------------+
        |    x1           | x-coordinate of the lower-left corner of the data |
        |                 | raster                                            |
        +-----------------+---------------------------------------------------+
        |    y1           | y-coordinate of the lower-left corner of the data |
        |                 | raster                                            |
        +-----------------+---------------------------------------------------+
        |    x2           | x-coordinate of the upper-right corner of the     |
        |                 | data raster                                       |
        +-----------------+---------------------------------------------------+
        |    y2           | y-coordinate of the upper-right corner of the     |
        |                 | data raster                                       |
        +-----------------+---------------------------------------------------+
        |    yorigin      | a string specifying the location of the first     |
        |                 | element in the data raster w.r.t. y-axis:         |
        |                 | 'upper' = upper border, 'lower' = lower border    |
        +-----------------+---------------------------------------------------+
    units : {'mm/h', 'mm', 'dBZ'}, optional
        Units of the input array. If ptype is 'prob', this specifies the unit of
        the intensity threshold.
    bbox : tuple, optional
        Four-element tuple specifying the coordinates of the bounding box. Use
        this for plotting a subdomain inside the input grid. The coordinates are
        of the form (lower left x, lower left y ,upper right x, upper right y).
        If 'geodata' is not None, the bbox is in map coordinates, otherwise
        it represents image pixels.
    colorscale : {'pysteps', 'STEPS-BE', 'STEPS-NL', 'BOM-RF3'}, optional
        Which colorscale to use. Applicable if units is 'mm/h', 'mm' or 'dBZ'.
    probthr : float, optional
        Intensity threshold to show in the color bar of the exceedance
        probability map.
        Required if ptype is "prob" and colorbar is True.
    title : str, optional
        If not None, print the title on top of the plot.
    colorbar : bool, optional
        If set to True, add a colorbar on the right side of the plot.
    axis : {'off','on'}, optional
        Whether to turn off or on the x and y axis.
    cax : Axes_ object, optional
        Axes into which the colorbar will be drawn. If no axes is provided
        the colorbar axes are created next to the plot.
    colormap_config : ColormapConfig, optional
        Custom colormap configuration. If provided, this will override the
        colorscale parameter.
        The ColormapConfig class must have the following attributes: cmap,
        norm, clevs.

    Other parameters
    ----------------
    map_kwargs: dict
        Optional parameters that need to be passed to
        :py:func:`pysteps.visualization.basemaps.plot_geography`.

    Returns
    -------
    ax : fig Axes_
        Figure axes. Needed if one wants to add e.g. text inside the plot.
    """

    if map_kwargs is None:
        map_kwargs = {}

    if ptype not in PRECIP_VALID_TYPES:
        raise ValueError(
            f"Invalid precipitation type '{ptype}'."
            f"Supported: {str(PRECIP_VALID_TYPES)}"
        )

    if units not in PRECIP_VALID_UNITS:
        raise ValueError(
            f"Invalid precipitation units '{units}."
            f"Supported: {str(PRECIP_VALID_UNITS)}"
        )

    if ptype == "prob" and colorbar and probthr is None:
        raise ValueError("ptype='prob' but probthr not specified")

    if len(precip.shape) != 2:
        raise ValueError("The input is not two-dimensional array")

    # Assumes the input dimensions are lat/lon
    nlat, nlon = precip.shape

    x_grid, y_grid, extent, regular_grid, origin = get_geogrid(
        nlat, nlon, geodata=geodata
    )

    ax = get_basemap_axis(extent, ax=ax, geodata=geodata, map_kwargs=map_kwargs)

    precip = np.ma.masked_invalid(precip)

    # Handle colormap configuration
    if colormap_config is None:
        cmap, norm, clevs, clevs_str = get_colormap(ptype, units, colorscale)
    else:
        cmap, norm, clevs = _validate_colormap_config(colormap_config, ptype)
        clevs_str = _dynamic_formatting_floats(clevs)

    # Plot the precipitation field
    if regular_grid:
        im = _plot_field(precip, ax, extent, cmap, norm, origin=origin)
    else:
        im = _plot_field(precip, ax, extent, cmap, norm, x_grid=x_grid, y_grid=y_grid)

    plt.title(title)

    # Add colorbar
    if colorbar:
        if ptype in ["intensity", "depth"]:
            extend = "max"
        else:
            extend = "neither"
        cbar = plt.colorbar(
            im, ticks=clevs, spacing="uniform", extend=extend, shrink=0.8, cax=cax
        )
        if clevs_str is not None:
            cbar.ax.set_yticklabels(clevs_str)

        if ptype == "intensity":
            cbar.set_label(f"Precipitation intensity [{units}]")
        elif ptype == "depth":
            cbar.set_label(f"Precipitation depth [{units}]")
        else:
            cbar.set_label(f"P(R > {probthr:.1f} {units})")

    if geodata is None or axis == "off":
        ax.xaxis.set_ticks([])
        ax.xaxis.set_ticklabels([])
        ax.yaxis.set_ticks([])
        ax.yaxis.set_ticklabels([])

    if bbox is not None:
        ax.set_xlim(bbox[0], bbox[2])
        ax.set_ylim(bbox[1], bbox[3])

    return ax
Function to plot a precipitation intensity or probability field with a
colorbar.

.. _Axes: https://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes

.. _SubplotSpec: https://matplotlib.org/api/_as_gen/matplotlib.gridspec.SubplotSpec.html

Parameters
----------
precip: array-like
Two-dimensional array containing the input precipitation field or an
exceedance probability map.
ptype: {'intensity', 'depth', 'prob'}, optional
Type of the map to plot: 'intensity' = precipitation intensity field,
'depth' = precipitation depth (accumulation) field,
'prob' = exceedance probability field.
geodata: dictionary or None, optional
Optional dictionary containing geographical information about
the field. Required is map is not None.

If geodata is not None, it must contain the following key-value pairs:

.. tabularcolumns:: |p{1.5cm}|L|

+-----------------+---------------------------------------------------+
|        Key      |                  Value                            |
+=================+===================================================+
|    projection   | PROJ.4-compatible projection definition           |
+-----------------+---------------------------------------------------+
|    x1           | x-coordinate of the lower-left corner of the data |
|                 | raster                                            |
+-----------------+---------------------------------------------------+
|    y1           | y-coordinate of the lower-left corner of the data |
|                 | raster                                            |
+-----------------+---------------------------------------------------+
|    x2           | x-coordinate of the upper-right corner of the     |
|                 | data raster                                       |
+-----------------+---------------------------------------------------+
|    y2           | y-coordinate of the upper-right corner of the     |
|                 | data raster                                       |
+-----------------+---------------------------------------------------+
|    yorigin      | a string specifying the location of the first     |
|                 | element in the data raster w.r.t. y-axis:         |
|                 | 'upper' = upper border, 'lower' = lower border    |
+-----------------+---------------------------------------------------+
units : {'mm/h', 'mm', 'dBZ'}, optional
Units of the input array. If ptype is 'prob', this specifies the unit of
the intensity threshold.
bbox : tuple, optional
Four-element tuple specifying the coordinates of the bounding box. Use
this for plotting a subdomain inside the input grid. The coordinates are
of the form (lower left x, lower left y ,upper right x, upper right y).
If 'geodata' is not None, the bbox is in map coordinates, otherwise
it represents image pixels.
colorscale : {'pysteps', 'STEPS-BE', 'STEPS-NL', 'BOM-RF3'}, optional
Which colorscale to use. Applicable if units is 'mm/h', 'mm' or 'dBZ'.
probthr : float, optional
Intensity threshold to show in the color bar of the exceedance
probability map.
Required if ptype is "prob" and colorbar is True.
title : str, optional
If not None, print the title on top of the plot.
colorbar : bool, optional
If set to True, add a colorbar on the right side of the plot.
axis : {'off','on'}, optional
Whether to turn off or on the x and y axis.
cax : Axes_ object, optional
Axes into which the colorbar will be drawn. If no axes is provided
the colorbar axes are created next to the plot.
colormap_config : ColormapConfig, optional
Custom colormap configuration. If provided, this will override the
colorscale parameter.
The ColormapConfig class must have the following attributes: cmap,
norm, clevs.

Other parameters
----------------
map_kwargs: dict
Optional parameters that need to be passed to
:py:func:`pysteps.visualization.basemaps.plot_geography`.

Returns
-------
ax : fig Axes_
Figure axes. Needed if one wants to add e.g. text inside the plot.
pysteps/visualization/precipfields.py