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
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
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
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
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
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
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
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
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
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
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
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
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
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