在特定位置绘制一条水平线/注释Seaborn中的Facetgrid

BCA*_*Arg 7 python seaborn facet-grid

A通过以下方式在Seaborn中制作了Facetgrid的箱线图

# Import the dataset
tips = sns.load_dataset("tips")

# Plot using Facegrid, separated by smoke
plt.style.use('ggplot')
g = sns.FacetGrid(tips, col="smoker", size=5, aspect=1.5)
g.map(sns.boxplot, "sex", "total_bill", palette='viridis', order=['Male', 'Female'])
plt.show()
Run Code Online (Sandbox Code Playgroud)

我现在想在每个图中绘制不同的水平线。例如,一条水平线(坐标为(0,10))在左侧图中,而另一条水平线(坐标为(0,30))在右侧图中。

我该怎么做呢?

Tre*_*ney 13

  • 建议seaborn v0.11.0使用图形级函数,例如seaborn.catplot代替seaborn.FacetGrid
  • 如果每个 需要不同的行位置和注释axes,那么最简单的实现是将位置和文本放入 中dict,并axes在创建绘图时压平返回的结果。
    • 使用 enumerate 访问每组值dict
    • 这确实需要知道输出图的顺序,因此需要运行该图,然后创建 anddict循环来添加线条和注释。
  • 或者,请参阅此答案,它使用 和 提取每个轴的行名称和列g.row_names名称g.col_names。行名和列名可以用作keys.
  • matplotlib.pyplot.vlines和用于matplotlib.pyplot.hlines多条垂直或水平线。
import seaborn as sns

tips = sns.load_dataset("tips")
g = sns.catplot(kind='box', data=tips, col='smoker', row='sex', x='sex', y='total_bill', height=3)

# dict of line positions and annotations
la = {0: [5, 0.4, 0.75, 40, 'text_a'], 1: [10, 0.5, 0.75, 40, 'text_b'],
      2: [25, 0.6, 0.75, 40, 'text_c'], 3: [35, 0.7, 0.75, 40, 'text_d']}

# flatten axes into a 1-d array
axes = g.axes.flatten()

# iterate through the axes
for i, ax in enumerate(axes):
    ax.axhline(la[i][0], ls='--', c='green')
    ax.axvline(la[i][1], ls='--', c='purple')
    ax.text(la[i][2], la[i][3], la[i][4], c='orange')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Dav*_*idG 11

您可以获取FacetGrid中使用的轴的列表,使用该列表FacetGrid.axes可返回使用的轴。然后,您可以使用以下轴进行所有常规的matplotlib操作,例如axhline用于水平线,或plt.text在轴上放置文本:

import seaborn as sns
import matplotlib.pyplot as plt
tips = sns.load_dataset("tips")

# Plot using Facegrid, separated by smoke
plt.style.use('ggplot')
g = sns.FacetGrid(tips, col="smoker", size=5, aspect=1.5)
g.map(sns.boxplot, "sex", "total_bill", palette='viridis', order=['Male', 'Female'])

ax1, ax2 = g.axes[0]

ax1.axhline(10, ls='--')
ax2.axhline(30, ls='--')

ax1.text(0.5,25, "Some text")
ax2.text(0.5,25, "Some text")

plt.show()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明


小智 11

此外,如果您有一堆网格,想要向所有网格添加一条水平线(例如 y=10),那么您只需将“plt.axhline”与网格对象“映射”即可:

import seaborn as sns
import matplotlib.pyplot as plt
tips = sns.load_dataset("tips")
# Plot using Facegrid, separated by smoke
plt.style.use('ggplot')
g = sns.FacetGrid(tips, col="smoker", size=5, aspect=1.5)
g.map(sns.boxplot, "sex", "total_bill", palette='viridis', order=['Male', 'Female'])

g.map(plt.axhline, y=10, ls='--', c='red')
Run Code Online (Sandbox Code Playgroud)