Skip to content

Commit a166af2

Browse files
authored
Fix inner box with unpaired split violins (#2814)
* Fix inner box with unpaired split violins Fixes #2742 * Fix tests and update release notes
1 parent 995ea1c commit a166af2

File tree

3 files changed

+18
-11
lines changed

3 files changed

+18
-11
lines changed

doc/releases/v0.12.0.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,13 @@ Other updates
5757

5858
- |Fix| Fixed two edgecases in :func:`histplot` when only `binwidth` was provided (:pr:`2813').
5959

60-
- |Fix| FacetGrid subplot titles will no longer be reset when calling :meth:`FacetGrid.map` or :meth:`FacetGrid.map_dataframe` after :meth:`FacetGrid.set_titles` (:pr:`2705`).
60+
- |Fix| Fixed a bug in :func:`violinplot` where inner boxes/points could be missing with unpaired split violins (:pr:`2814`).
61+
62+
- |Fix| Subplot titles will no longer be reset when calling :meth:`FacetGrid.map` or :meth:`FacetGrid.map_dataframe` (:pr:`2705`).
6163

6264
- |Fix| In :func:`lineplot`, allowed the `dashes` keyword to set the style of a line without mapping a `style` variable (:pr:`2449`).
6365

66+
6467
- |Dependencies| Made `scipy` an optional dependency and added `pip install seaborn[all]` as a method for ensuring the availability of compatible `scipy` and `statsmodels` libraries at install time. This has a few minor implications for existing code, which are explained in the Github pull request (:pr:`2398`).
6568

6669
- |Dependencies| Following `NEP29 <https://numpy.org/neps/nep-0029-deprecation_policy.html>`_, dropped support for Python 3.6 and bumped the minimally-supported versions of the library dependencies.

seaborn/categorical.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,7 +1136,7 @@ def draw_violins(self, ax):
11361136

11371137
# Draw box and whisker information
11381138
if self.inner.startswith("box"):
1139-
self.draw_box_lines(ax, violin_data, support, density, i)
1139+
self.draw_box_lines(ax, violin_data, i)
11401140

11411141
# Draw quartile lines
11421142
elif self.inner.startswith("quart"):
@@ -1217,16 +1217,15 @@ def draw_violins(self, ax):
12171217

12181218
# The box and point interior plots are drawn for
12191219
# all data at the group level, so we just do that once
1220-
if not j:
1220+
if j and any(self.plot_hues[0] == hue_level):
12211221
continue
12221222

12231223
# Get the whole vector for this group level
12241224
violin_data = remove_na(group_data)
12251225

12261226
# Draw box and whisker information
12271227
if self.inner.startswith("box"):
1228-
self.draw_box_lines(ax, violin_data,
1229-
support, density, i)
1228+
self.draw_box_lines(ax, violin_data, i)
12301229

12311230
# Draw point observations
12321231
elif self.inner.startswith("point"):
@@ -1252,9 +1251,7 @@ def draw_violins(self, ax):
12521251

12531252
# Draw box and whisker information
12541253
if self.inner.startswith("box"):
1255-
self.draw_box_lines(ax, violin_data,
1256-
support, density,
1257-
i + offsets[j])
1254+
self.draw_box_lines(ax, violin_data, i + offsets[j])
12581255

12591256
# Draw quartile lines
12601257
elif self.inner.startswith("quart"):
@@ -1286,7 +1283,7 @@ def draw_single_observation(self, ax, at_group, at_quant, density):
12861283
color=self.gray,
12871284
linewidth=self.linewidth)
12881285

1289-
def draw_box_lines(self, ax, data, support, density, center):
1286+
def draw_box_lines(self, ax, data, center):
12901287
"""Draw boxplot information at center of the density."""
12911288
# Compute the boxplot statistics
12921289
q25, q50, q75 = np.percentile(data, [25, 50, 75])

seaborn/tests/test_categorical.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,7 +1324,7 @@ def test_draw_box_lines(self):
13241324
p = cat._ViolinPlotter(**kws)
13251325

13261326
_, ax = plt.subplots()
1327-
p.draw_box_lines(ax, self.y, p.support[0], p.density[0], 0)
1327+
p.draw_box_lines(ax, self.y, 0)
13281328
assert len(ax.lines) == 2
13291329

13301330
q25, q50, q75 = np.percentile(self.y, [25, 50, 75])
@@ -1342,7 +1342,7 @@ def test_draw_box_lines(self):
13421342
p = cat._ViolinPlotter(**kws)
13431343

13441344
_, ax = plt.subplots()
1345-
p.draw_box_lines(ax, self.y, p.support[0], p.density[0], 0)
1345+
p.draw_box_lines(ax, self.y, 0)
13461346
assert len(ax.lines) == 2
13471347

13481348
q25, q50, q75 = np.percentile(self.y, [25, 50, 75])
@@ -1592,6 +1592,13 @@ def test_violinplots(self):
15921592
inner=inner, split=True)
15931593
plt.close("all")
15941594

1595+
def test_split_one_each(self, rng):
1596+
1597+
x = np.repeat([0, 1], 5)
1598+
y = rng.normal(0, 1, 10)
1599+
ax = cat.violinplot(x=x, y=y, hue=x, split=True, inner="box")
1600+
assert len(ax.lines) == 4
1601+
15951602

15961603
# ====================================================================================
15971604
# ====================================================================================

0 commit comments

Comments
 (0)