36
36
from matplotlib .axes ._base import _AxesBase , _process_plot_format
37
37
from matplotlib .axes ._secondary_axes import SecondaryAxis
38
38
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
+
39
63
_log = logging .getLogger (__name__ )
40
64
41
65
@@ -6649,9 +6673,6 @@ def hist(self, x, bins=None, range=None, density=None, weights=None,
6649
6673
if bin_range is not None :
6650
6674
bin_range = self .convert_xunits (bin_range )
6651
6675
6652
- # Check whether bins or range are given explicitly.
6653
- binsgiven = np .iterable (bins ) or bin_range is not None
6654
-
6655
6676
# We need to do to 'weights' what was done to 'x'
6656
6677
if weights is not None :
6657
6678
w = cbook ._reshape_2D (weights , 'weights' )
@@ -6676,22 +6697,42 @@ def hist(self, x, bins=None, range=None, density=None, weights=None,
6676
6697
"sets and %d colors were provided" % (nx , len (color )))
6677
6698
raise ValueError (error_message )
6678
6699
6679
- # If bins are not specified either explicitly or via range,
6680
- # we need to figure out the range required for all datasets,
6681
- # and supply that to np.histogram.
6682
- if not binsgiven and not input_empty :
6700
+ hist_kwargs = dict ()
6701
+
6702
+ # if the bin_range is not given, compute without nan numpy
6703
+ # does not do this for us when guessing the range (but will
6704
+ # happily ignore nans when computing the histogram).
6705
+ if bin_range is None :
6683
6706
xmin = np .inf
6684
6707
xmax = - np .inf
6685
6708
for xi in x :
6686
- if len (xi ) > 0 :
6709
+ if len (xi ):
6710
+ # python's min/max ignore nan,
6711
+ # np.minnan returns nan for all nan input
6687
6712
xmin = min (xmin , np .nanmin (xi ))
6688
6713
xmax = max (xmax , np .nanmax (xi ))
6689
- bin_range = (xmin , xmax )
6714
+ # make sure we have seen at least one non-nan and finite
6715
+ # value before we reset the bin range
6716
+ if not np .isnan ([xmin , xmax ]).any () and not (xmin > xmax ):
6717
+ bin_range = (xmin , xmax )
6718
+
6719
+ # If bins are not specified either explicitly or via range,
6720
+ # we need to figure out the range required for all datasets,
6721
+ # and supply that to np.histogram.
6722
+ if not input_empty and len (x ) > 1 :
6723
+ if weights is not None :
6724
+ _w = np .concatenate (w )
6725
+ else :
6726
+ _w = None
6727
+
6728
+ bins = histogram_bin_edges (np .concatenate (x ),
6729
+ bins , bin_range , _w )
6730
+ else :
6731
+ hist_kwargs ['range' ] = bin_range
6732
+
6690
6733
density = bool (density ) or bool (normed )
6691
6734
if density and not stacked :
6692
- hist_kwargs = dict (range = bin_range , density = density )
6693
- else :
6694
- hist_kwargs = dict (range = bin_range )
6735
+ hist_kwargs = dict (density = density )
6695
6736
6696
6737
# List to store all the top coordinates of the histograms
6697
6738
tops = []
0 commit comments