Ejemplo n.º 1
0
def fastkde_2d(d_x, d_y, xmin=None, xmax=None, ymin=None, ymax=None):
    """Perform a two-dimensional kernel density estimation.

    Wrapper round fastkde.fastKDE. Boundary corrections implemented by
    reflecting boundary conditions.

    Parameters
    ----------
    d_x, d_y: numpy.array
        x/y coordinates of data to perform kde on

    xmin, xmax, ymin, ymax: float
        lower/upper prior bounds in x/y coordinates
        optional, default None

    Returns
    -------
    x,y: numpy.array
        x/y-coordinates of kernel density estimates. One-dimensional array
    p: numpy.array
        kernel density estimates. Two-dimensional array

    """
    xmin, xmax = check_bounds(d_x, xmin, xmax)
    ymin, ymax = check_bounds(d_y, ymin, ymax)
    f = [xmax is None or xmin is None, ymax is None or ymin is None]
    d_x_, d_y_ = mirror_2d(d_x, d_y, xmin, xmax, ymin, ymax)

    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        p, (x, y) = fastKDE.pdf(d_x_,
                                d_y_,
                                axisExpansionFactor=f,
                                numPointsPerSigma=10 * (2 - f[0]) * (2 - f[1]))

    p *= (2 - f[0])
    p *= (2 - f[1])
    if xmin is not None:
        p = p[:, x >= xmin]
        x = x[x >= xmin]

    if xmax is not None:
        p = p[:, x <= xmax]
        x = x[x <= xmax]

    if ymin is not None:
        p = p[y >= ymin, :]
        y = y[y >= ymin]

    if ymax is not None:
        p = p[y <= ymax, :]
        y = y[y <= ymax]

    return x, y, p
Ejemplo n.º 2
0
def scatter_plot_2d(ax, data_x, data_y, *args, **kwargs):
    """Plot samples from a 2d marginalised distribution.

    This functions as a wrapper around matplotlib.axes.Axes.plot, enforcing any
    prior bounds. All remaining keyword arguments are passed onwards.

    Parameters
    ----------
    ax: matplotlib.axes.Axes
        axis object to plot on

    data_x, data_y: np.array
        x and y coordinates of uniformly weighted samples to plot.

    xmin, xmax, ymin, ymax: float
        lower/upper prior bounds in x/y coordinates
        optional, default None

    Returns
    -------
    lines: matplotlib.lines.Line2D
        A list of line objects representing the plotted data (same as
        matplotlib matplotlib.axes.Axes.plot command)

    """
    kwargs = normalize_kwargs(kwargs,
                              dict(color=['c'],
                                   mfc=['facecolor', 'fc'],
                                   mec=['edgecolor', 'ec']),
                              drop=['ls', 'lw'])
    kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
    xmin = kwargs.pop('xmin', None)
    xmax = kwargs.pop('xmax', None)
    ymin = kwargs.pop('ymin', None)
    ymax = kwargs.pop('ymax', None)
    kwargs.pop('q', None)
    markersize = kwargs.pop('markersize', 1)
    cmap = kwargs.pop('cmap', None)
    color = kwargs.pop('color', (next(ax._get_lines.prop_cycler)['color']
                                 if cmap is None else cmap(0.68)))

    points = ax.plot(data_x,
                     data_y,
                     'o',
                     color=color,
                     markersize=markersize,
                     *args,
                     **kwargs)
    ax.set_xlim(*check_bounds(data_x, xmin, xmax), auto=True)
    ax.set_ylim(*check_bounds(data_y, ymin, ymax), auto=True)
    return points
Ejemplo n.º 3
0
def kde_plot_1d(ax, data, *args, **kwargs):
    """Plot a 1d marginalised distribution.

    This functions as a wrapper around matplotlib.axes.Axes.plot, with a kernel
    density estimation computation provided by scipy.stats.gaussian_kde in
    between. All remaining keyword arguments are passed onwards.

    Parameters
    ----------
    ax: matplotlib.axes.Axes
        axis object to plot on.

    data: numpy.array
        Samples to generate kernel density estimator.

    weights: numpy.array, optional
        Sample weights.

    ncompress: int, optional
        Degree of compression. Default 1000

    xmin, xmax: float
        lower/upper prior bound.
        optional, default None

    Returns
    -------
    lines: matplotlib.lines.Line2D
        A list of line objects representing the plotted data (same as
        matplotlib matplotlib.axes.Axes.plot command)

    """
    if len(data) == 0:
        return numpy.zeros(0), numpy.zeros(0)

    if data.max() - data.min() <= 0:
        return

    xmin = kwargs.pop('xmin', None)
    xmax = kwargs.pop('xmax', None)
    weights = kwargs.pop('weights', None)
    ncompress = kwargs.pop('ncompress', 1000)
    x, w = sample_compression_1d(data, weights, ncompress)
    kde = gaussian_kde(x, weights=w)
    p = kde(x)
    p /= p.max()
    i = ((x < quantile(x, 0.999, w)) & (x > quantile(x, 0.001, w))) | (p > 0.1)
    if xmin is not None:
        i = i & (x > xmin)
    if xmax is not None:
        i = i & (x < xmax)
    sigma = numpy.sqrt(kde.covariance[0, 0])
    pp = cut_and_normalise_gaussian(x[i], p[i], sigma, xmin, xmax)
    pp /= pp.max()
    ans = ax.plot(x[i], pp, *args, **kwargs)
    ax.set_xlim(*check_bounds(x[i], xmin, xmax), auto=True)
    return ans
