8000 FIX: if bins input to hist is str, treat like no bins by tacaswell · Pull Request #8638 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

FIX: if bins input to hist is str, treat like no bins #8638

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 2, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
FIX: restore (and test) handling of nan in hist data
  • Loading branch information
tacaswell committed Apr 1, 2019
commit c6f05548c7e4b7bf8ce90b4eb71ad884e15563c8
28 changes: 24 additions & 4 deletions lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@
try:
from numpy.lib.histograms import histogram_bin_edges
except ImportError:
# this function is new in np 1.15
def histogram_bin_edges(arr, bins, range=None, weights=None):
# this in True for 1D arrays, and False for None and str
if np.ndim(bins) == 1:
return bins

if isinstance(bins, str):
# rather than backporting the internals, just do the full
# computation. If this is too slow for users, they can
Expand Down Expand Up @@ -6630,9 +6635,6 @@ def hist(self, x, bins=None, range=None, density=None, weights=None,
if bin_range is not None:
bin_range = self.convert_xunits(bin_range)

# this in True for 1D arrays, and False for None and str
bins_array_given = np.ndim(bins) == 1

# We need to do to 'weights' what was done to 'x'
if weights is not None:
w = cbook._reshape_2D(weights, 'weights')
Expand All @@ -6659,14 +6661,32 @@ def hist(self, x, bins=None, range=None, density=None, weights=None,

hist_kwargs = dict()

# if the bin_range is not given, compute without nan numpy
# does not do this for us when guessing the range (but will
# happily ignore nans when computing the histogram).
if bin_range is None:
xmin = np.inf
xmax = -np.inf
for xi in x:
if len(xi):
# python's min/max ignore nan,
# np.minnan returns nan for all nan input
xmin = min(xmin, np.nanmin(xi))
xmax = max(xmax, np.nanmax(xi))
# make sure we have seen at least one non-nan and finite
# value before we reset the bin range
if not np.isnan([xmin, xmax]).any() and not (xmin > xmax):
bin_range = (xmin, xmax)

# If bins are not specified either explicitly or via range,
# we need to figure out the range required for all datasets,
# and supply that to np.histogram.
if not bins_array_given and not input_empty and len(x) > 1:
if not input_empty and len(x) > 1:
if weights is not None:
_w = np.concatenate(w)
else:
_w = None

bins = histogram_bin_edges(np.concatenate(x),
bins, bin_range, _w)
else:
Expand Down
14 changes: 14 additions & 0 deletions lib/matplotlib/tests/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6352,3 +6352,17 @@ def test_hist_auto_bins():
_, bins, _ = plt.hist([[1, 2, 3], [3, 4, 5, 6]], bins='auto')
assert bins[0] <= 1
assert bins[-1] >= 6


def test_hist_nan_data():
fig, (ax1, ax2) = plt.subplots(2)

data = [1, 2, 3]
nan_data = data + [np.nan]

bins, edges, _ = ax1.hist(data)
with np.errstate(invalid='ignore'):
nanbins, nanedges, _ = ax2.hist(nan_data)

assert np.allclose(bins, nanbins)
assert np.allclose(edges, nanedges)
0