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

Skip to content

Commit 1c6b59a

Browse files
committed
Merge pull request #7360 from DrNightmare/violinPlotExample
Updated violin plot example as per suggestions in issue #7251
1 parent 1759004 commit 1c6b59a

File tree

1 file changed

+39
-67
lines changed

1 file changed

+39
-67
lines changed

examples/statistics/customized_violin_demo.py

Lines changed: 39 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -18,87 +18,59 @@
1818
import numpy as np
1919

2020

21-
# functions to calculate percentiles and adjacent values
22-
def percentile(vals, p):
23-
N = len(vals)
24-
n = p*(N+1)
25-
k = int(n)
26-
d = n-k
27-
if k <= 0:
28-
return vals[0]
29-
if k >= N:
30-
return vals[N-1]
31-
return vals[k-1] + d*(vals[k] - vals[k-1])
32-
33-
34-
def adjacent_values(vals):
35-
q1 = percentile(vals, 0.25)
36-
q3 = percentile(vals, 0.75)
37-
iqr = q3 - q1 # inter-quartile range
38-
39-
# upper adjacent values
40-
uav = q3 + iqr * 1.5
41-
if uav > vals[-1]:
42-
uav = vals[-1]
43-
if uav < q3:
44-
uav = q3
45-
46-
# lower adjacent values
47-
lav = q1 - iqr * 1.5
48-
if lav < vals[0]:
49-
lav = vals[0]
50-
if lav > q1:
51-
lav = q1
52-
return [lav, uav]
21+
def adjacent_values(vals, q1, q3):
22+
upper_adjacent_value = q3 + (q3 - q1) * 1.5
23+
upper_adjacent_value = np.clip(upper_adjacent_value, q3, vals[-1])
24+
25+
lower_adjacent_value = q1 - (q3 - q1) * 1.5
26+
lower_adjacent_value = np.clip(lower_adjacent_value, vals[0], q1)
27+
return lower_adjacent_value, upper_adjacent_value
28+
29+
30+
def set_axis_style(ax, labels):
31+
ax.get_xaxis().set_tick_params(direction='out')
32+
ax.xaxis.set_ticks_position('bottom')
33+
ax.set_xticks(np.arange(1, len(labels) + 1))
34+
ax.set_xticklabels(labels)
35+
ax.set_xlim(0.25, len(labels) + 0.75)
36+
ax.set_xlabel('Sample name')
5337

5438

5539
# create test data
5640
np.random.seed(123)
57-
dat = [np.random.normal(0, std, 100) for std in range(1, 5)]
58-
lab = ['A', 'B', 'C', 'D'] # labels
59-
med = [] # medians
60-
iqr = [] # inter-quantile ranges
61-
avs = [] # upper and lower adjacent values
62-
for arr in dat:
63-
sarr = sorted(arr)
64-
med.append(percentile(sarr, 0.5))
65-
iqr.append([percentile(sarr, 0.25), percentile(sarr, 0.75)])
66-
avs.append(adjacent_values(sarr))
67-
68-
# plot the violins
69-
fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(9, 4),
70-
sharey=True)
71-
_ = ax1.violinplot(dat)
72-
parts = ax2.violinplot(dat, showmeans=False, showmedians=False,
73-
showextrema=False)
41+
data = [sorted(np.random.normal(0, std, 100)) for std in range(1, 5)]
42+
43+
fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(9, 4), sharey=True)
7444

7545
ax1.set_title('Default violin plot')
76-
ax2.set_title('Customized violin plot')
46+
ax1.set_ylabel('Observed values')
47+
ax1.violinplot(data)
7748

78-
# plot whiskers as thin lines, quartiles as fat lines,
79-
# and medians as points
80-
for i in range(len(med)):
81-
# whiskers
82-
ax2.plot([i + 1, i + 1], avs[i], '-', color='black', linewidth=1)
83-
ax2.plot([i + 1, i + 1], iqr[i], '-', color='black', linewidth=5)
84-
ax2.plot(i + 1, med[i], 'o', color='white',
85-
markersize=6, markeredgecolor='none')
49+
ax2.set_title('Customized violin plot')
50+
parts = ax2.violinplot(
51+
data, showmeans=False, showmedians=False,
52+
showextrema=False)
8653

87-
# customize colors
8854
for pc in parts['bodies']:
8955
pc.set_facecolor('#D43F3A')
9056
pc.set_edgecolor('black')
9157
pc.set_alpha(1)
9258

93-
ax1.set_ylabel('Observed values')
59+
quartile1, medians, quartile3 = np.percentile(data, [25, 50, 75], axis=1)
60+
whiskers = np.array([
61+
adjacent_values(sorted_array, q1, q3)
62+
for sorted_array, q1, q3 in zip(data, quartile1, quartile3)])
63+
whiskersMin, whiskersMax = whiskers[:, 0], whiskers[:, 1]
64+
65+
inds = np.arange(1, len(medians) + 1)
66+
ax2.scatter(inds, medians, marker='o', color='white', s=30, zorder=3)
67+
ax2.vlines(inds, quartile1, quartile3, color='k', linestyle='-', lw=5)
68+
ax2.vlines(inds, whiskersMin, whiskersMax, color='k', linestyle='-', lw=1)
69+
70+
# set style for the axes
71+
labels = ['A', 'B', 'C', 'D']
9472
for ax in [ax1, ax2]:
95-
ax.get_xaxis().set_tick_params(direction='out')
96-
ax.xaxis.set_ticks_position('bottom')
97-
ax.set_xticks(np.arange(1, len(lab) + 1))
98-
ax.set_xticklabels(lab)
99-
ax.set_xlim(0.25, len(lab) + 0.75)
100-
ax.set_xlabel('Sample name')
73+
set_axis_style(ax, labels)
10174

10275
plt.subplots_adjust(bottom=0.15, wspace=0.05)
103-
10476
plt.show()

0 commit comments

Comments
 (0)