Ejemplo n.º 4
0
def scatter_plot_2d(ax, data_x, data_y, *args, **kwargs):
    """Plot samples from a 2d marginalised distribution.

    This functions as a wrapper around matplotlib.axes.Axes.plot, enforcing any
    prior bounds. All remaining keyword arguments are passed onwards.

    Parameters
    ----------
    ax: matplotlib.axes.Axes
        axis object to plot on

    data_x, data_y: numpy.array
        x and y coordinates of uniformly weighted samples to plot.

    xmin, xmax, ymin, ymax: float
        lower/upper prior bounds in x/y coordinates
        optional, default None

    Returns
    -------
    lines: matplotlib.lines.Line2D
        A list of line objects representing the plotted data (same as
        matplotlib matplotlib.axes.Axes.plot command)

    """
    xmin = kwargs.pop('xmin', None)
    xmax = kwargs.pop('xmax', None)
    ymin = kwargs.pop('ymin', None)
    ymax = kwargs.pop('ymax', None)
    markersize = kwargs.pop('markersize', 1)

    points = ax.plot(data_x,
                     data_y,
                     'o',
                     markersize=markersize,
                     *args,
                     **kwargs)
    ax.set_xlim(*check_bounds(data_x, xmin, xmax), auto=True)
    ax.set_ylim(*check_bounds(data_y, ymin, ymax), auto=True)
    return points
Ejemplo n.º 5
0
def fastkde_plot_1d(ax, data, *args, **kwargs):
    """Plot a 1d marginalised distribution.

    This functions as a wrapper around matplotlib.axes.Axes.plot, with a kernel
    density estimation computation provided by the package fastkde in between.
    All remaining keyword arguments are passed onwards.

    Parameters
    ----------
    ax: matplotlib.axes.Axes
        axis object to plot on

    data: np.array
        Uniformly weighted samples to generate kernel density estimator.

    xmin, xmax: float
        lower/upper prior bound
        optional, default None

    Returns
    -------
    lines: matplotlib.lines.Line2D
        A list of line objects representing the plotted data (same as
        matplotlib matplotlib.axes.Axes.plot command)

    """
    if len(data) == 0:
        return np.zeros(0), np.zeros(0)

    if data.max() - data.min() <= 0:
        return

    xmin = kwargs.pop('xmin', None)
    xmax = kwargs.pop('xmax', None)
    cmap = kwargs.pop('cmap', None)
    color = kwargs.pop('color', (next(ax._get_lines.prop_cycler)['color']
                                 if cmap is None else cmap(0.68)))
    q = kwargs.pop('q', '5sigma')
    q = quantile_plot_interval(q=q)

    try:
        x, p = fastkde_1d(data, xmin, xmax)
    except NameError:
        raise ImportError("You need to install fastkde to use fastkde")
    p /= p.max()
    i = ((x > quantile(x, q[0], p)) & (x < quantile(x, q[1], p)))

    ans = ax.plot(x[i], p[i], color=color, *args, **kwargs)
    ax.set_xlim(*check_bounds(x[i], xmin, xmax), auto=True)
    return ans
Ejemplo n.º 6
0
def fastkde_1d(d, xmin=None, xmax=None):
    """Perform a one-dimensional kernel density estimation.

    Wrapper round fastkde.fastKDE. Boundary corrections implemented by
    reflecting boundary conditions.

    Parameters
    ----------
    d: numpy.array
        Data to perform kde on

    xmin, xmax: float
        lower/upper prior bounds
        optional, default None

    Returns
    -------
    x: numpy.array
        x-coordinates of kernel density estimates
    p: numpy.array
        kernel density estimates

    """
    xmin, xmax = check_bounds(d, xmin, xmax)
    f = xmax is None or xmin is None
    d_ = mirror_1d(d, xmin, xmax)
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        p, x = fastKDE.pdf(d_,
                           axisExpansionFactor=f,
                           numPointsPerSigma=10 * (2 - f))
    p *= 2 - f

    if xmin is not None:
        p = p[x >= xmin]
        x = x[x >= xmin]

    if xmax is not None:
        p = p[x <= xmax]
        x = x[x <= xmax]

    return x, p
