Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 013757e

Browse files
committed
resolve conflicts
2 parents 9c033d2 + a60e49c commit 013757e

File tree

7 files changed

+93
-24
lines changed

7 files changed

+93
-24
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Add option to plot only one half of violin plot
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
Setting the parameter *side* to 'low' or 'high' allows to only plot one half of the violin plot.

galleries/examples/statistics/violinplot.py

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,55 +28,73 @@
2828
pos = [1, 2, 4, 5, 7, 8]
2929
data = [np.random.normal(0, std, size=100) for std in pos]
3030

31-
fig, axs = plt.subplots(nrows=2, ncols=5, figsize=(10, 6))
31+
fig, axs = plt.subplots(nrows=2, ncols=6, figsize=(10, 4))
3232

3333
axs[0, 0].violinplot(data, pos, points=20, widths=0.3,
3434
showmeans=True, showextrema=True, showmedians=True)
35-
axs[0, 0].set_title('Custom violinplot 1', fontsize=fs)
35+
axs[0, 0].set_title('Custom violin 1', fontsize=fs)
3636

3737
axs[0, 1].violinplot(data, pos, points=40, widths=0.5,
3838
showmeans=True, showextrema=True, showmedians=True,
3939
bw_method='silverman')
40-
axs[0, 1].set_title('Custom violinplot 2', fontsize=fs)
40+
axs[0, 1].set_title('Custom violin 2', fontsize=fs)
4141

4242
axs[0, 2].violinplot(data, pos, points=60, widths=0.7, showmeans=True,
4343
showextrema=True, showmedians=True, bw_method=0.5)
44-
axs[0, 2].set_title('Custom violinplot 3', fontsize=fs)
44+
axs[0, 2].set_title('Custom violin 3', fontsize=fs)
4545

4646
axs[0, 3].violinplot(data, pos, points=60, widths=0.7, showmeans=True,
4747
showextrema=True, showmedians=True, bw_method=0.5,
4848
quantiles=[[0.1], [], [], [0.175, 0.954], [0.75], [0.25]])
49-
axs[0, 3].set_title('Custom violinplot 4', fontsize=fs)
49+
axs[0, 3].set_title('Custom violin 4', fontsize=fs)
5050

5151
axs[0, 4].violinplot(data[-1:], pos[-1:], points=60, widths=0.7,
5252
showmeans=True, showextrema=True, showmedians=True,
5353
quantiles=[0.05, 0.1, 0.8, 0.9], bw_method=0.5)
54-
axs[0, 4].set_title('Custom violinplot 5', fontsize=fs)
54+
axs[0, 4].set_title('Custom violin 5', fontsize=fs)
55+
56+
axs[0, 5].violinplot(data[-1:], pos[-1:], points=60, widths=0.7,
57+
showmeans=True, showextrema=True, showmedians=True,
58+
quantiles=[0.05, 0.1, 0.8, 0.9], bw_method=0.5, side='low')
59+
60+
axs[0, 5].violinplot(data[-1:], pos[-1:], points=60, widths=0.7,
61+
showmeans=True, showextrema=True, showmedians=True,
62+
quantiles=[0.05, 0.1, 0.8, 0.9], bw_method=0.5, side='high')
63+
axs[0, 5].set_title('Custom violin 6', fontsize=fs)
5564

5665
axs[1, 0].violinplot(data, pos, points=80, vert=False, widths=0.7,
5766
showmeans=True, showextrema=True, showmedians=True)
58-
axs[1, 0].set_title('Custom violinplot 6', fontsize=fs)
67+
axs[1, 0].set_title('Custom violin 7', fontsize=fs)
5968

6069
axs[1, 1].violinplot(data, pos, points=100, vert=False, widths=0.9,
6170
showmeans=True, showextrema=True, showmedians=True,
6271
bw_method='silverman')
63-
axs[1, 1].set_title('Custom violinplot 7', fontsize=fs)
72+
axs[1, 1].set_title('Custom violin 8', fontsize=fs)
6473

6574
axs[1, 2].violinplot(data, pos, points=200, vert=False, widths=1.1,
6675
showmeans=True, showextrema=True, showmedians=True,
6776
bw_method=0.5)
68-
axs[1, 2].set_title('Custom violinplot 8', fontsize=fs)
77+
axs[1, 2].set_title('Custom violin 9', fontsize=fs)
6978

7079
axs[1, 3].violinplot(data, pos, points=200, vert=False, widths=1.1,
7180
showmeans=True, showextrema=True, showmedians=True,
7281
quantiles=[[0.1], [], [], [0.175, 0.954], [0.75], [0.25]],
7382
bw_method=0.5)
74-
axs[1, 3].set_title('Custom violinplot 9', fontsize=fs)
83+
axs[1, 3].set_title('Custom violin 10', fontsize=fs)
7584

