簡體   English   中英

如何使用 3D 數組的 seaborn 制作嵌套/分組箱線圖

[英]How to make a nested / grouped boxplot using seaborn of a 3D array

我正在嘗試制作一個嵌套箱線圖,如 matplotlib 的這個 SO -answer 中,但我無法弄清楚如何創建我的 dataframe。

這樣做的目的是對代表 object 位置(3D)的 PCA model 進行某種敏感性分析; 根據我使用的 PCA 組件的數量,我可以看到 PCA model 能夠代表拱形分布的能力。

所以我有一個形狀數組(n_pca_components,n_samples,n_objects),其中包含對象到拱門上的“理想”position 的距離。 我能夠進行箱線圖的是(顯示隨機數據的示例): 非嵌套箱線圖 這是 - 我假設 - 一個聚合箱線圖(在我的數組的前兩個軸上收集的統計數據); 我想創建一個具有相同 x 軸和 y 軸的箱線圖,但是對於每個 'obj_..' 我想要一個沿數據的第一個軸 ( n_pca_components)的每個值的箱線圖,即類似這樣的東西(其中天數對應到“obj_i”,“total_bill”到我存儲的距離,“吸煙者”到我數組第一個軸上的每個條目。

嵌套箱線圖

我四處閱讀,但迷失在 panda 的多索引、groupby、(un)stack、reset_index 等概念中……我看到的所有示例都有不同的數據結構,我認為這就是問題所在,我還沒有做出了心理“點擊”,並在錯誤的數據結構中思考。

到目前為止我所擁有的是(使用隨機/示例數據):

n_pca_components = 5  # Let's say I want to make this analysis for using 3, 6, 9, 12, 15 PCA components
n_objects = 14   # 14 objects per sample
n_samples = 100  # 100 samples

# Create random data
mses = np.random.rand(n_pca_components, n_samples, n_objects)   # Simulated errors

# Create column names
n_comps = [f'{(i+1) * 3}' for i in range(n_pca_components)]
object_ids = [f'obj_{i}' for i in range(n_objects)]
samples = [f'sample_{i}' for i in range(n_samples)]

# Create panda dataframe
mses_pd = mses.reshape(-1, 14)
midx = pd.MultiIndex.from_product([n_comps, samples], names=['n_comps', 'samples'])

mses_frame = pd.DataFrame(data=mses_pd, index=midx, columns=object_ids)

# Make a nested boxplot with `object_ids` on the 'large' X-axis and `n_comps` on each 'nested' X-axis; and the box-statistics about the mses stored in `mses_frame` on the y-axis.

# Things I tried (yes, I'm a complete pandas-newbie). I've been reading a lot of SO-posts and documentation but cannot seem to figure out how to do what I want.
sns.boxplot(data=mses_frame, hue='n_comps')  # ValueError: Cannot use `hue` without `x` and `y`
sns.boxplot(data=mses_frame, hue='n_comps', x='object_ids') # ValueError: Could not interpret input 'object_ids'
sns.boxplot(data=mses_frame, hue='n_comps', x=object_ids) # ValueError: Could not interpret input 'n_comps'
sns.boxplot(data=mses_frame, hue=n_comps, x=object_ids) # ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

這是你想要的嗎?

在此處輸入圖像描述

雖然我認為 seaborn 可以處理寬數據,但我個人發現使用“整潔數據” (或長數據)更容易。 要將 dataframe 從“寬”轉換為“長”,您可以使用DataFrame.melt並確保保留您的輸入。

所以

>>> mses_frame.melt(ignore_index=False)

                  variable     value
n_comps samples
3       sample_0     obj_0  0.424960
        sample_1     obj_0  0.758884
        sample_2     obj_0  0.408663
        sample_3     obj_0  0.440811
        sample_4     obj_0  0.112798
...                    ...       ...
15      sample_95   obj_13  0.172044
        sample_96   obj_13  0.381045
        sample_97   obj_13  0.364024
        sample_98   obj_13  0.737742
        sample_99   obj_13  0.762252

[7000 rows x 2 columns]

同樣,seaborn 可能可以以某種方式使用它(也許其他人可以對此發表評論)但我發現重置索引更容易,因此您的多索引成為列

>>> mses_frame.melt(ignore_index=False).reset_index()

     n_comps    samples variable     value
0          3   sample_0    obj_0  0.424960
1          3   sample_1    obj_0  0.758884
2          3   sample_2    obj_0  0.408663
3          3   sample_3    obj_0  0.440811
4          3   sample_4    obj_0  0.112798
...      ...        ...      ...       ...
6995      15  sample_95   obj_13  0.172044
6996      15  sample_96   obj_13  0.381045
6997      15  sample_97   obj_13  0.364024
6998      15  sample_98   obj_13  0.737742
6999      15  sample_99   obj_13  0.762252

[7000 rows x 4 columns]

現在你可以決定你想要什么 plot,我想你是說你想要

sns.boxplot(x="variable", y="value", hue="n_comps", 
            data=mses_frame.melt(ignore_index=False).reset_index())

如果我誤解了什么,請告訴我

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM