forked from matplotlib/matplotlib
-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Inconsistent behavior of hexbins mincnt parameter, depending on C parameter
Task reference: ID 282
Bug report
Bug summary
Different behavior of hexbin's mincnt parameter, depending on whether the C parameter is supplied.
Code for reproduction
from matplotlib import pyplot
import numpy as np
np.random.seed(42)
X, Y = np.random.multivariate_normal([0.0, 0.0], [[1.0, 0.1], [0.1, 1.0]], size=250).T
Z = np.ones_like(X)
extent = [-3., 3., -3., 3.]
gridsize = (7, 7)
# no mincnt, no C
fig, ax = pyplot.subplots(1, 1)
ax.hexbin(X, Y, extent=extent, gridsize=gridsize, linewidth=0.0, cmap='Blues')
ax.set_facecolor("green")
# mincnt=1, no C
fig, ax = pyplot.subplots(1, 1)
ax.hexbin(X, Y, mincnt=1, extent=extent, gridsize=gridsize, linewidth=0.0, cmap='Blues')
ax.set_facecolor("green")
# no mincnt, with C
fig, ax = pyplot.subplots(1, 1)
ax.hexbin(X, Y, C=Z, reduce_C_function=np.sum, extent=extent, gridsize=gridsize, linewidth=0.0, cmap='Blues')
ax.set_facecolor("green")
# mincnt=1, with C
fig, ax = pyplot.subplots(1, 1)
ax.hexbin(X, Y, C=Z, reduce_C_function=np.sum, mincnt=1, extent=extent, gridsize=gridsize, linewidth=0.0, cmap='Blues')
ax.set_facecolor("green")
# mincnt=0, with C
fig, ax = pyplot.subplots(1, 1)
ax.hexbin(X, Y, C=Z, reduce_C_function=np.sum, mincnt=0, extent=extent, gridsize=gridsize, linewidth=0.0, cmap='Blues')
ax.set_facecolor("green")Actual outcome
- With no
Cspecified,mincnt=1shows bins with at least one datum. - With
Cspecified but notmincnt, bins with at least one datum are shown. - With
Cspecified andmincnt=1, bins require at least two datapoints (unexpected off-by-one).
Expected outcome
With mincnt == 1, the same gridpoints should be plotted whether C is supplied or not—i.e., bins with at least one point should be included.
Additional resources
- Prior behavior discussion: matplotlib@5b127df
Research and proposed resolution (by Emerson Gray)
Code locations (branch matplotlib__matplotlib-26113):
- File:
lib/matplotlib/axes/_axes.py,Axes.hexbin - C is None path effectively applies
counts >= mincntby settingaccum[accum < mincnt] = np.nan. - C is not None path uses
len(acc) > mincntto decide reducing viareduce_C_function, and defaultsmincntto0when None—leading to off-by-one relative to the C is None path.
Proposed fix:
- In the
Cis not None path:- If
mincnt is None, setmincnt = 1(default excludes empty bins consistently). - Change reduction decision to
len(acc) >= mincnt(parity with the C is None path).
- If
- Update docstring for
mincntto state “at least mincnt” points instead of “more than mincnt”.
Potential side effects considered:
- Avoids calling
reduce_C_function([])by defaultingmincntto 1; parity achieved without breaking expected behavior. - Masked arrays and color mapping continue to treat failing bins as NaN; unaffected.
bins='log'/norm autoscale unaffected; marginals compute reduces wherelen(ci) > 0independent of mincnt.
Unit tests to add:
- Deterministic dataset with two points in separate bins:
X=Y=[0.1, 1.6],gridsize=(2,2),extent=(0,2,0,2).- Test A:
C=None,mincnt=1includes both bins, values equal to 1. - Test B:
C=np.ones_like(X),reduce_C_function=np.sum,mincnt=1includes both bins, sums equal to 1. - Optional:
mincnt=2excludes bins with a single point for both paths.
- Test A:
We will submit a PR implementing this change and tests, targeting base branch matplotlib__matplotlib-26113.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working