2017-12-14 28 views
1

私はpandasデータフレームを使用してボックスプロットを作成しましたが、今度は同じプロットの特定の値に "X"(うまくいけば赤い!パンダを使用してBoxplotの特定の値をマーク

一部のデータ:

df = pd.DataFrame(
[ 
[2, 4, 5, 6, 1], 
[4, 5, 6, 7, 2], 
[5, 4, 5, 5, 1], 
[10, 4, 7, 8, 2], 
[9, 3, 4, 6, 2], 
[3, 3, 4, 4, 1] 
], columns=['a1', 'a2', 'a3', 'a4', 'b']) 

mark_values = pd.DataFrame(
[ 
[2,1], 
[8.25,2] 
], columns=['a1', 'b']) 

df_long = pd.melt(df, "b", var_name="a", value_name="c") 
g = sns.boxplot(x='c', y='a', hue='b', data=df_long, 
palette=sns.color_palette("Blues_d"), orient='h') 
sns.despine(left=True) 

これは箱ひげ図を生成します。赤い十字などのマーカーを追加したいと思います。サブタイプa1、サブグループにXを "4"、サブグループにXを "8.25"などでマーキングしても、わかりやすいボックスプロットを保持します。

上記のデータフレームmark_valuesのように、マークする値を定義して保存する必要があります。例のように:

mark_values 

Out[1]: 
    a1 b 
0 4.00 1 
1 8.25 2 

簡単な解決方法はありますか? Seabornがmatplotlibを使用して構築されているので

おかげ

答えて

0

あなたはtextを使用することができます。

import pandas as pd 
import seaborn as sns 

df = pd.DataFrame(
[ 
[2, 4, 5, 6, 1], 
[4, 5, 6, 7, 2], 
[5, 4, 5, 5, 1], 
[10, 4, 7, 8, 2], 
[9, 3, 4, 6, 2], 
[3, 3, 4, 4, 1] 
], columns=['a1', 'a2', 'a3', 'a4', 'b']) 

mark_values = pd.DataFrame(
[ 
[2,1], 
[8.25,2] 
], columns=['a1', 'b']) 

df_long = pd.melt(df, "b", var_name="a", value_name="c") 
g = sns.boxplot(x='c', y='a', hue='b', data=df_long, 
palette=sns.color_palette("Blues_d"), orient='h') 
sns.despine(left=True) 
g.text(4,0.1,'X', fontsize=50, color='red') 
g.text(8.25,.5,'X', fontsize=50, color='red') 

enter image description here

X軸は単にcからの値です。しかし、希望の出力を得るためにget_ylim()で作業することもできます。あなたはまた、等間隔の値を取得するためにnp.linspaceを使用することができます。

import numpy as np 
print(g.get_ylim()) 
print(str(g.get_ylim()[0]) + ' is the low value') 
print(str(g.get_ylim()[1]) + ' is the high value') 
print(np.linspace(g.get_ylim()[0], g.get_ylim()[1], 4)) 

も左下に「X」のは、XとY軸の正確なintersacitonになりますのでご注意ください。 50のfontsizeは、Xが "オフ"のように見える場所が大きすぎます。 'X'が正しい位置にくるように、これらの値で遊ぶ必要があるかもしれません。しかしあなたの質問から私はあなたがXをどれくらいの大きさにしたいのかは分かりません。

ここで違いを見てください。 -.08.1が30のフォントサイズに適していたようです。緑色の「X」はこれらの調整値を使用しています。

g.text(4,2.1666,'X', fontsize=30, color='red') 
g.text(4 - (4*.08) ,2.1666 + (2.1666 * .1),'X', fontsize=30, color='green') 

enter image description here

+1

はい、動作しますが、しかし、あなたはどこにに非常に特異的ではないだろうが、実際のマーカー... 'a3'にマーカーを入れたいとしたら、私のy値が何であるかを推測する必要があります。右? – gussilago

+0

@gussilago、私の編集をチェックしてください。あなたは 'get_ylim()'で気になるかもしれません。例えば、「Y」値をカテゴリの数で除算して、グラフ上のスポットの推定値を得る。おそらくよりエレガントな方法がありますが、これは私のテストで大丈夫です。 – MattR

0

まず、私はそれは例えば、"a"を表示しなければならないかを指定する列が含まれるようにmark_valuesを定義するために理にかなっていると思います"a1"をマークするには、1をaの列に入れます。

 c a b 
0 2.00 1 1 
1 8.25 1 2 

その後散乱座標はそれを説明するために

y = (a-1)+(b-1.5)*0.4 

により与えられる水平方向および垂直方向の列Cである場合マーカーとして「X」で散布図をプロットすることができる:

  • 1で開始しますが、最初のカテゴリは0でプロットされ、すべてのb値の間
  • 平均ここにあります1.5。バー幅の
  • 半分は合計で0.4

あり、これは与える:

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


df = pd.DataFrame([[2, 4, 5, 6, 1], 
        [4, 5, 6, 7, 2], 
        [5, 4, 5, 5, 1], 
        [10, 4, 7, 8, 2], 
        [9, 3, 4, 6, 2], 
        [3, 3, 4, 4, 1]], 
       columns=['a1', 'a2', 'a3', 'a4', 'b']) 

mark_values = pd.DataFrame([ [2,1,1], [8.25,1,2], [4,3,2] ], columns=['c',"a",'b']) 
print mark_values 
df_long = pd.melt(df, "b", var_name="a", value_name="c") 

ax = sns.boxplot(x='c', y='a', hue='b', data=df_long, 
       palette=sns.color_palette("Blues_d"), orient='h') 
sns.despine(left=True) 

y = (mark_values["a"].values - 1)+(mark_values["b"].values-1.5)*0.4 
ax.scatter(mark_values["c"].values, y, marker="x", c="red", s=400, lw=6) 

plt.show() 

enter image description here

関連する問題