我想根据字典制作小提琴图。这是我的字典的一个例子,尽管我的实际字典有更多的患者和更多的值。
paired_patients={'Patient_1': {'n':[1, nan, 3, 4], 't': [5,6,7,8]},
'Patient_2': {'n':[9,10,11,12], 't':[14,nan,16,17]},
'Patient_3': {'n':[1.5,nan,3.5,4.5], 't':[5.5,6.5,7.5,8.5]}}
对于每个患者,我希望有一组并排的两个小提琴图,一个
'n'
和一个 't'
。我希望所有六个小提琴图都位于同一个图表上,共享 y 轴。
我正在尝试使用
matplotlib violinplot
,但我不确定如何在 'dataset'
选项中输入我的字典,也不知道如何按患者对 'n'
和 't'
进行分组。
我建议将您的数据保存在
pandas.DataFrame
中。df = pd.DataFrame(columns = ['Patient', 'n', 't'])
for key, value in paired_patients.items():
patient_df = pd.DataFrame({'Patient': [key]*len(value['n']),
'n': value['n'],
't': value['t']})
df = df.append(patient_df, ignore_index = True)
所以我得到:
Patient n t
0 Patient_1 1.0 5
1 Patient_1 NaN 6
2 Patient_1 3.0 7
3 Patient_1 4.0 8
4 Patient_2 9.0 14
5 Patient_2 10.0 NaN
6 Patient_2 11.0 16
7 Patient_2 12.0 17
8 Patient_3 1.5 5.5
9 Patient_3 NaN 6.5
10 Patient_3 3.5 7.5
11 Patient_3 4.5 8.5
然后我需要通过
'n'
堆叠't'
和pd.melt
列:
df = pd.melt(frame = df,
id_vars = 'Patient',
value_vars = ['n', 't'],
var_name = 'type',
value_name = 'value')
通过这种方式,数据框的形状如下:
Patient type value
0 Patient_1 n 1
1 Patient_1 n NaN
2 Patient_1 n 3
3 Patient_1 n 4
4 Patient_2 n 9
5 Patient_2 n 10
6 Patient_2 n 11
7 Patient_2 n 12
8 Patient_3 n 1.5
9 Patient_3 n NaN
10 Patient_3 n 3.5
11 Patient_3 n 4.5
12 Patient_1 t 5
13 Patient_1 t 6
14 Patient_1 t 7
15 Patient_1 t 8
16 Patient_2 t 14
17 Patient_2 t NaN
18 Patient_2 t 16
19 Patient_2 t 17
20 Patient_3 t 5.5
21 Patient_3 t 6.5
22 Patient_3 t 7.5
23 Patient_3 t 8.5
最后您可能需要将
'value'
列类型转换为 float
:
df['value'] = df['value'].astype(float)
现在可以使用
seaborn.violinplot
绘制这些数据:
fig, ax = plt.subplots()
sns.violinplot(ax = ax,
data = df,
x = 'Patient',
y = 'value',
hue = 'type',
split = True)
plt.show()
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
from math import nan
paired_patients = {'Patient_1': {'n': [1, nan, 3, 4], 't': [5, 6, 7, 8]},
'Patient_2': {'n': [9, 10, 11, 12], 't': [14, nan, 16, 17]},
'Patient_3': {'n': [1.5, nan, 3.5, 4.5], 't': [5.5, 6.5, 7.5, 8.5]}}
df = pd.DataFrame(columns = ['Patient', 'n', 't'])
for key, value in paired_patients.items():
patient_df = pd.DataFrame({'Patient': [key]*len(value['n']),
'n': value['n'],
't': value['t']})
df = df.append(patient_df, ignore_index = True)
df = pd.melt(frame = df,
id_vars = 'Patient',
value_vars = ['n', 't'],
var_name = 'type',
value_name = 'value')
df['value'] = df['value'].astype(float)
fig, ax = plt.subplots()
sns.violinplot(ax = ax,
data = df,
x = 'Patient',
y = 'value',
hue = 'type',
split = True)
plt.show()
如果你有很多病人,你的x轴数据就会太多,所以我建议你设置
split = True
以节省一些空间。split = False
,您将得到: