3636from matplotlib .axes ._base import _AxesBase , _process_plot_format
3737from matplotlib .axes ._secondary_axes import SecondaryAxis
3838
39+ try :
40+ from numpy .lib .histograms import histogram_bin_edges
41+ except ImportError :
42+ # this function is new in np 1.15
43+ def histogram_bin_edges (arr , bins , range = None , weights = None ):
44+ # this in True for 1D arrays, and False for None and str
45+ if np .ndim (bins ) == 1 :
46+ return bins
47+
48+ if isinstance (bins , str ):
49+ # rather than backporting the internals, just do the full
50+ # computation. If this is too slow for users, they can
51+ # update numpy, or pick a manual number of bins
52+ return np .histogram (arr , bins , range , weights )[1 ]
53+ else :
54+ if bins is None :
55+ # hard-code numpy's default
56+ bins = 10
57+ if range is None :
58+ range = np .min (arr ), np .max (arr )
59+
60+ return np .linspace (* range , bins + 1 )
61+
62+
3963_log = logging .getLogger (__name__ )
4064
4165
@@ -6611,9 +6635,6 @@ def hist(self, x, bins=None, range=None, density=None, weights=None,
66116635 if bin_range is not None :
66126636 bin_range = self .convert_xunits (bin_range )
66136637
6614- # Check whether bins or range are given explicitly.
6615- binsgiven = np .iterable (bins ) or bin_range is not None
6616-
66176638 # We need to do to 'weights' what was done to 'x'
66186639 if weights is not None :
66196640 w = cbook ._reshape_2D (weights , 'weights' )
@@ -6638,22 +6659,42 @@ def hist(self, x, bins=None, range=None, density=None, weights=None,
66386659 "sets and %d colors were provided" % (nx , len (color )))
66396660 raise ValueError (error_message )
66406661
6641- # If bins are not specified either explicitly or via range,
6642- # we need to figure out the range required for all datasets,
6643- # and supply that to np.histogram.
6644- if not binsgiven and not input_empty :
6662+ hist_kwargs = dict ()
6663+
6664+ # if the bin_range is not given, compute without nan numpy
6665+ # does not do this for us when guessing the range (but will
6666+ # happily ignore nans when computing the histogram).
6667+ if bin_range is None :
66456668 xmin = np .inf
66466669 xmax = - np .inf
66476670 for xi in x :
6648- if len (xi ) > 0 :
6671+ if len (xi ):
6672+ # python's min/max ignore nan,
6673+ # np.minnan returns nan for all nan input
66496674 xmin = min (xmin , np .nanmin (xi ))
66506675 xmax = max (xmax , np .nanmax (xi ))
6651- bin_range = (xmin , xmax )
6676+ # make sure we have seen at least one non-nan and finite
6677+ # value before we reset the bin range
6678+ if not np .isnan ([xmin , xmax ]).any () and not (xmin > xmax ):
6679+ bin_range = (xmin , xmax )
6680+
6681+ # If bins are not specified either explicitly or via range,
6682+ # we need to figure out the range required for all datasets,
6683+ # and supply that to np.histogram.
6684+ if not input_empty and len (x ) > 1 :
6685+ if weights is not None :
6686+ _w = np .concatenate (w )
6687+ else :
6688+ _w = None
6689+
6690+ bins = histogram_bin_edges (np .concatenate (x ),
6691+ bins , bin_range , _w )
6692+ else :
6693+ hist_kwargs ['range' ] = bin_range
6694+
66526695 density = bool (density ) or bool (normed )
66536696 if density and not stacked :
6654- hist_kwargs = dict (range = bin_range , density = density )
6655- else :
6656- hist_kwargs = dict (range = bin_range )
6697+ hist_kwargs = dict (density = density )
66576698
66586699 # List to store all the top coordinates of the histograms
66596700 tops = []
0 commit comments