Ejemplo n.º 7
0
def hist_plot_2d(ax, data_x, data_y, *args, **kwargs):
    """Plot a 2d marginalised distribution as a histogram.

    This functions as a wrapper around matplotlib.axes.Axes.hist2d

    Parameters
    ----------
    ax: matplotlib.axes.Axes
        axis object to plot on

    data_x, data_y: numpy.array
        x and y coordinates of uniformly weighted samples to generate kernel
        density estimator.

    xmin, xmax, ymin, ymax: float
        lower/upper prior bounds in x/y coordinates
        optional, default None

    levels: list
        Shade iso-probability contours containing these levels of probability
        mass. If None defaults to usual matplotlib.axes.Axes.hist2d colouring.
        optional, default None

    Returns
    -------
    c: matplotlib.collections.QuadMesh
        A set of colors

    """
    xmin = kwargs.pop('xmin', None)
    xmax = kwargs.pop('xmax', None)
    ymin = kwargs.pop('ymin', None)
    ymax = kwargs.pop('ymax', None)
    label = kwargs.pop('label', None)
    levels = kwargs.pop('levels', None)
    color = kwargs.pop('color', next(ax._get_lines.prop_cycler)['color'])

    if len(data_x) == 0 or len(data_y) == 0:
        return numpy.zeros(0), numpy.zeros(0), numpy.zeros((0, 0))

    cmap = basic_cmap(color)

    if levels is None:
        pdf, x, y, image = ax.hist2d(data_x,
                                     data_y,
                                     cmap=cmap,
                                     *args,
                                     **kwargs)
    else:
        bins = kwargs.pop('bins', 10)
        range = kwargs.pop('range', None)
        density = kwargs.pop('density', False)
        weights = kwargs.pop('weights', None)
        cmin = kwargs.pop('cmin', None)
        cmax = kwargs.pop('cmax', None)
        pdf, x, y = numpy.histogram2d(data_x, data_y, bins, range, density,
                                      weights)
        levels = iso_probability_contours(pdf, levels)
        pdf = numpy.digitize(pdf, levels, right=True)
        pdf = numpy.array(levels)[pdf]
        pdf = numpy.ma.masked_array(pdf, pdf < levels[1])
        if cmin is not None:
            pdf[pdf < cmin] = numpy.ma.masked
        if cmax is not None:
            pdf[pdf > cmax] = numpy.ma.masked
        image = ax.pcolormesh(x,
                              y,
                              pdf.T,
                              cmap=cmap,
                              vmin=0,
                              vmax=pdf.max(),
                              *args,
                              **kwargs)

    ax.patches += [
        plt.Rectangle((0, 0),
                      1,
                      1,
                      fc=cmap(0.999),
                      ec=cmap(0.32),
                      lw=2,
                      label=label)
    ]

    ax.set_xlim(*check_bounds(x, xmin, xmax), auto=True)
    ax.set_ylim(*check_bounds(y, ymin, ymax), auto=True)
    return image
