我使用pandas dataframe创建了一个boxplot,现在我想在同一个图中标记特定的值,使用" X" (希望在尖叫的红色!)。
一些数据:
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 ,子组 1 ,其中X位于" 4"和子组 2 ,其中X位于&# 34; 8.25"等等,仍然保留我的漂亮的箱形图。
应标记要标记的值,并将其存储为上面定义的数据框mark_values
。如示例所示:
mark_values
Out[1]:
a1 b
0 4.00 1
1 8.25 2
对此有任何简单的解决方案吗?
由于
答案 0 :(得分:0)
由于Seaborn是使用matplotlib
构建的,因此您可以使用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')
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轴的确切位置。因此,字体大小为50使得它看起来像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')
答案 1 :(得分:0)
首先我想有必要定义mark_values
以包含一个列,该列指定应标记哪个"a"
,例如标记"a1"
,将1放在一列中。
c a b
0 2.00 1 1
1 8.25 1 2
然后,您可以使用“x”作为标记绘制散点图,其中散点坐标为水平方向的列c,垂直方向由
给出y = (a-1)+(b-1.5)*0.4
解释一下:
b
值之间的平均值为1.5。总的来说,这给出了:
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()