# Path: frbpoppy/misc.py
# def hist(parameter, bin_type='lin', n_bins=25, norm='max', edges=True,
#          bins=None):
#     """Bin up a parameter either in a lin or log space.
# 
#     Why is this not a standard option in numpy or matplotlib?
# 
#     Args:
#         parameter (array): To be binned
#         bin_type (str): Either 'lin', 'log' or 'ln'
#         n_bins (int): Number of bins. Can be overriden internally
#         norm (bool): Whether to normalise to 'max' or 'prob' or none
# 
#     Returns:
#         tuple: bin centers, values per bin
# 
#     """
#     if isinstance(parameter, list):
#         parameter = np.array(parameter)
# 
#     if len(parameter) == 0:
#         return np.nan, np.nan
# 
#     # Drop NaN-values
#     parameter = parameter[~(np.isnan(parameter) | np.isinf(parameter))]
# 
#     # Determine number of bins
#     if n_bins != 25:
#         pass
#     elif len(parameter) < 50:
#         n_bins = 15
#     elif len(parameter) > 500:
#         n_bins = 50
# 
#     # Determine type of binning
#     if bin_type == 'lin':
#         _bins = n_bins
#     elif bin_type == 'log':
#         min_f = np.log10(np.min(parameter[parameter != 0]))
#         max_f = np.log10(max(parameter))
#         _bins = np.logspace(min_f, max_f, n_bins)
#     elif bin_type == 'ln':
#         min_f = np.log(np.min(parameter[parameter != 0]))
#         max_f = np.log(max(parameter))
#         _bins = np.logspace(min_f, max_f, n_bins, base=np.e)
# 
#     # Allow for custom bins
#     if bins is not None:
#         _bins = bins
# 
#     # Allow for probability weighting
#     weights = None
#     if norm == 'prob':
#         weights = np.ones(len(parameter)) / len(parameter)
# 
#     # Bin
#     n, bin_edges = np.histogram(parameter, bins=_bins, weights=weights)
# 
#     if norm == 'max':
#         n = n/max(n)  # Normalise
# 
#     # Centre bins
#     bins = (bin_edges[:-1] + bin_edges[1:]) / 2
# 
#     # Ensure there are edges on the outer bins of the histograms
#     if edges:
#         if bin_type == 'lin':
#             bin_dif = np.diff(bins)[-1]
#             bins = np.insert(bins, 0, bins[0] - bin_dif)
#             bins = np.insert(bins, len(bins), bins[-1] + bin_dif)
#             n = np.insert(n, 0, 0)
#             n = np.insert(n, len(n), 0)
#         else:
#             bin_dif = np.diff(np.log10(bins))[-1]
#             bins = np.insert(bins, 0, 10**(np.log10(bins[0])-bin_dif))
#             bins = np.insert(bins, len(bins), 10**(np.log10(bins[-1])+bin_dif))
#             n = np.insert(n, 0, 0)
#             n = np.insert(n, len(n), 0)
# 
#     return bins, n


import numpy as np
import matplotlib.pyplot as plt
from frbpoppy import hist
def lognormal(mean, std, shape):
    """Calculate the mean and std from the underlying distribution.

    See
    https://en.wikipedia.org/wiki/Log-normal_distribution
    """
    mean, std = calc_lognormal_input(mean, std)
    return np.random.lognormal(mean, std, shape)


fig, axes = plt.subplots(1, 1, sharey=True)

mean = 2.71**2
std = 5
size = int(1e4)

axes.set_xscale('log', basex=2.71)
colors = plt.rcParams['axes.prop_cycle'].by_key()['color']

data = lognormal(mean, std, size)
xy = hist(data, bin_type='log')
label = 'Distribution with input (frbpoppy)'
axes.step(*xy, where='mid', color=colors[0], label=label)
axes.axvline(mean, color=colors[0], linestyle='dotted')
axes.text(mean, 1, mean)
axes.axvline(mean+std, color=colors[0], linestyle='dotted')
axes.text(mean+std, 1, f'{mean}+{std}')


data = np.random.lognormal(mean, std, size)

# Path: frbpoppy/misc.py
# def hist(parameter, bin_type='lin', n_bins=25, norm='max', edges=True,
#          bins=None):
#     """Bin up a parameter either in a lin or log space.
# 
#     Why is this not a standard option in numpy or matplotlib?
# 
#     Args:
#         parameter (array): To be binned
#         bin_type (str): Either 'lin', 'log' or 'ln'
#         n_bins (int): Number of bins. Can be overriden internally
#         norm (bool): Whether to normalise to 'max' or 'prob' or none
# 
#     Returns:
#         tuple: bin centers, values per bin
# 
#     """
#     if isinstance(parameter, list):
#         parameter = np.array(parameter)
# 
#     if len(parameter) == 0:
#         return np.nan, np.nan
# 
#     # Drop NaN-values
#     parameter = parameter[~(np.isnan(parameter) | np.isinf(parameter))]
# 
#     # Determine number of bins
#     if n_bins != 25:
#         pass
#     elif len(parameter) < 50:
#         n_bins = 15
#     elif len(parameter) > 500:
#         n_bins = 50
# 
#     # Determine type of binning
#     if bin_type == 'lin':
#         _bins = n_bins
#     elif bin_type == 'log':
#         min_f = np.log10(np.min(parameter[parameter != 0]))
#         max_f = np.log10(max(parameter))
#         _bins = np.logspace(min_f, max_f, n_bins)
#     elif bin_type == 'ln':
#         min_f = np.log(np.min(parameter[parameter != 0]))
#         max_f = np.log(max(parameter))
#         _bins = np.logspace(min_f, max_f, n_bins, base=np.e)
# 
#     # Allow for custom bins
#     if bins is not None:
#         _bins = bins
# 
#     # Allow for probability weighting
#     weights = None
#     if norm == 'prob':
#         weights = np.ones(len(parameter)) / len(parameter)
# 
#     # Bin
#     n, bin_edges = np.histogram(parameter, bins=_bins, weights=weights)
# 
#     if norm == 'max':
#         n = n/max(n)  # Normalise
# 
#     # Centre bins
#     bins = (bin_edges[:-1] + bin_edges[1:]) / 2
# 
#     # Ensure there are edges on the outer bins of the histograms
#     if edges:
#         if bin_type == 'lin':
#             bin_dif = np.diff(bins)[-1]
#             bins = np.insert(bins, 0, bins[0] - bin_dif)
#             bins = np.insert(bins, len(bins), bins[-1] + bin_dif)
#             n = np.insert(n, 0, 0)
#             n = np.insert(n, len(n), 0)
#         else:
#             bin_dif = np.diff(np.log10(bins))[-1]
#             bins = np.insert(bins, 0, 10**(np.log10(bins[0])-bin_dif))
#             bins = np.insert(bins, len(bins), 10**(np.log10(bins[-1])+bin_dif))
#             n = np.insert(n, 0, 0)
#             n = np.insert(n, len(n), 0)
# 
#     return bins, n


# Path: tests/misc/understanding_lognormal.py
import numpy as np
import matplotlib.pyplot as plt
from frbpoppy import hist

def lognormal(mean, std, shape):
    """Calculate the mean and std from the underlying distribution.

    See
    https://en.wikipedia.org/wiki/Log-normal_distribution
    """
    mean, std = calc_lognormal_input(mean, std)
    return np.random.lognormal(mean, std, shape)


fig, axes = plt.subplots(1, 1, sharey=True)

mean = 2.71**2
std = 5
size = int(1e4)

axes.set_xscale('log', basex=2.71)
colors = plt.rcParams['axes.prop_cycle'].by_key()['color']

data = lognormal(mean, std, size)
xy = hist(data, bin_type='log')
label = 'Distribution with input (frbpoppy)'
axes.step(*xy, where='mid', color=colors[0], label=label)
axes.axvline(mean, color=colors[0], linestyle='dotted')
axes.text(mean, 1, mean)
axes.axvline(mean+std, color=colors[0], linestyle='dotted')
axes.text(mean+std, 1, f'{mean}+{std}')


data = np.random.lognormal(mean, std, size)

xy = hist(data, bin_type='log')