我正在寻找一种在seaborn中表示两侧箱线图的方法。 我有2个索引(index1和index2),我想根据两个信息info1(一个数字)和info2(一个字母)来表示 我的问题是我的箱线图已经分组在一起,我不明白如何管理最后一个维度?
现在我可以在两个面板(顶部和中间)中分别表示两个索引
我想要的是在旁边表示的两个指数的箱线图
不知道是否容易实现
这里有一个简短的例子:
import numpy as np
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = plt.subplot(3, 1, 1)
ax2 = plt.subplot(3, 1, 2)
ax3 = plt.subplot(3, 1, 3)
index1 = np.random.random((4,100,4))
intex2 = np.random.random((4,100,4))/2.
info1 = np.zeros(shape=index1.shape,dtype='object')
info1[0,:,:] = 'One'
info1[1,:,:] = 'Two'
info1[2,:,:] = 'Three'
info1[3,:,:] = 'Four'
info2 = np.zeros(shape=index1.shape, dtype='object')
info2[:, :, 0] = 'A'
info2[:, :, 1] = 'B'
info2[:, :, 2] = 'C'
info2[:, :, 3] = 'D'
df = pd.DataFrame(
columns=['Info1', 'Info2', 'Index1', 'Index2'],
data=np.array(
(info1.flatten(), info2.flatten(), index1.flatten(), intex2.flatten())).T)
sns.boxplot(x='Info1', y='Index1', hue="Info2", data=df, ax=ax1)
ax1.set_title('Index1')
ax1.set_ylim([0, 1])
sns.boxplot(x='Info1', y='Index2', hue="Info2", data=df, ax=ax2)
ax2.set_ylim([0, 1])
ax2.set_title('Index2')
# sns.boxplot(x='Info1', y='Index1', hue="Info2", data=df, ax=ax3)
ax3.set_ylim([0, 1])
ax3.set_title('Index1 + Index2')
plt.show()
要在 Seaborn 中创建附加分组,其想法是让 Seaborn 创建子图网格(在 Seaborn 中称为
FacetGrid
)。函数 sns.catplot(kind='box', ...)
为箱线图创建这样的 FacetGrid
。 col=
参数负责将每个 Info1
放入单独的子图中。
要将
Index1
/Index2
用作 hue
,需要合并两列(例如通过 pd.melt(...)
)。
总共,
catplot
允许 4 组:x
、hue
、col
和 row
。
以下是代码和绘图的样子。不幸的是,您无法将这样的
catplot
强加到之前创建的图形中。
import numpy as np
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
index1 = np.random.random((4, 100, 4))
intex2 = np.random.random((4, 100, 4)) / 2.
info1 = np.zeros(shape=index1.shape, dtype='object')
info1[0, :, :] = 'One'
info1[1, :, :] = 'Two'
info1[2, :, :] = 'Three'
info1[3, :, :] = 'Four'
info2 = np.zeros(shape=index1.shape, dtype='object')
info2[:, :, 0] = 'A'
info2[:, :, 1] = 'B'
info2[:, :, 2] = 'C'
info2[:, :, 3] = 'D'
df = pd.DataFrame(
columns=['Info1', 'Info2', 'Index1', 'Index2'],
data=np.array(
(info1.flatten(), info2.flatten(), index1.flatten(), intex2.flatten())).T)
df_long = df.melt(id_vars=['Info1', 'Info2'], value_vars=['Index1', 'Index2'], var_name='Index')
sns.catplot(data=df_long, kind='box', col='Info1', x='Info2', y='value', hue='Index', height=3, aspect=1)
plt.show()