2017-07-03 19 views
1

私はいくつかの点を追加したいseaborn boxplot(sns.boxplot)を持っています。seaborn boxplot boxの正確なデータ座標を取得する

[In] sns.boxplot(x='Property 2', hue='Property 1', y='Value', data=df) 
[Out] 

Boxplot alone

は、今私は、特定の場合のためにマーカーを追加したいと言う:私は簡単にseabornと箱ひげ図を生成することができます

[In] import pandas as pd 
     import numpy as np 
     import matplotlib.pyplot as plt 
     import seaborn as sns 

     df = pd.DataFrame({'Property 1':['a']*100+['b']*100, 
         'Property 2': ['w', 'x', 'y', 'z']*50, 
         'Value': np.random.normal(size=200)}) 
     df.head(3) 

[Out]   Property 1 Property 2 Value 
      0 a    w  1.421380 
      1 a    x  -1.034465 
      2 a    y  0.212911 
[In] df.shape 
[Out] (200, 3) 

:たとえば、私はこのパンダのデータフレームを持っていると言います私のサンプル。私はこれと密接に得ることができます。もちろん、不十分である

[In] specific_case = pd.DataFrame([['a', 'w', '0.5'], 
            ['a', 'x', '0.2'], 
            ['a', 'y', '0.1'], 
            ['a', 'z', '0.3'], 
            ['b', 'w', '-0.5'], 
            ['b', 'x', '-0.2'], 
            ['b', 'y', '0.3'], 
            ['b', 'z', '0.5'] 
            ], 
            columns = df.columns 
            ) 
[In] sns.boxplot(x='Property 2', hue='Property 1', y='Value', data=df) 
     plt.plot(np.arange(-0.25, 3.75, 0.5), 
       specific_case['Value'].values, 'ro') 
[Out] 

Adding markers with human guess

。私の第二のためにすべてではない

[In] def get_x_coordinates_of_seaborn_boxplot(ax, x_or_y): 
     display_coordinates = [] 
     inv = ax.transData.inverted()  
     for c in ax.get_children(): 
      if type(c) == mpl.patches.PathPatch: 
       if x_or_y == 'x':   
        display_coordinates.append(
         (c.get_extents().xmin+c.get_extents().xmax)/2) 
       if x_or_y == 'y': 
        display_coordinates.append(
         (c.get_extents().ymin+c.get_extents().ymax)/2) 
     return inv.transform(tuple(display_coordinates)) 

私の最初の色相のために素晴らしい作品が、:

私は、その後のデータは、この関数を記述するための座標にdiplayの変換についてbBoxthis tutorialを得ることについて語るthis answer座標を使用しました:

[In] ax = sns.boxplot(x='Property 2', hue='Property 1', y='Value', data=df) 
     coords = get_x_coordinates_of_seaborn_boxplot(ax, 'x') 
     plt.plot(coords, specific_case['Value'].values, 'ro') 
[Out] 

Almost there...

どのように取得することができます私のすべてのボックスのデータ座標ですか?

答えて

1

私はこれらの変換の目的については不明です。しかし実際の問題はちょうどspecific_caseのポイントを正しい位置にプロットすることだと思われます。すべてのboxplotのx座標は、整数から0.2だけシフトしています。 (バーはデフォルトで0.8ワイドであるため、2つのボックスがあり、それぞれ0.4ワイド、その半分は0.2です)。 x値をspecific_caseデータフレームのものに合わせて配置する必要があります。

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

df = pd.DataFrame({'Property 1':['a']*100+['b']*100, 
       'Property 2': ['w', 'x', 'y', 'z']*50, 
       'Value': np.random.normal(size=200)}) 

specific_case = pd.DataFrame([['a', 'w', '0.5'], 
          ['a', 'x', '0.2'], 
          ['a', 'y', '0.1'], 
          ['a', 'z', '0.3'], 
          ['b', 'w', '-0.5'], 
          ['b', 'x', '-0.2'], 
          ['b', 'y', '0.3'], 
          ['b', 'z', '0.5'] 
          ], columns = df.columns) 
ax = sns.boxplot(x='Property 2', hue='Property 1', y='Value', data=df) 

X = np.repeat(np.atleast_2d(np.arange(4)),2, axis=0)+ np.array([[-.2],[.2]]) 
ax.plot(X.flatten(), specific_case['Value'].values, 'ro', zorder=4) 

plt.show() 

enter image description here