# 【2.4.6】小提琴图（matplotlib-violinplot）

## 一、例子

### 例1

import matplotlib.pyplot as plt
import numpy as np

fig, axes = plt.subplots(nrows=1,ncols=2, figsize=(12,5))

all_data = [np.random.normal(0, std, 100) for std in range(6, 10)]

#fig = plt.figure(figsize=(8,6))

axes[0].violinplot(all_data,
showmeans=False,
showmedians=True
)
axes[0].set_title('violin plot')

axes[1].boxplot(all_data,
)
axes[1].set_title('box plot')

for ax in axes:
ax.yaxis.grid(True)
ax.set_xticks([y+1 for y in range(len(all_data))], )
ax.set_xlabel('xlabel')
ax.set_ylabel('ylabel')

plt.setp(axes, xticks=[y+1 for y in range(len(all_data))],
xticklabels=['x1', 'x2', 'x3', 'x4'],
)

plt.show()


### 例2

"""
==================================
Demo of the basics of violin plots
==================================

Violin plots are similar to histograms and box plots in that they show
an abstract representation of the probability distribution of the
sample. Rather than showing counts of data points that fall into bins
or order statistics, violin plots use kernel density estimation (KDE) to
compute an empirical distribution of the sample. That computation
is controlled by several parameters. This example demonstrates how to
modify the number of points at which the KDE is evaluated (points)
and how to modify the band-width of the KDE (bw_method).

have a great section: http://scikit-learn.org/stable/modules/density.html
"""

import random
import numpy as np
import matplotlib.pyplot as plt

# fake data
fs = 10  # fontsize
pos = [1, 2, 4, 5, 7, 8]
data = [np.random.normal(0, std, size=100) for std in pos]

fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(6, 6))

axes[0, 0].violinplot(data, pos, points=20, widths=0.3,
showmeans=True, showextrema=True, showmedians=True)
axes[0, 0].set_title('Custom violinplot 1', fontsize=fs)

axes[0, 1].violinplot(data, pos, points=40, widths=0.5,
showmeans=True, showextrema=True, showmedians=True,
bw_method='silverman')
axes[0, 1].set_title('Custom violinplot 2', fontsize=fs)

axes[0, 2].violinplot(data, pos, points=60, widths=0.7, showmeans=True,
showextrema=True, showmedians=True, bw_method=0.5)
axes[0, 2].set_title('Custom violinplot 3', fontsize=fs)

axes[1, 0].violinplot(data, pos, points=80, vert=False, widths=0.7,
showmeans=True, showextrema=True, showmedians=True)
axes[1, 0].set_title('Custom violinplot 4', fontsize=fs)

axes[1, 1].violinplot(data, pos, points=100, vert=False, widths=0.9,
showmeans=True, showextrema=True, showmedians=True,
bw_method='silverman')
axes[1, 1].set_title('Custom violinplot 5', fontsize=fs)

axes[1, 2].violinplot(data, pos, points=200, vert=False, widths=1.1,
showmeans=True, showextrema=True, showmedians=True,
bw_method=0.5)
axes[1, 2].set_title('Custom violinplot 6', fontsize=fs)

for ax in axes.flatten():
ax.set_yticklabels([])

fig.suptitle("Violin Plotting Examples")
plt.show()


### 例3

import matplotlib.pyplot as plt
import numpy as np

upper_adjacent_value = q3 + (q3 - q1) * 1.5

lower_adjacent_value = q1 - (q3 - q1) * 1.5

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')

# create test data
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([
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)

# set style for the axes
labels = ['A', 'B', 'C', 'D']
for ax in [ax1, ax2]:
set_axis_style(ax, labels)

plt.show()


### 例4

# Import Data

# Draw Plot
plt.figure(figsize=(13,10), dpi= 80)
sns.violinplot(x='class', y='hwy', data=df, scale='width', inner='quartile')

# Decoration
plt.title('Violin Plot of Highway Mileage by Vehicle Class', fontsize=22)
plt.show()


## 二、我的案例

import matplotlib
# matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.dates import date2num
from collections import Counter
import matplotlib.patches as mpatches
import numpy as np
import pandas as pd

df_1_2 =  np.array(df_1.iloc[:,0].values.tolist())
df_2_2 =  np.array(df_2.iloc[:,0].values.tolist())
df_3_2 =  np.array(df_3.iloc[:,0].values.tolist())

all_data = [df_1_2,df_2_2,df_3_2]

# all_data = [np.random.normal(0, std, 100) for std in range(1, 4)]

# print all_data

fig = plt.figure(figsize=(8,6))

plt.violinplot(all_data,
showmeans=False,
showmedians=True,
vert=False)   # horizontal box aligmnent

plt.yticks([y+1 for y in range(len(all_data))], ['Heavy', 'Light', 'Pair'])
plt.ylabel('Chain')
plt.xlabel('# Mismatch Residues')
t = plt.title('Mismatch Residues Violin')

fig = matplotlib.pyplot.gcf()
fig.set_size_inches(15, 12)
plt.savefig('pic/pair-mismatch.jpeg',dpi=400)

plt.show()