Ejemplo n.º 8
0
def kde_contour_plot_2d(ax, data_x, data_y, *args, **kwargs):
    """Plot a 2d marginalised distribution as contours.

    This functions as a wrapper around matplotlib.axes.Axes.tricontour, and
    matplotlib.axes.Axes.tricontourf with a kernel density estimation
    computation provided by scipy.stats.gaussian_kde in between. All remaining
    keyword arguments are passed onwards to both functions.

    Parameters
    ----------
    ax: matplotlib.axes.Axes
        axis object to plot on.

    data_x, data_y: numpy.array
        x and y coordinates of uniformly weighted samples to generate kernel
        density estimator.

    weights: numpy.array, optional
        Sample weights.

    ncompress: int, optional
        Degree of compression.
        optional, Default 1000

    xmin, xmax, ymin, ymax: float
        lower/upper prior bounds in x/y coordinates.
        optional, default None

    Returns
    -------
    c: matplotlib.contour.QuadContourSet
        A set of contourlines or filled regions

    """
    xmin = kwargs.pop('xmin', None)
    xmax = kwargs.pop('xmax', None)
    ymin = kwargs.pop('ymin', None)
    ymax = kwargs.pop('ymax', None)
    weights = kwargs.pop('weights', None)
    ncompress = kwargs.pop('ncompress', 1000)
    label = kwargs.pop('label', None)
    zorder = kwargs.pop('zorder', 1)
    linewidths = kwargs.pop('linewidths', 0.5)
    color = kwargs.pop('color', next(ax._get_lines.prop_cycler)['color'])

    if len(data_x) == 0 or len(data_y) == 0:
        return numpy.zeros(0), numpy.zeros(0), numpy.zeros((0, 0))

    cov = numpy.cov(data_x, data_y, aweights=weights)
    tri, w = triangular_sample_compression_2d(data_x, data_y, cov, weights,
                                              ncompress)
    kde = gaussian_kde([tri.x, tri.y], weights=w)

    x, y = kde.resample(ncompress)
    x = numpy.concatenate([tri.x, x])
    y = numpy.concatenate([tri.y, y])
    w = numpy.concatenate([w, numpy.zeros(ncompress)])
    tri = scaled_triangulation(x, y, cov)

    p = kde([tri.x, tri.y])

    sigmax = numpy.sqrt(kde.covariance[0, 0])
    p = cut_and_normalise_gaussian(tri.x, p, sigmax, xmin, xmax)
    sigmay = numpy.sqrt(kde.covariance[1, 1])
    p = cut_and_normalise_gaussian(tri.y, p, sigmay, ymin, ymax)

    contours = iso_probability_contours_from_samples(p, weights=w)

    cmap = basic_cmap(color)

    cbar = ax.tricontourf(tri,
                          p,
                          contours,
                          cmap=cmap,
                          zorder=zorder,
                          vmin=0,
                          vmax=p.max(),
                          *args,
                          **kwargs)
    for c in cbar.collections:
        c.set_cmap(cmap)

    ax.tricontour(tri,
                  p,
                  contours,
                  zorder=zorder,
                  vmin=0,
                  vmax=p.max(),
                  linewidths=linewidths,
                  colors='k',
                  *args,
                  **kwargs)
    ax.patches += [
        plt.Rectangle((0, 0),
                      1,
                      1,
                      fc=cmap(0.999),
                      ec=cmap(0.32),
                      lw=2,
                      label=label)
    ]

    ax.set_xlim(*check_bounds(tri.x, xmin, xmax), auto=True)
    ax.set_ylim(*check_bounds(tri.y, ymin, ymax), auto=True)
    return cbar
Ejemplo n.º 9
0
def fastkde_contour_plot_2d(ax, data_x, data_y, *args, **kwargs):
    """Plot a 2d marginalised distribution as contours.

    This functions as a wrapper around matplotlib.axes.Axes.contour, and
    matplotlib.axes.Axes.contourf with a kernel density estimation computation
    in between. All remaining keyword arguments are passed onwards to both
    functions.

    Parameters
    ----------
    ax: matplotlib.axes.Axes
        axis object to plot on

    data_x, data_y: numpy.array
        x and y coordinates of uniformly weighted samples to generate kernel
        density estimator.

    levels: list
        amount of mass within each iso-probability contour.
        optional, default [0.68, 0.95]

    xmin, xmax, ymin, ymax: float
        lower/upper prior bounds in x/y coordinates
        optional, default None

    Returns
    -------
    c: matplotlib.contour.QuadContourSet
        A set of contourlines or filled regions

    """
    xmin = kwargs.pop('xmin', None)
    xmax = kwargs.pop('xmax', None)
    ymin = kwargs.pop('ymin', None)
    ymax = kwargs.pop('ymax', None)
    label = kwargs.pop('label', None)
    zorder = kwargs.pop('zorder', 1)
    linewidths = kwargs.pop('linewidths', 0.5)
    levels = kwargs.pop('levels', [0.68, 0.95])
    color = kwargs.pop('color', next(ax._get_lines.prop_cycler)['color'])

    if len(data_x) == 0 or len(data_y) == 0:
        return numpy.zeros(0), numpy.zeros(0), numpy.zeros((0, 0))

    try:
        x, y, pdf = fastkde_2d(data_x,
                               data_y,
                               xmin=xmin,
                               xmax=xmax,
                               ymin=ymin,
                               ymax=ymax)
    except NameError:
        raise ImportError("You need to install fastkde to use fastkde")

    levels = iso_probability_contours(pdf, contours=levels)
    cmap = basic_cmap(color)

    i = (pdf >= levels[0] * 0.5).any(axis=0)
    j = (pdf >= levels[0] * 0.5).any(axis=1)

    cbar = ax.contourf(x[i],
                       y[j],
                       pdf[numpy.ix_(j, i)],
                       levels,
                       cmap=cmap,
                       zorder=zorder,
                       vmin=0,
                       vmax=pdf.max(),
                       *args,
                       **kwargs)
    for c in cbar.collections:
        c.set_cmap(cmap)

    ax.contour(x[i],
               y[j],
               pdf[numpy.ix_(j, i)],
               levels,
               zorder=zorder,
               vmin=0,
               vmax=pdf.max(),
               linewidths=linewidths,
               colors='k',
               *args,
               **kwargs)
    ax.patches += [
        plt.Rectangle((0, 0),
                      1,
                      1,
                      fc=cmap(0.999),
                      ec=cmap(0.32),
                      lw=2,
                      label=label)
    ]

    ax.set_xlim(*check_bounds(x[i], xmin, xmax), auto=True)
    ax.set_ylim(*check_bounds(y[j], ymin, ymax), auto=True)
    return cbar
