簡體   English   中英

Python:seaborn pointplot和boxplot在一個圖中,但在x軸上移位

[英]Python: seaborn pointplot and boxplot in one plot but shifted on the x-axis

我想在一個圖中繪制箱線圖和平均值。 到目前為止,我的情節使用這些代碼行看起來像這樣:

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");

在此輸入圖像描述

我想將我的平均'x'標記向右移動一點,以便錯誤條不與箱圖中的胡須重疊。 知道怎么做嗎? 一個額外的問題:如何在這個情節中插入一個圖例,說“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')

為了在圖上移動點,可以使用變換; 在這種情況下, 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()

在此輸入圖像描述

要移動線條圖,您需要使用其散點( ax.collections[1] )和圖中的所有線( ax.lines )執行與上面相同的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)

暫無
暫無

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

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