diff --git a/src/hydrodiy/plot/putils.py b/src/hydrodiy/plot/putils.py index 67c7cdd..a58ad68 100644 --- a/src/hydrodiy/plot/putils.py +++ b/src/hydrodiy/plot/putils.py @@ -401,6 +401,9 @@ def kde(xy, ngrid=50, eps=1e-10): if xy.shape[1] != 2: xy = xy.T + iok = np.all(np.isfinite(xy), axis=1) + xy = xy[iok] + x = np.linspace(xy[:, 0].min(), xy[:, 0].max(), ngrid) y = np.linspace(xy[:, 1].min(), xy[:, 1].max(), ngrid) xx, yy = np.meshgrid(x, y) @@ -535,10 +538,13 @@ def ecdfplot(ax, df, label_stat=None, label_stat_format="4.2f", lines : dict Dictionnary containing the line object for each column in df. """ - lines = {} + data = {} for name, se in df.items(): - values = se.sort_values().values - values = values[~np.isnan(values)] + values = se.sort_values() + idx = values.index + isok = values.notnull() + idx = idx[isok] + values = values[isok].values pp = sutils.ppos(len(values), cst=cst) @@ -549,7 +555,12 @@ def ecdfplot(ax, df, label_stat=None, label_stat_format="4.2f", format=label_stat_format) ax.plot(values, pp, label=label, *args, **kwargs) - lines[name] = ax.get_lines()[-1] + data[name] = { + "line": ax.get_lines()[-1], + "index": idx, + "values": values, + "position": pp + } # Decorate ax.set_ylabel("Empirical CDF [-]") @@ -561,7 +572,7 @@ def ecdfplot(ax, df, label_stat=None, label_stat_format="4.2f", ylabs[0].set_va("bottom") ylabs[2].set_va("top") - return lines + return data def scattercat(ax, x, y, z, ncats=5, cuts=None, cmap="PiYG", diff --git a/src/hydrodiy/plot/tests/test_hyplot_putils.py b/src/hydrodiy/plot/tests/test_hyplot_putils.py index a310741..0dde42a 100644 --- a/src/hydrodiy/plot/tests/test_hyplot_putils.py +++ b/src/hydrodiy/plot/tests/test_hyplot_putils.py @@ -193,6 +193,31 @@ def test_kde(): fig.savefig(fp) +def test_kde_missing(): + xy = np.random.multivariate_normal( \ + [1, 2], [[1, 0.9], [0.9, 1]], \ + size=1000) + + miss = np.random.choice(np.arange(len(xy) * 2), 20, + replace=False) + xy.flat[miss] = np.nan + + inf = np.random.choice(np.arange(len(xy) * 2), 20, + replace=False) + xy.flat[inf] = np.inf + + xx, yy, zz = putils.kde(xy) + + plt.close("all") + fig, ax = plt.subplots() + cont = ax.contourf(xx, yy, zz, cmap="Blues") + ax.contour(cont, colors="grey") + ax.plot(xy[:, 0], xy[:, 1], ".", alpha=0.2, mfc="grey", mec="none") + fp = FIMG / "kde_missing.png" + fig.savefig(fp) + + + def test_kde_ties(): """ Test kde generation with ties """ xy = np.random.multivariate_normal( \ @@ -271,8 +296,8 @@ def test_ecdfplot(): fig, ax = plt.subplots() lines = putils.ecdfplot(ax, df) - for nm in lines: - lines[nm].set_linestyle(":") + for vn, obj in lines.items(): + obj["line"].set_linestyle(":") ax.legend(loc=2) fp = FIMG / "ecdf_plot.png"