7685
axs[1, 4].violinplot(data[-1:], pos[-1:], points=200, vert=False, widths=1.1,
7786
showmeans=True, showextrema=True, showmedians=True,
7887
quantiles=[0.05, 0.1, 0.8, 0.9], bw_method=0.5)
79-
axs[1, 4].set_title('Custom violinplot 10', fontsize=fs)
88+
axs[1, 4].set_title('Custom violin 11', fontsize=fs)
89+
90+
axs[1, 5].violinplot(data[-1:], pos[-1:], points=200, vert=False, widths=1.1,
91+
showmeans=True, showextrema=True, showmedians=True,
92+
quantiles=[0.05, 0.1, 0.8, 0.9], bw_method=0.5, side='low')
93+
94+
axs[1, 5].violinplot(data[-1:], pos[-1:], points=200, vert=False, widths=1.1,
95+
showmeans=True, showextrema=True, showmedians=True,
96+
quantiles=[0.05, 0.1, 0.8, 0.9], bw_method=0.5, side='high')
97+
axs[1, 5].set_title('Custom violin 12', fontsize=fs)
8098

8199

82100
for ax in axs.flat:

lib/matplotlib/axes/_axes.py

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8244,7 +8244,7 @@ def matshow(self, Z, **kwargs):
82448244
@_preprocess_data(replace_names=["dataset"])
82458245
def violinplot(self, dataset, positions=None, vert=True, widths=0.5,
82468246
showmeans=False, showextrema=True, showmedians=False,
8247-
quantiles=None, points=100, bw_method=None):
8247+
quantiles=None, points=100, bw_method=None, side='both'):
82488248
"""
82498249
Make a violin plot.
82508250
@@ -8295,6 +8295,10 @@ def violinplot(self, dataset, positions=None, vert=True, widths=0.5,
82958295
callable, it should take a `matplotlib.mlab.GaussianKDE` instance as
82968296
its only parameter and return a float.
82978297
8298+
side : {'both', 'low', 'high'}, default: 'both'
8299+
'both' plots standard violins. 'low'/'high' only
8300+
plots the side below/above the positions value.
8301+
82988302
data : indexable object, optional
82998303
DATA_PARAMETER_PLACEHOLDER
83008304
@@ -8346,10 +8350,10 @@ def _kde_method(X, coords):
83468350
quantiles=quantiles)
83478351
return self.violin(vpstats, positions=positions, vert=vert,
83488352
widths=widths, showmeans=showmeans,
8349-
showextrema=showextrema, showmedians=showmedians)
8353+
showextrema=showextrema, showmedians=showmedians, side=side)
83508354

83518355
def violin(self, vpstats, positions=None, vert=True, widths=0.5,
8352-
showmeans=False, showextrema=True, showmedians=False):
8356+
showmeans=False, showextrema=True, showmedians=False, side='both'):
83538357
"""
83548358
Draw a violin plot from pre-computed statistics.
83558359
@@ -8405,6 +8409,10 @@ def violin(self, vpstats, positions=None, vert=True, widths=0.5,
84058409
showmedians : bool, default: False
84068410
Whether to show the median with a line.
84078411
8412+
side : {'both', 'low', 'high'}, default: 'both'
8413+
'both' plots standard violins. 'low'/'high' only
8414+
plots the side below/above the positions value.
8415+
84088416
Returns
84098417
-------
84108418
dict
@@ -8467,8 +8475,13 @@ def violin(self, vpstats, positions=None, vert=True, widths=0.5,
84678475
elif len(widths) != N:
84688476
raise ValueError(datashape_message.format("widths"))
84698477

8478+
# Validate side
8479+
_api.check_in_list(["both", "low", "high"], side=side)
8480+
84708481
# Calculate ranges for statistics lines (shape (2, N)).
8471-
line_ends = [[-0.25], [0.25]] * np.array(widths) + positions
8482+
line_ends = [[-0.25 if side in ['both', 'low'] else 0],
8483+
[0.25 if side in ['both', 'high'] else 0]] \
8484+
* np.array(widths) + positions
84728485

84738486
# Colors.
84748487
if mpl.rcParams['_internal.classic_mode']:
@@ -8480,20 +8493,34 @@ def violin(self, vpstats, positions=None, vert=True, widths=0.5,
84808493
# Check whether we are rendering vertically or horizontally
84818494
if vert:
84828495
fill = self.fill_betweenx
8483-
perp_lines = functools.partial(self.hlines, colors=linecolor)
8484-
par_lines = functools.partial(self.vlines, colors=linecolor)
8496+
if side in ['low', 'high']:
8497+
perp_lines = functools.partial(self.hlines, colors=linecolor,
8498+
capstyle='projecting')
8499+
par_lines = functools.partial(self.vlines, colors=linecolor,
8500+
capstyle='projecting')
8501+
else:
8502+
perp_lines = functools.partial(self.hlines, colors=linecolor)
8503+
par_lines = functools.partial(self.vlines, colors=linecolor)
84858504
else:
84868505
fill = self.fill_between
8487-
perp_lines = functools.partial(self.vlines, colors=linecolor)
8488-
par_lines = functools.partial(self.hlines, colors=linecolor)
8506+
if side in ['low', 'high']:
8507+
perp_lines = functools.partial(self.vlines, colors=linecolor,
8508+
capstyle='projecting')
8509+
par_lines = functools.partial(self.hlines, colors=linecolor,
8510+
capstyle='projecting')
8511+
else:
8512+
perp_lines = functools.partial(self.vlines, colors=linecolor)
8513+
par_lines = functools.partial(self.hlines, colors=linecolor)
84898514

84908515
# Render violins
84918516
bodies = []
84928517
for stats, pos, width in zip(vpstats, positions, widths):
84938518
# The 0.5 factor reflects the fact that we plot from v-p to v+p.
84948519
vals = np.array(stats['vals'])
84958520
vals = 0.5 * width * vals / vals.max()
8496-
bodies += [fill(stats['coords'], -vals + pos, vals + pos,
8521+
bodies += [fill(stats['coords'],
8522+
-vals + pos if side in ['both', 'low'] else pos,
8523+
vals + pos if side in ['both', 'high'] else pos,
84978524
facecolor=fillcolor, alpha=0.3)]
84988525
means.append(stats['mean'])
84998526
mins.append(stats['min'])

lib/matplotlib/axes/_axes.pyi

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ class Axes(_AxesBase):
370370
autorange: bool = ...,
371371
zorder: float | None = ...,
372372
capwidths: float | ArrayLike | None = ...,
373-
label: Sequence[str] | None = ...,
373+
label: Sequence[str] | None = ...,
374374
*,
375375
data=...,
376376
) -> dict[str, Any]: ...
@@ -745,6 +745,7 @@ class Axes(_AxesBase):
745745
| float
746746
| Callable[[GaussianKDE], float]
747747
| None = ...,
748+
side: Literal["both", "low", "high"] = ...,
748749
*,
749750
data=...,
750751
) -> dict[str, Collection]: ...
@@ -757,6 +758,7 @@ class Axes(_AxesBase):
757758
showmeans: bool = ...,
758759
showextrema: bool = ...,
759760
showmedians: bool = ...,
761+
side: Literal["both", "low", "high"] = ...,
760762
) -> dict[str, Collection]: ...
761763

762764
table = mtable.table

lib/matplotlib/pyplot.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4078,9 +4078,11 @@ def violinplot(
40784078
showmedians: bool = False,
40794079
quantiles: Sequence[float | Sequence[float]] | None = None,
40804080
points: int = 100,
4081-
bw_method: (
4082-
Literal["scott", "silverman"] | float | Callable[[GaussianKDE], float] | None
4083-
) = None,
4081+
bw_method: Literal["scott", "silverman"]
4082+
| float
4083+
| Callable[[GaussianKDE], float]
4084+
| None = None,
4085+
side: Literal["both", "low", "high"] = "both",
40844086
*,
40854087
data=None,
40864088
) -> dict[str, Collection]:
@@ -4095,6 +4097,7 @@ def violinplot(
40954097
quantiles=quantiles,
40964098
points=points,
40974099
bw_method=bw_method,
4100+
side=side,
40984101
**({"data": data} if data is not None else {}),
40994102
)
41004103

lib/matplotlib/tests/test_axes.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3794,6 +3794,21 @@ def test_horiz_violinplot_custompoints_200():
37943794
showextrema=False, showmedians=False, points=200)
37953795

37963796

3797+
@image_comparison(['violinplot_sides.png'], remove_text=True, style='mpl20')
3798+
def test_violinplot_sides():
3799+
ax = plt.axes()
3800+
np.random.seed(19680801)
3801+
data = [np.random.normal(size=100)]
3802+
# Check horizontal violinplot
3803+
for pos, side in zip([0, -0.5, 0.5], ['both', 'low', 'high']):
3804+
ax.violinplot(data, positions=[pos], vert=False, showmeans=False,
3805+
showextrema=True, showmedians=True, side=side)
3806+
# Check vertical violinplot
3807+
for pos, side in zip([4, 3.5, 4.5], ['both', 'low', 'high']):
3808+
ax.violinplot(data, positions=[pos], vert=True, showmeans=False,
3809+
showextrema=True, showmedians=True, side=side)
3810+
3811+
37973812
def test_violinplot_bad_positions():
37983813
ax = plt.axes()
37993814
# First 9 digits of frac(sqrt(47))

0 commit comments

Comments
 (0)