Ejemplo n.º 10
0
def hist_plot_1d(ax, data, *args, **kwargs):
    """Plot a 1d histogram.

    This functions is a wrapper around matplotlib.axes.Axes.hist. All remaining
    keyword arguments are passed onwards.

    Parameters
    ----------
    ax: matplotlib.axes.Axes
        axis object to plot on

    data: numpy.array
        Samples to generate histogram from

    weights: numpy.array, optional
        Sample weights.

    xmin, xmax: float
        lower/upper prior bound.
        optional, default data.min() and data.max()
        cannot be None (reverts to default in that case)

    Returns
    -------
    patches : list or list of lists
        Silent list of individual patches used to create the histogram
        or list of such list if multiple input datasets.

    Other Parameters
    ----------------
    **kwargs : `~matplotlib.axes.Axes.hist` properties

    """
    if data.max() - data.min() <= 0:
        return

    xmin = kwargs.pop('xmin', None)
    xmax = kwargs.pop('xmax', None)
    plotter = kwargs.pop('plotter', '')
    weights = kwargs.pop('weights', None)
    if xmin is None:
        xmin = quantile(data, 0.01, weights)
    if xmax is None:
        xmax = quantile(data, 0.99, weights)
    histtype = kwargs.pop('histtype', 'bar')

    if plotter == 'astropyhist':
        try:
            h, edges, bars = hist(data,
                                  ax=ax,
                                  range=(xmin, xmax),
                                  histtype=histtype,
                                  *args,
                                  **kwargs)
        except NameError:
            raise ImportError("You need to install astropy to use astropyhist")
    else:
        h, edges, bars = ax.hist(data,
                                 range=(xmin, xmax),
                                 histtype=histtype,
                                 weights=weights,
                                 *args,
                                 **kwargs)

    if histtype == 'bar':
        for b in bars:
            b.set_height(b.get_height() / h.max())
    elif histtype == 'step' or histtype == 'stepfilled':
        trans = Affine2D().scale(sx=1, sy=1. / h.max()) + ax.transData
        bars[0].set_transform(trans)

    ax.set_xlim(*check_bounds(edges, xmin, xmax), auto=True)
    ax.set_ylim(0, 1.1)
    return bars
