diff --git a/doc/api/next_api_changes/behavior/27179-KS.rst b/doc/api/next_api_changes/behavior/27179-KS.rst new file mode 100644 index 000000000000..873cd622bbd4 --- /dev/null +++ b/doc/api/next_api_changes/behavior/27179-KS.rst @@ -0,0 +1,7 @@ +Default behavior of ``hexbin`` with *C* provided requires at least 1 point +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The behavior changed in 3.8.0 to be inclusive of *mincnt*. However that resulted in +errors or warnings with some reduction functions, so now the default is to require at +least 1 point to call the reduction function. This effectively restores the default +behavior to match that of Matplotlib 3.7 and before. diff --git a/doc/api/prev_api_changes/api_changes_3.8.0/behaviour.rst b/doc/api/prev_api_changes/api_changes_3.8.0/behaviour.rst index 37176f99972b..fd38708c9243 100644 --- a/doc/api/prev_api_changes/api_changes_3.8.0/behaviour.rst +++ b/doc/api/prev_api_changes/api_changes_3.8.0/behaviour.rst @@ -165,3 +165,9 @@ PostScript paper type adds option to use figure size The :rc:`ps.papertype` 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. diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 9997e660f40c..b4a41099beda 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -4858,8 +4858,8 @@ def hexbin(self, x, y, C=None, gridsize=100, bins=None, yscale : {'linear', 'log'}, default: 'linear' Use a linear or log10 scale on the vertical axis. - mincnt : int > 0, default: *None* - If not *None*, only display cells with more than *mincnt* + mincnt : int >= 0, default: *None* + If not *None*, only display cells with at least *mincnt* number of points in the cell. marginals : bool, default: *False* @@ -4926,6 +4926,11 @@ def reduce_C_function(C: array) -> float - `numpy.sum`: integral of the point values - `numpy.amax`: value taken from the largest point + By default will only reduce cells with at least 1 point because some + reduction functions (such as `numpy.amax`) will error/warn with empty + input. Changing *mincnt* will adjust the cutoff, and if set to 0 will + pass empty input to the reduction function. + data : indexable object, optional DATA_PARAMETER_PLACEHOLDER @@ -5023,7 +5028,7 @@ def reduce_C_function(C: array) -> float else: Cs_at_i2[i2[i]].append(C[i]) if mincnt is None: - mincnt = 0 + mincnt = 1 accum = np.array( [reduce_C_function(acc) if len(acc) >= mincnt else np.nan for Cs_at_i in [Cs_at_i1, Cs_at_i2] diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 30992d5780ed..6c5dd712b7fd 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -965,6 +965,8 @@ def test_hexbin_empty(): # From #23922: creating hexbin with log scaling from empty # dataset raises ValueError ax.hexbin([], [], bins='log') + # From #27103: np.max errors when handed empty data + ax.hexbin([], [], C=[], reduce_C_function=np.max) def test_hexbin_pickable():