# Behaviour Changes

## Tk backend respects file format selection when saving figures

When saving a figure from a Tkinter GUI to a filename without an
extension, the file format is now selected based on the value of the
dropdown menu, rather than defaulting to PNG. When the filename contains
an extension, or the OS automatically appends one, the behavior remains
unchanged.

## Placing of maximum and minimum minor ticks

Calculation of minor tick locations has been corrected to make the
maximum and minimum minor ticks more consistent. In some cases this
results in an extra minor tick on an Axis.

## `hexbin` now defaults to `rcParams["patch.linewidth"]`

The default value of the *linewidths* argument of
[.Axes.hexbin]{.title-ref} has been changed from `1.0` to
`patch.linewidth`{.interpreted-text role="rc"}. This improves the
consistency with [.QuadMesh]{.title-ref} in
[.Axes.pcolormesh]{.title-ref} and [.Axes.hist2d]{.title-ref}.

## TwoSlopeNorm now auto-expands to always have two slopes

In the case where either `vmin` or `vmax` are not manually specified to
[\~.TwoSlopeNorm]{.title-ref}, and where the data it is scaling is all
less than or greater than the center point, the limits are now
auto-expanded so there are two symmetrically sized slopes either side of
the center point.

Previously `vmin` and `vmax` were clipped at the center point, which
caused issues when displaying color bars.

This does not affect behaviour when `vmin` and `vmax` are manually
specified by the user.

## Event objects emitted for `axes_leave_event`

`axes_leave_event` now emits a synthetic [.LocationEvent]{.title-ref},
instead of reusing the last event object associated with a
`motion_notify_event`.

## Streamplot now draws streamlines as one piece if no width or no color variance

Since there is no need to draw streamlines piece by piece if there is no
color change or width change, now streamplot will draw each streamline
in one piece.

The behavior for varying width or varying color is not changed, same
logic is used for these kinds of streamplots.

## `canvas` argument now required for `FigureFrameWx`

`FigureFrameWx` now requires a keyword-only `canvas` argument when it is
constructed.

## `ContourSet` is now a single Collection

Prior to this release, [.ContourSet]{.title-ref} (the object returned by
[\~.Axes.contour]{.title-ref}) was a custom object holding multiple
[.Collection]{.title-ref}s (and not an [.Artist]{.title-ref}) \-- one
collection per level, each connected component of that level\'s contour
being an entry in the corresponding collection.

[.ContourSet]{.title-ref} is now instead a plain
[.Collection]{.title-ref} (and thus an [.Artist]{.title-ref}). The
collection contains a single path per contour level; this path may be
non-continuous in case there are multiple connected components.

Setting properties on the ContourSet can now usually be done using
standard collection setters (`cset.set_linewidth(3)` to use the same
linewidth everywhere or `cset.set_linewidth([1, 2, 3, ...])` to set
different linewidths on each level) instead of having to go through the
individual sub-components (`cset.collections[0].set_linewidth(...)`).
Note that during the transition period, it remains possible to access
the (deprecated) `.collections` attribute; this causes the ContourSet to
modify itself to use the old-style multi-Collection representation.

## `SubFigure` default facecolor is now transparent

Subfigures default facecolor changed to `"none"`. Previously the default
was the value of `figure.facecolor`.

## Reject size related keyword arguments to MovieWriter *grab_frame* method

Although we pass [.Figure.savefig]{.title-ref} keyword arguments through
the [.AbstractMovieWriter.grab_frame]{.title-ref} some of the arguments
will result in invalid output if passed. To be successfully stitched
into a movie, each frame must be exactly the same size, thus
*bbox_inches* and *dpi* are excluded. Additionally, the movie writers
are opinionated about the format of each frame, so the *format* argument
is also excluded. Passing these arguments will now raise
[TypeError]{.title-ref} for all writers (it already did so for some
arguments and some writers). The *bbox_inches* argument is already
ignored (with a warning) if passed to [.Animation.save]{.title-ref}.