Ejemplo n.º 11
0
def kde_contour_plot_2d(ax, data_x, data_y, *args, **kwargs):
    """Plot a 2d marginalised distribution as contours.

    This functions as a wrapper around matplotlib.axes.Axes.tricontour, and
    matplotlib.axes.Axes.tricontourf with a kernel density estimation
    computation provided by scipy.stats.gaussian_kde in between. All remaining
    keyword arguments are passed onwards to both functions.

    Parameters
    ----------
    ax: matplotlib.axes.Axes
        axis object to plot on.

    data_x, data_y: np.array
        x and y coordinates of uniformly weighted samples to generate kernel
        density estimator.

    weights: np.array, optional
        Sample weights.

    levels: list, optional
        amount of mass within each iso-probability contour.
        Has to be ordered from outermost to innermost contour.
        optional, default [0.95, 0.68]

    ncompress: int, optional
        Degree of compression.
        optional, Default 1000

    xmin, xmax, ymin, ymax: float
        lower/upper prior bounds in x/y coordinates.
        optional, default None

    Returns
    -------
    c: matplotlib.contour.QuadContourSet
        A set of contourlines or filled regions

    """
    kwargs = normalize_kwargs(kwargs, dict(linewidths=['linewidth', 'lw'],
                                           linestyles=['linestyle', 'ls'],
                                           color=['c'],
                                           facecolor=['fc'],
                                           edgecolor=['ec']))
    xmin = kwargs.pop('xmin', None)
    xmax = kwargs.pop('xmax', None)
    ymin = kwargs.pop('ymin', None)
    ymax = kwargs.pop('ymax', None)
    weights = kwargs.pop('weights', None)
    ncompress = kwargs.pop('ncompress', 1000)
    label = kwargs.pop('label', None)
    zorder = kwargs.pop('zorder', 1)
    levels = kwargs.pop('levels', [0.95, 0.68])
    color = kwargs.pop('color', next(ax._get_lines.prop_cycler)['color'])
    facecolor = kwargs.pop('facecolor', color)
    edgecolor = kwargs.pop('edgecolor', color)
    kwargs.pop('q', None)

    if len(data_x) == 0 or len(data_y) == 0:
        return np.zeros(0), np.zeros(0), np.zeros((0, 0))

    if weights is not None:
        data_x = data_x[weights != 0]
        data_y = data_y[weights != 0]
        weights = weights[weights != 0]

    cov = np.cov(data_x, data_y, aweights=weights)
    tri, w = triangular_sample_compression_2d(data_x, data_y, cov,
                                              weights, ncompress)
    kde = gaussian_kde([tri.x, tri.y], weights=w)

    x, y = kde.resample(ncompress)
    x = np.concatenate([tri.x, x])
    y = np.concatenate([tri.y, y])
    w = np.concatenate([w, np.zeros(ncompress)])
    tri = scaled_triangulation(x, y, cov)

    p = kde([tri.x, tri.y])

    sigmax = np.sqrt(kde.covariance[0, 0])
    p = cut_and_normalise_gaussian(tri.x, p, sigmax, xmin, xmax)
    sigmay = np.sqrt(kde.covariance[1, 1])
    p = cut_and_normalise_gaussian(tri.y, p, sigmay, ymin, ymax)

    levels = iso_probability_contours_from_samples(p, contours=levels,
                                                   weights=w)

    if facecolor not in [None, 'None', 'none']:
        linewidths = kwargs.pop('linewidths', 0.5)
        cmap = kwargs.pop('cmap', basic_cmap(facecolor))
        contf = ax.tricontourf(tri, p, levels=levels, cmap=cmap, zorder=zorder,
                               vmin=0, vmax=p.max(), *args, **kwargs)
        for c in contf.collections:
            c.set_cmap(cmap)
        ax.patches += [plt.Rectangle((0, 0), 0, 0, lw=2, label=label,
                                     fc=cmap(0.999), ec=cmap(0.32))]
        cmap = None
    else:
        linewidths = kwargs.pop('linewidths',
                                plt.rcParams.get('lines.linewidth'))
        cmap = kwargs.pop('cmap', None)
        contf = None
        ax.patches += [
            plt.Rectangle((0, 0), 0, 0, lw=2, label=label,
                          fc='None' if cmap is None else cmap(0.999),
                          ec=edgecolor if cmap is None else cmap(0.32))
        ]
        edgecolor = edgecolor if cmap is None else None

    vmin, vmax = match_contour_to_contourf(levels, vmin=0, vmax=p.max())
    cont = ax.tricontour(tri, p, levels=levels, zorder=zorder,
                         vmin=vmin, vmax=vmax, linewidths=linewidths,
                         colors=edgecolor, cmap=cmap, *args, **kwargs)

    ax.set_xlim(*check_bounds(tri.x, xmin, xmax), auto=True)
    ax.set_ylim(*check_bounds(tri.y, ymin, ymax), auto=True)
    return contf, cont
