Skip to content

Commit

Permalink
fix: fixed clipping of kde for censored values in violinplot (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
jlerat authored Mar 6, 2025
1 parent 46fb0f5 commit 2172e12
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
12 changes: 12 additions & 0 deletions src/hydrodiy/plot/tests/test_hyplot_violinplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,18 @@ def test_violin_missing():
fig.savefig(fp)


def test_violin_censored():
plt.close("all")
df = DATA1.copy()
df.data2 = df.data2.clip(-np.inf, df.data2.quantile(0.3))
df.data3 = df.data3.clip(df.data3.quantile(0.3))
vl = Violin(data=df)
fig, ax = plt.subplots()
vl.draw(ax=ax)
fp = FIMG / "violin_censored.png"
fig.savefig(fp)


def test_violin_allnan():
plt.close("all")
df = DATA1.copy()
Expand Down
22 changes: 20 additions & 2 deletions src/hydrodiy/plot/violinplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,28 @@ def _compute(self):
continue

sen = se[notnull]
kernel = gaussian_kde(sen.values)
values = sen.values
x0, x1 = sen.min(), sen.max()

# reduce impact of censored data
ilow = np.abs(values-x0) < 1e-10
if ilow.sum() > 1:
idx = np.where(ilow)[0][1:]
ilow[idx] = False

ihigh = np.abs(values-x1) < 1e-10
if ihigh.sum() > 1:
idx = np.where(ihigh)[0][1:]
ihigh[idx] = False

irest = ~ilow & ~ihigh

selected = irest | ilow | ihigh

# Run kde estimate
kernel = gaussian_kde(values[selected])

# blend regular spacing and ecdf spacing
x0, x1 = sen.min(), sen.max()
x = np.linspace(x0, x1, (npts-len(sen)))
err = 1e-6*np.random.uniform(-1, 1, len(sen))
x = np.sort(np.concatenate([x, sen.values+err]))
Expand Down

0 comments on commit 2172e12

Please sign in to comment.