Additionally, if `savefig.bbox`{.interpreted-text role="rc"} is set to
`'tight'`, [.AbstractMovieWriter.grab_frame]{.title-ref} will now error.
Previously this rcParam would be temporarily overridden (with a warning)
in [.Animation.save]{.title-ref}, it is now additionally overridden in
[.AbstractMovieWriter.saving]{.title-ref}.

## Changes of API after deprecation

-   [.dviread.find_tex_file]{.title-ref} now raises
    [FileNotFoundError]{.title-ref} when the requested filename is not
    found.
-   [.Figure.colorbar]{.title-ref} now raises if *cax* is not given and
    it is unable to determine from which Axes to steal space, i.e. if
    *ax* is also not given and *mappable* has not been added to an Axes.
-   [.pyplot.subplot]{.title-ref} and [.pyplot.subplot2grid]{.title-ref}
    no longer auto-remove preexisting overlapping Axes; explicitly call
    `Axes.remove` as needed.

## Invalid types for Annotation xycoords now raise TypeError

Previously, a [RuntimeError]{.title-ref} would be raised in some cases.

## Default antialiasing behavior changes for `Text` and `Annotation`

`matplotlib.pyplot.annotate()` and `matplotlib.pyplot.text()` now
support parameter *antialiased* when initializing. Examples:

``` python
mpl.text.Text(.5, .5, "foo\nbar", antialiased=True)
plt.text(0.5, 0.5, '6 inches x 2 inches', antialiased=True)
ax.annotate('local max', xy=(2, 1), xytext=(3, 1.5), antialiased=False)
```

See \"What\'s New\" for more details on usage.

With this new feature, you may want to make sure that you are creating
and saving/showing the figure under the same context:

    # previously this was a no-op, now it is what works
    with rccontext(text.antialiased=False):
        fig, ax = plt.subplots()
        ax.annotate('local max', xy=(2, 1), xytext=(3, 1.5))
        fig.savefig('/tmp/test.png')

    # previously this had an effect, now this is a no-op
    fig, ax = plt.subplots()
    ax.annotate('local max', xy=(2, 1), xytext=(3, 1.5))
    with rccontext(text.antialiased=False):
        fig.savefig('/tmp/test.png')

Also note that antialiasing for tick labels will be set with
`text.antialiased`{.interpreted-text role="rc"} when they are created
(usually when a `Figure` is created) - This means antialiasing for them
can no longer be changed by modifying
`text.antialiased`{.interpreted-text role="rc"}.

## `ScalarMappable.to_rgba()` now respects the mask of RGB(A) arrays

Previously, the mask was ignored. Now the alpha channel is set to 0 if
any component (R, G, B, or A) is masked.

## `Text.get_rotation_mode` return value

Passing `None` as `rotation_mode` to [.Text]{.title-ref} (the default
value) or passing it to [.Text.set_rotation_mode]{.title-ref} will make
[.Text.get_rotation_mode]{.title-ref} return `"default"` instead of
`None`. The behaviour otherwise is the same.

## PostScript paper size adds option to use figure size

The `ps.papersize`{.interpreted-text role="rc"} rcParam can now be set
to `'figure'`, which will use a paper size that corresponds exactly with
the size of the figure that is being saved.

## `hexbin` *mincnt* parameter made consistently inclusive

Previously, *mincnt* was inclusive with no *C* provided but exclusive
when *C* is provided. It is now inclusive of *mincnt* in both cases.

# `matplotlib.mpl_toolkits` is now an implicit namespace package

Following the deprecation of `pkg_resources.declare_namespace` in
`setuptools` 67.3.0, `matplotlib.mpl_toolkits` is now implemented as an
implicit namespace, following [PEP
420](https://peps.python.org/pep-0420/).

As a consequence using `pip` to install a version of Matplotlib \>= 3.8
on top of a version of Matplotlib \< 3.8 (e.g. via `pip install --local`
or `python -m venv --system-site-packages ...`) will fail because the
old `matplotlib.mpl_toolkits` files will be found whereas the newer
files will be found for all other modules. This will result in errors
due to the version mismatch.

To avoid this issue you need to avoid having multiple versions of
Matplotlib in different entries of `sys.path`. Either uninstall
Matplotlib at the system level or use a more isolated virtual
environment.