Ejemplo n.º 12
0
def kde_plot_1d(ax, data, *args, **kwargs):
    """Plot a 1d marginalised distribution.

    This functions as a wrapper around matplotlib.axes.Axes.plot, with a kernel
    density estimation computation provided by scipy.stats.gaussian_kde in
    between. All remaining keyword arguments are passed onwards.

    Parameters
    ----------
    ax: matplotlib.axes.Axes
        axis object to plot on.

    data: np.array
        Samples to generate kernel density estimator.

    weights: np.array, optional
        Sample weights.

    ncompress: int, optional
        Degree of compression. Default 1000

    xmin, xmax: float
        lower/upper prior bound.
        optional, default None

    levels: list
        values at which to draw iso-probability lines.
        optional, default [0.95, 0.68]

    facecolor: bool or string
        If set to True then the 1d plot will be shaded with the value of the
        ``color`` kwarg. Set to a string such as 'blue', 'k', 'r', 'C1' ect.
        to define the color of the shading directly.
        optional, default False

    Returns
    -------
    lines: matplotlib.lines.Line2D
        A list of line objects representing the plotted data (same as
        matplotlib matplotlib.axes.Axes.plot command)

    """
    if len(data) == 0:
        return np.zeros(0), np.zeros(0)

    if data.max()-data.min() <= 0:
        return

    kwargs = normalize_kwargs(
        kwargs,
        dict(linewidth=['lw'], linestyle=['ls'], color=['c'],
             facecolor=['fc'], edgecolor=['ec']))

    levels = kwargs.pop('levels', [0.95, 0.68])

    xmin = kwargs.pop('xmin', None)
    xmax = kwargs.pop('xmax', None)
    weights = kwargs.pop('weights', None)
    ncompress = kwargs.pop('ncompress', 1000)
    density = kwargs.pop('density', False)
    cmap = kwargs.pop('cmap', None)
    color = kwargs.pop('color', (next(ax._get_lines.prop_cycler)['color']
                                 if cmap is None else cmap(0.68)))
    facecolor = kwargs.pop('facecolor', False)

    if 'edgecolor' in kwargs:
        edgecolor = kwargs.pop('edgecolor')
        if edgecolor:
            color = edgecolor
    else:
        edgecolor = color

    q = kwargs.pop('q', '5sigma')
    q = quantile_plot_interval(q=q)

    if weights is not None:
        data = data[weights != 0]
        weights = weights[weights != 0]

    x, w = sample_compression_1d(data, weights, ncompress)
    kde = gaussian_kde(x, weights=w)
    p = kde(x)
    p /= p.max()
    i = ((x > quantile(x, q[0], w)) & (x < quantile(x, q[1], w)))
    if xmin is not None:
        i = i & (x > xmin)
    if xmax is not None:
        i = i & (x < xmax)
    sigma = np.sqrt(kde.covariance[0, 0])
    pp = cut_and_normalise_gaussian(x[i], p[i], sigma, xmin, xmax)
    pp /= pp.max()
    area = np.trapz(x=x[i], y=pp) if density else 1
    ans = ax.plot(x[i], pp/area, color=color, *args, **kwargs)
    ax.set_xlim(*check_bounds(x[i], xmin, xmax), auto=True)

    if facecolor and facecolor not in [None, 'None', 'none']:
        if facecolor is True:
            facecolor = color
        c = iso_probability_contours_from_samples(pp, contours=levels,
                                                  weights=w)
        cmap = basic_cmap(facecolor)
        fill = []
        for j in range(len(c)-1):
            fill.append(ax.fill_between(x[i], pp, where=pp >= c[j],
                        color=cmap(c[j]), edgecolor=edgecolor))

        return ans, fill

    return ans
Ejemplo n.º 13
0
def fastkde_contour_plot_2d(ax, data_x, data_y, *args, **kwargs):
    """Plot a 2d marginalised distribution as contours.

    This functions as a wrapper around matplotlib.axes.Axes.contour, and
    matplotlib.axes.Axes.contourf with a kernel density estimation computation
    in between. All remaining keyword arguments are passed onwards to both
    functions.

    Parameters
    ----------
    ax: matplotlib.axes.Axes
        axis object to plot on

    data_x, data_y: np.array
        x and y coordinates of uniformly weighted samples to generate kernel
        density estimator.

    levels: list
        amount of mass within each iso-probability contour.
        optional, default [0.68, 0.95]

    xmin, xmax, ymin, ymax: float
        lower/upper prior bounds in x/y coordinates
        optional, default None

    Returns
    -------
    c: matplotlib.contour.QuadContourSet
        A set of contourlines or filled regions

    """
    kwargs = normalize_kwargs(
        kwargs,
        dict(linewidths=['linewidth', 'lw'],
             linestyles=['linestyle', 'ls'],
             color=['c'],
             facecolor=['fc'],
             edgecolor=['ec']))
    xmin = kwargs.pop('xmin', None)
    xmax = kwargs.pop('xmax', None)
    ymin = kwargs.pop('ymin', None)
    ymax = kwargs.pop('ymax', None)
    label = kwargs.pop('label', None)
    zorder = kwargs.pop('zorder', 1)
    levels = kwargs.pop('levels', [0.68, 0.95])
    color = kwargs.pop('color', next(ax._get_lines.prop_cycler)['color'])
    facecolor = kwargs.pop('facecolor', color)
    edgecolor = kwargs.pop(
        'edgecolor', color if facecolor in [None, 'None', 'none'] else 'k')
    kwargs.pop('q', None)

    if len(data_x) == 0 or len(data_y) == 0:
        return np.zeros(0), np.zeros(0), np.zeros((0, 0))

    try:
        x, y, pdf = fastkde_2d(data_x,
                               data_y,
                               xmin=xmin,
                               xmax=xmax,
                               ymin=ymin,
                               ymax=ymax)
    except NameError:
        raise ImportError("You need to install fastkde to use fastkde")

    levels = iso_probability_contours(pdf, contours=levels)

    i = (pdf >= levels[0] * 0.5).any(axis=0)
    j = (pdf >= levels[0] * 0.5).any(axis=1)

    if facecolor not in [None, 'None', 'none']:
        linewidths = kwargs.pop('linewidths', 0.5)
        cmap = kwargs.pop('cmap', basic_cmap(facecolor))
        contf = ax.contourf(x[i],
                            y[j],
                            pdf[np.ix_(j, i)],
                            levels,
                            cmap=cmap,
                            zorder=zorder,
                            vmin=0,
                            vmax=pdf.max(),
                            *args,
                            **kwargs)
        for c in contf.collections:
            c.set_cmap(cmap)
        ax.patches += [
            plt.Rectangle((0, 0),
                          0,
                          0,
                          lw=2,
                          label=label,
                          fc=cmap(0.999),
                          ec=cmap(0.32))
        ]
        cmap = None
    else:
        linewidths = kwargs.pop('linewidths',
                                plt.rcParams.get('lines.linewidth'))
        cmap = kwargs.pop('cmap', None)
        contf = None
        ax.patches += [
            plt.Rectangle((0, 0),
                          0,
                          0,
                          lw=2,
                          label=label,
                          fc='None' if cmap is None else cmap(0.999),
                          ec=edgecolor if cmap is None else cmap(0.32))
        ]
        edgecolor = edgecolor if cmap is None else None

    vmin, vmax = match_contour_to_contourf(levels, vmin=0, vmax=pdf.max())
    cont = ax.contour(x[i],
                      y[j],
                      pdf[np.ix_(j, i)],
                      levels,
                      zorder=zorder,
                      vmin=vmin,
                      vmax=vmax,
                      linewidths=linewidths,
                      colors=edgecolor,
                      cmap=cmap,
                      *args,
                      **kwargs)

    ax.set_xlim(*check_bounds(x[i], xmin, xmax), auto=True)
    ax.set_ylim(*check_bounds(y[j], ymin, ymax), auto=True)
    return contf, cont
