2017-09-29 100 views
0

我要繪製兩個箱線圖和一個數字的平均值。到目前爲止,我的情節看起來像這樣使用這些代碼:的Python:seaborn pointplot和積於一身,但箱線圖上移動x軸

sns.swarmplot(x="stimulus", y="data", data=spi_num.astype(np.float), edgecolor="black", linewidth=.9) 
sns.boxplot(x="stimulus", y="data", data=spi_num.astype(np.float), saturation=1) 
sns.pointplot(x="stimulus", y="data", data=spi_num.astype(np.float), linestyles='', scale=1, color='k', errwidth=1.5, capsize=0.2, markers='x') 
sns.pointplot(x="stimulus", y="data", data=spi_num.astype(np.float), linestyles='--', scale=0.4, color='k', errwidth=0, capsize=0) 
plt.ylabel("number of spikes") 
plt.title("Median Number of Spikes"); 

enter image description here

我想有點改變我的平均「X」標誌的權利,這樣的errorbars不重疊盒子裏的鬍鬚。任何想法如何做到這一點?一個額外的問題:我如何在這個情節中插入一個說明「x:mean,o:data values」優雅的圖例?


建立我的數據框

trial_vec = np.tile(np.arange(16)+1, 10)  
stimulus_vec = np.repeat([-2., -1.75, -1., -0.75, -0.5, 0.5, 1., 1.25, 1.75, 2.5 ], 16)     
data_vec  = np.random.randint(0, 16, size=160) 
spi_num  = pd.DataFrame({'trial': trial_vec, 'stimulus': stimulus_vec, 'data': data_vec}).astype('object') 

回答

1

爲了在一塊土地上換檔點,可以使用轉換;在這種情況下,ScaledTranslation是有用的。不幸的是,seaborn不允許直接使用變換,也不允許訪問繪製的對象。因此需要從座標軸中獲取繪製的對象(本例中爲PathCollection)。如果要偏移的圖是軸ax中的第一個圖,我們可以簡單地通過ax.collections[0]得到它。然後我們可以通過.set_transform來設置變換。

fig, ax = plt.subplots() 
sns.pointplot(... , ax=ax) 
#produce transform with 5 points offset in x direction 
offset = transforms.ScaledTranslation(5/72., 0, ax.figure.dpi_scale_trans) 
trans = ax.collections[0].get_transform() 
ax.collections[0].set_transform(trans + offset) 

完整代碼:

import pandas as pd 
import numpy as np 
import seaborn as sns 
import matplotlib.pyplot as plt 
import matplotlib.transforms as transforms 


trial_vec = np.tile(np.arange(16)+1, 10)  
stimulus_vec = np.repeat([-2., -1.75, -1., -0.75, -0.5, 0.5, 1., 1.25, 1.75, 2.5 ], 16) 
data_vec  = np.random.randint(0, 16, size=160) 
spi_num  = pd.DataFrame({'trial': trial_vec, 
          'stimulus': stimulus_vec, 'data': data_vec}) 

fig, ax = plt.subplots() 

sns.pointplot(x="stimulus", y="data", data=spi_num, linestyles='', scale=1, 
       color='k', errwidth=1.5, capsize=0.2, markers='x', ax=ax) 
#produce transform with 5 points offset in x direction 
offset = transforms.ScaledTranslation(5/72., 0, ax.figure.dpi_scale_trans) 
trans = ax.collections[0].get_transform() 
ax.collections[0].set_transform(trans + offset) 

sns.swarmplot(x="stimulus", y="data", data=spi_num, edgecolor="black", linewidth=.9, ax=ax) 
sns.boxplot(x="stimulus", y="data", data=spi_num, saturation=1, ax=ax) 
sns.pointplot(x="stimulus", y="data", data=spi_num, linestyles='--', scale=0.4, 
       color='k', errwidth=0, capsize=0, ax=ax) 
plt.ylabel("number of spikes") 
plt.title("Median Number of Spikes"); 

plt.show() 

enter image description here

要轉移lineplot還有,你需要做的與上面相同,其散射點(ax.collections[1])和所有行(ax.lines

sns.pointplot(x="stimulus", y="data", data=spi_num, linestyles='--', scale=0.4, 
       color='k', errwidth=0, capsize=0, ax=ax, gid="Nm") 
# shift points of connecting line: 
trans = ax.collections[1].get_transform() 
ax.collections[1].set_transform(trans + offset) 
# shift everything else: 
for line in ax.lines: 
    trans = line.get_transform() 
    line.set_transform(trans + offset) 
+0

你是親,th anks!我會稍後再嘗試。 –

+0

如何將虛線與我的'x's一起移動?還有錯誤條?到目前爲止,只有我的標記被移動,但看起來很奇怪。 –

+0

問題在哪裏?你有嘗試過什麼嗎? – ImportanceOfBeingErnest