1# Licensed under a 3-clause BSD style license - see LICENSE.rst
2
3from astropy.stats.histogram import calculate_bin_edges
4
5__all__ = ['hist']
6
7
8def hist(x, bins=10, ax=None, max_bins=1e5, **kwargs):
9    """Enhanced histogram function
10
11    This is a histogram function that enables the use of more sophisticated
12    algorithms for determining bins.  Aside from the ``bins`` argument allowing
13    a string specified how bins are computed, the parameters are the same
14    as pylab.hist().
15
16    This function was ported from astroML: https://www.astroml.org/
17
18    Parameters
19    ----------
20    x : array-like
21        array of data to be histogrammed
22
23    bins : int, list, or str, optional
24        If bins is a string, then it must be one of:
25
26        - 'blocks' : use bayesian blocks for dynamic bin widths
27
28        - 'knuth' : use Knuth's rule to determine bins
29
30        - 'scott' : use Scott's rule to determine bins
31
32        - 'freedman' : use the Freedman-Diaconis rule to determine bins
33
34    ax : `~matplotlib.axes.Axes` instance, optional
35        Specify the Axes on which to draw the histogram. If not specified,
36        then the current active axes will be used.
37
38    max_bins : int, optional
39        Maximum number of bins allowed. With more than a few thousand bins
40        the performance of matplotlib will not be great. If the number of
41        bins is large *and* the number of input data points is large then
42        the it will take a very long time to compute the histogram.
43
44    **kwargs :
45        other keyword arguments are described in ``plt.hist()``.
46
47    Notes
48    -----
49    Return values are the same as for ``plt.hist()``
50
51    See Also
52    --------
53    astropy.stats.histogram
54    """
55    # Note that we only calculate the bin edges...matplotlib will calculate
56    # the actual histogram.
57    range = kwargs.get('range', None)
58    weights = kwargs.get('weights', None)
59    bins = calculate_bin_edges(x, bins, range=range, weights=weights)
60
61    if len(bins) > max_bins:
62        raise ValueError('Histogram has too many bins: '
63                         '{nbin}. Use max_bins to increase the number '
64                         'of allowed bins or range to restrict '
65                         'the histogram range.'.format(nbin=len(bins)))
66
67    if ax is None:
68        # optional dependency; only import if strictly needed.
69        import matplotlib.pyplot as plt
70        ax = plt.gca()
71
72    return ax.hist(x, bins, **kwargs)
73