Ejemplo n.º 14
0
def kde_plot_1d(ax, data, *args, **kwargs):
    """Plot a 1d marginalised distribution.

    This functions as a wrapper around matplotlib.axes.Axes.plot, with a kernel
    density estimation computation provided by scipy.stats.gaussian_kde in
    between. All remaining keyword arguments are passed onwards.

    Parameters
    ----------
    ax: matplotlib.axes.Axes
        axis object to plot on.

    data: np.array
        Samples to generate kernel density estimator.

    weights: np.array, optional
        Sample weights.

    ncompress: int, optional
        Degree of compression. Default 1000

    xmin, xmax: float
        lower/upper prior bound.
        optional, default None

    Returns
    -------
    lines: matplotlib.lines.Line2D
        A list of line objects representing the plotted data (same as
        matplotlib matplotlib.axes.Axes.plot command)

    """
    if len(data) == 0:
        return np.zeros(0), np.zeros(0)

    if data.max() - data.min() <= 0:
        return

    kwargs = normalize_kwargs(kwargs,
                              dict(linewidth=['lw'],
                                   linestyle=['ls'],
                                   color=['c']),
                              drop=['fc', 'ec'])
    xmin = kwargs.pop('xmin', None)
    xmax = kwargs.pop('xmax', None)
    weights = kwargs.pop('weights', None)
    ncompress = kwargs.pop('ncompress', 1000)
    cmap = kwargs.pop('cmap', None)
    color = kwargs.pop('color', (next(ax._get_lines.prop_cycler)['color']
                                 if cmap is None else cmap(0.68)))
    q = kwargs.pop('q', '5sigma')
    q = quantile_plot_interval(q=q)

    if weights is not None:
        data = data[weights != 0]
        weights = weights[weights != 0]

    x, w = sample_compression_1d(data, weights, ncompress)
    kde = gaussian_kde(x, weights=w)
    p = kde(x)
    p /= p.max()
    i = ((x > quantile(x, q[0], w)) & (x < quantile(x, q[1], w)))
    if xmin is not None:
        i = i & (x > xmin)
    if xmax is not None:
        i = i & (x < xmax)
    sigma = np.sqrt(kde.covariance[0, 0])
    pp = cut_and_normalise_gaussian(x[i], p[i], sigma, xmin, xmax)
    pp /= pp.max()
    ans = ax.plot(x[i], pp, color=color, *args, **kwargs)
    ax.set_xlim(*check_bounds(x[i], xmin, xmax), auto=True)
    return ans