1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| import matplotlib.pyplot as plt import numpy as np
def adjacent_values(vals, q1, q3): upper_adjacent_value = q3 + (q3 - q1) * 1.5 upper_adjacent_value = np.clip(upper_adjacent_value, q3, vals[-1])
lower_adjacent_value = q1 - (q3 - q1) * 1.5 lower_adjacent_value = np.clip(lower_adjacent_value, vals[0], q1) return lower_adjacent_value, upper_adjacent_value
def set_axis_style(ax, labels): ax.get_xaxis().set_tick_params(direction='out') ax.xaxis.set_ticks_position('bottom') ax.set_xticks(np.arange(1, len(labels) + 1)) ax.set_xticklabels(labels) ax.set_xlim(0.25, len(labels) + 0.75) ax.set_xlabel('Sample name')
np.random.seed(19680801) data = [sorted(np.random.normal(0, std, 100)) for std in range(1, 5)]
fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(9, 4), sharey=True)
ax1.set_title('Default violin plot') ax1.set_ylabel('Observed values') ax1.violinplot(data)
ax2.set_title('Customized violin plot') parts = ax2.violinplot( data, showmeans=False, showmedians=False, showextrema=False)
for pc in parts['bodies']: pc.set_facecolor('#D43F3A') pc.set_edgecolor('black') pc.set_alpha(1)
quartile1, medians, quartile3 = np.percentile(data, [25, 50, 75], axis=1) whiskers = np.array([ adjacent_values(sorted_array, q1, q3) for sorted_array, q1, q3 in zip(data, quartile1, quartile3)]) whiskersMin, whiskersMax = whiskers[:, 0], whiskers[:, 1]
inds = np.arange(1, len(medians) + 1) ax2.scatter(inds, medians, marker='o', color='white', s=30, zorder=3) ax2.vlines(inds, quartile1, quartile3, color='k', linestyle='-', lw=5) ax2.vlines(inds, whiskersMin, whiskersMax, color='k', linestyle='-', lw=1)
labels = ['A', 'B', 'C', 'D'] for ax in [ax1, ax2]: set_axis_style(ax, labels)
plt.subplots_adjust(bottom=0.15, wspace=0.05) plt.show()
|