Skip to content

hexbin passes empty bins to reduce_C_function when mincnt is 0 or None #32077

Description

@SuYanqi

Bug summary

Empty bins are passed to the C reducer when mincnt is zero or None. This causes reducers such as np.sum to produce spurious zero-valued bins, while custom reducers may raise an exception.

Code for reproduction

import numpy as np
import matplotlib.pyplot as plt

x = [0.25]
y = [0.25]
c = [3.0]
mincnt = 0

def reject_empty(values):
    if len(values) == 0:
        raise ValueError("empty bin passed to reducer")
    return float(np.sum(values))

print("Inputs:", {"x": x, "y": y, "C": c, "mincnt": mincnt})
try:
    fig, ax = plt.subplots()
    collection = ax.hexbin(
        x, y, C=c, gridsize=3, extent=(0, 1, 0, 1),
        reduce_C_function=reject_empty, mincnt=mincnt
    )
    print("Bin offsets:", collection.get_offsets().tolist())
    print("Reduced values:", collection.get_array().tolist())
    plt.close(fig)
except Exception as exc:
    print(str(exc))

Actual outcome

Inputs: {'x': [0.25], 'y': [0.25], 'C': [3.0], 'mincnt': 0}
empty bin passed to reducer

Expected outcome

Empty bins should not be passed to reduce_C_function. The output should contain only the non-empty bin:

Inputs: {'x': [0.25], 'y': [0.25], 'C': [3.0], 'mincnt': 0}
Bin offsets: [[0.333333333, 0.0]]
Reduced values: [3.0]

Additional information

This is a regression introduced by PR #26113: #26113

The bin-inclusion condition was changed from count > mincnt to count >= mincnt. Consequently, zero-count bins are processed when mincnt is 0. When C is provided and mincnt is None, it is internally set to 0, producing the same behavior. Reducers such as np.sum return spurious zero-valued bins for empty inputs, while custom reducers may raise an exception.

Operating system

Linux

Matplotlib Version

3.11.1

Matplotlib Backend

agg

Python version

3.11.13

Jupyter version

N/A

Installation

N/A

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions