2017-06-18 67 views
1

我正在嘗試使用matplotlib和Seaborn將swarm plot和box plot繪製在一起。我發現如何將它們繪製在一起,但箱形圖出現在羣體圖下。這樣做的問題在於,羣體情節點淹沒了盒子情節,盒子情節丟失了。我認爲,通過切換所調用函數的順序,讓盒子情節首先被調用,而不是像下面鏈接那樣調用第二個情節,則會將盒子情節疊加在頂部,但它不會。在Seaborn的羣體情節之上,盒子情節如何疊加?

是否有可能覆蓋羣集繪圖頂部的箱形圖?如果沒有,是否可以創建指示四分位數的位置的行?

代碼:

swarm_name = "Swarm_Plot_01" 
# 
sns.set_style("whitegrid") 
ax = sns.boxplot( data = [df.Rate_VL1R, df.Rate_V12R, df.Rate_V23R, df.Rate_VM3R ], 
    showcaps=False,boxprops={'facecolor':'None'}, 
    showfliers=False,whiskerprops={'linewidth':0}) 
ax = sns.swarmplot(data = [df.Rate_VL1R, df.Rate_V12R, df.Rate_V23R, df.Rate_VM3R ]) 
plt.show() 
fig = ax.get_figure() 
fig.savefig(swarm_name) 
plt.figure() 

這個問題是有關,但不完全一樣的,因爲How to create a swarm plot with matplotlib我期待改變風格,不只是把兩者結合起來。

Swarm plot with box plot

回答

1

的問題是,箱線圖組成,因爲seaborn包裹機構的許多不同的音樂人,我們不能簡單地將整個boxplot的zorder設置爲更高的數字。

第一次天真的嘗試將是設置swarmplot的zorder爲零。雖然這使得插圖背後的小插曲點也放在網格線後面。因此,如果沒有使用網格線,這個解決方案只是最優的。

import seaborn as sns 
import matplotlib.pyplot as plt 
tips = sns.load_dataset("tips") 

# plot swarmplot 
ax = sns.swarmplot(x="day", y="total_bill", data=tips, zorder=0) 
# plot boxplot 
sns.boxplot(x="day", y="total_bill", data=tips, 
       showcaps=False,boxprops={'facecolor':'None'}, 
       showfliers=False,whiskerprops={'linewidth':0}, ax=ax) 

plt.show() 

enter image description here

如果網格線是期望的,我們可能將swarmplot的ZORDER設置爲1,使得其出現在網格線的上方,並且箱線圖的ZORDER設定爲高數字。如上所述,這需要將zorder屬性設置爲它的每個元素,因爲boxplot調用中的zorder=10不會影響所有藝術家。相反,我們需要使用boxprops,whiskerprops參數來爲這些參數設置zorder的合法性。

import seaborn as sns 
import matplotlib.pyplot as plt 
tips = sns.load_dataset("tips") 

# plot swarmplot 
ax = sns.swarmplot(x="day", y="total_bill", data=tips, zorder=1) 
# plot boxplot 
sns.boxplot(x="day", y="total_bill", data=tips, 
       showcaps=False,boxprops={'facecolor':'None', "zorder":10}, 
       showfliers=False,whiskerprops={'linewidth':0, "zorder":10}, 
       ax=ax, zorder=10) 

plt.show() 

enter image description here

的最終溶液,其可在完全沒有訪問被提供給藝術家性能一般情況下被施加是通過軸藝術家環並設置ZORDER爲他們取決於它們是否屬於這一個或另一個情節。

import seaborn as sns 
import matplotlib.pyplot as plt 
tips = sns.load_dataset("tips") 

# plot swarmplot 
ax = sns.swarmplot(x="day", y="total_bill", data=tips) 
#get all children of axes 
children1 = ax.get_children() 
# plot boxplot 
sns.boxplot(x="day", y="total_bill", data=tips, 
       showcaps=False,boxprops={'facecolor':'None'}, 
       showfliers=False,whiskerprops={'linewidth':0}, ax=ax) 
# again, get all children of axes. 
children2 = ax.get_children() 
# now those children which are in children2 but not in children1 
# must be part of the boxplot. Set zorder high for those. 
for child in children2: 
    if not child in children1: 
     child.set_zorder(10) 

plt.show() 

enter image description here

+0

「問題是boxplot由許多不同的藝術家組成,由於seaborn包裝機制,我們無法直接訪問它們。」你無法訪問哪些藝術家? – mwaskom

+0

我最初的意思是,對sns.boxplot的調用只返回一個座標軸而不是要使用的集合。我同意這是誤導,並會改變它。 – ImportanceOfBeingErnest

1

您需要更改zorderswarmplot

import seaborn.apionly as sns 
tips = sns.load_dataset("tips") 
sns.boxplot("day", "tip", data=tips, boxprops={'facecolor':'None'}) 
sns.swarmplot("day", "tip", data=tips, zorder=.5) 

enter image description here

+0

正如我的回答看出,這只是工作,如果沒有網格線都存在。 – ImportanceOfBeingErnest