def test_percentile(): np.random.seed(47) x0 = np.random.normal(loc=100, scale=10, size=1000) y0 = np.random.normal(loc=.1, scale=.01, size=1000) ds = dclab.new_dataset({"area_um": x0, "deform": y0}) ds.config["filtering"]["enable filters"] = False x, y, kde = ds.get_kde_contour(xax="area_um", yax="deform", xacc=.10, yacc=.01, kde_type="histogram") level = kde_contours.get_quantile_levels(density=kde, x=x, y=y, xp=ds["area_um"], yp=ds["deform"], q=.89, normalize=True) level2, err = kde_contours._find_quantile_level(density=kde, x=x, y=y, xp=ds["area_um"], yp=ds["deform"], quantile=.89, acc=0, ret_err=True) # since _find_quantile level does not do linear interpolation # in the density, the computed values can differ from the values # obtained using get_quantile_levels - even with err==0. assert err == 0 # This is the resulting level difference. assert np.abs(level - level2) < 0.00116 if __name__ == "__main__": c1 = kde_contours.find_contours_level(density=kde, x=x, y=y, level=level, closed=True)[0] c2 = kde_contours.find_contours_level(density=kde, x=x, y=y, level=level2, closed=True)[0] import matplotlib.pylab as plt plt.plot(ds["area_um"], ds["deform"], "x") # The contours are right on top of each other plt.plot(c1[:, 0], c2[:, 1]) plt.plot(c1[:, 0], c2[:, 1], ls="--") plt.show()
def test_contour_basic(): np.random.seed(47) x0 = np.random.normal(loc=100, scale=10, size=100) y0 = np.random.normal(loc=.1, scale=.01, size=100) ds = dclab.new_dataset({"area_um": x0, "deform": y0}) ds.config["filtering"]["enable filters"] = False x, y, kde = ds.get_kde_contour(xax="area_um", yax="deform", xacc=.10, yacc=.01, kde_type="histogram") level = kde_contours.get_quantile_levels(density=kde, x=x, y=y, xp=ds["area_um"], yp=ds["deform"], q=.89, normalize=True) contours = kde_contours.find_contours_level(density=kde, x=x, y=y, level=level, closed=True) if __name__ == "__main__": import matplotlib.pylab as plt plt.plot(ds["area_um"], ds["deform"], "x") # There should be 11 points (q=.89) in the contour for cc in contours: plt.plot(cc[:, 0], cc[:, 1]) plt.show() nump = 0 for p in zip(x0, y0): nump += polygon_filter.PolygonFilter.point_in_poly(p, poly=contours[0]) assert nump == 11, "there should be (1-q)*100 points in the contour" # added in dclab 0.24.1 nump2 = skimage.measure.points_in_poly( np.concatenate((x0.reshape(-1, 1), y0.reshape(-1, 1)), axis=1), contours[0]) assert nump2.sum() == 11
def test_contour_basic(): np.random.seed(47) x0 = np.random.normal(loc=100, scale=10, size=100) y0 = np.random.normal(loc=.1, scale=.01, size=100) ds = dclab.new_dataset({"area_um": x0, "deform": y0}) ds.config["filtering"]["enable filters"] = False x, y, kde = ds.get_kde_contour(xax="area_um", yax="deform", xacc=.10, yacc=.01, kde_type="histogram") level = kde_contours.get_quantile_levels(density=kde, x=x, y=y, xp=ds["area_um"], yp=ds["deform"], q=.89, normalize=True) contours = kde_contours.find_contours_level(density=kde, x=x, y=y, level=level, closed=True) if __name__ == "__main__": import matplotlib.pylab as plt plt.plot(ds["area_um"], ds["deform"], "x") # There should be 11 points (q=.89) in the contour for cc in contours: plt.plot(cc[:, 0], cc[:, 1]) plt.show() nump = 0 for p in zip(x0, y0): nump += polygon_filter.PolygonFilter.point_in_poly(p, poly=contours[0]) assert nump == 11, "there should be (1-q)*100 points in the contour"
def compute_contours(plot_state, rtdc_ds): gen = plot_state["general"] con = plot_state["contour"] try: x, y, density = plot_cache.get_contour_data( rtdc_ds=rtdc_ds, xax=gen["axis x"], yax=gen["axis y"], xacc=con["spacing x"], yacc=con["spacing y"], xscale=gen["scale x"], yscale=gen["scale y"], kde_type=gen["kde"], ) except ValueError: # most-likely there is nothing to compute a contour for return [] if density.shape[0] < 3 or density.shape[1] < 3: warnings.warn("Contour not possible; spacing may be too large!", ContourSpacingTooLarge) return [] plev = kde_contours.get_quantile_levels( density=density, x=x, y=y, xp=rtdc_ds[gen["axis x"]][rtdc_ds.filter.all], yp=rtdc_ds[gen["axis y"]][rtdc_ds.filter.all], q=np.array(con["percentiles"]) / 100, normalize=True) contours = [] for level in plev: # make sure that the contour levels are not at the boundaries if not (np.allclose(level, 0, atol=1e-12, rtol=0) or np.allclose(level, 1, atol=1e-12, rtol=0)): cc = kde_contours.find_contours_level( density, x=x, y=y, level=level) contours.append(cc) return contours
def add_contour(plot_item, plot_state, rtdc_ds, slot_state, legend=None): gen = plot_state["general"] con = plot_state["contour"] try: x, y, density = plot_cache.get_contour_data( rtdc_ds=rtdc_ds, xax=gen["axis x"], yax=gen["axis y"], xacc=con["spacing x"], yacc=con["spacing y"], xscale=gen["scale x"], yscale=gen["scale y"], kde_type=gen["kde"], ) except ValueError: # most-likely there is nothing to compute a contour for return [] if density.shape[0] < 3 or density.shape[1] < 3: warnings.warn("Contour not possible; spacing may be too large!", ContourSpacingTooLarge) return [] plev = kde_contours.get_quantile_levels( density=density, x=x, y=y, xp=rtdc_ds[gen["axis x"]][rtdc_ds.filter.all], yp=rtdc_ds[gen["axis y"]][rtdc_ds.filter.all], q=np.array(con["percentiles"]) / 100, normalize=True) contours = [] for level in plev: # make sure that the contour levels are not at the boundaries if not (np.allclose(level, 0, atol=1e-12, rtol=0) or np.allclose(level, 1, atol=1e-12, rtol=0)): cc = kde_contours.find_contours_level(density, x=x, y=y, level=level) contours.append(cc) elements = [] for ii in range(len(contours)): style = linestyles[con["line styles"][ii]] width = con["line widths"][ii] for cci in contours[ii]: cline = pg.PlotDataItem( x=cci[:, 0], y=cci[:, 1], pen=pg.mkPen( color=slot_state["color"], width=width, style=style, ), ) elements.append(cline) plot_item.addItem(cline) if ii == 0 and legend is not None: legend.addItem(cline, slot_state["name"]) # Always plot higher percentiles above lower percentiles # (useful if there are multiple contour plots overlapping) cline.setZValue(con["percentiles"][ii]) return elements