Как создать асимметричный график скрипки в python с использованием Matplotlib

#python #matplotlib #violin-plot

#python #matplotlib #violin-plot

Вопрос:

У меня есть эти два образца наборов данных:

 data = np.exp ( np.random.randn(N) ) 
data[data>threshold] = threshold   np.random.randn(sum(data>threshold))*0.2
data_1 = data
data_2 = np.random.randn(N)
  

И я хотел бы знать, как создать асимметричный график скрипки с использованием Matplotlib plt.violinplot() , в котором оба набора данных нанесены на две стороны одной оси. К сожалению, я не смог найти правильные параметры для этой функции, поскольку она доступна для statsmodels.graphics.boxplots.violinplot(side=) или для seaborn библиотеки.
Это мой код для отдельных графиков скрипки:

 import numpy as np
import matplotlib.pyplot as plt 

N = 10000
threshold = 5 

data = np.exp ( np.random.randn(N) ) 
data[data>threshold] = threshold   np.random.randn(sum(data>threshold))*0.2

data_1 = data
data_2 = np.random.randn(N)
plt.figure(figsize = (15,5))
plt.subplot(1,2,1)
plt.violinplot(data_1)
plt.title('Violin Plot For Dataset 1')

plt.subplot(1,2,2)[enter image description here][1]
plt.violinplot(data_2)
plt.title('Violin Plot For Dataset 2');
  

Результат прилагается.
[1]: https://i.stack.imgur.com/hx0Ha.png

Комментарии:

1. почему бы не использовать seaborn ?

2. На самом деле я предпочитаю писать этот код только на основе этих двух библиотек, однако мне хотелось бы знать, как это сделать, используя seaborn , если вы считаете, что это подойдет лучше.

Ответ №1:

Используя seaborn , вам необходимо преобразовать ваши данные в dataframe. split= Аргумент должен использоваться с hue -nesting , который можно использовать, только если у вас уже есть x= аргумент. Поэтому вам необходимо предоставить столбцы для обоих x (должно быть одинаковое значение для обоих наборов данных) и hue (кодируется в зависимости от набора данных):

 N=100
data_1 = np.random.normal(loc=1, size=N)
data_2 = np.random.normal(loc=2, size=N)

data = pd.DataFrame({'data_1':data_1, 'data_2':data_2})
data = data.melt()
data['dummy'] = 0

sns.violinplot(data=data, y='value', split=True, hue='variable', x='dummy')
  

введите описание изображения здесь

Для использования statsmodels.graphics.boxplots.violinplot требуется два вызова, по одному для каждого набора данных

 from statsmodels.graphics.boxplots import violinplot
fig, ax = plt.subplots()
violinplot([data_1], positions=[0], show_boxplot=False, side='left', ax=ax, plot_opts={'violin_fc':'C0'})
violinplot([data_2], positions=[0], show_boxplot=False, side='right', ax=ax, plot_opts={'violin_fc':'C1'})
  

введите описание изображения здесь