0

Consider the following data and FacetGrid:

d = {'SITE':['A', 'B', 'C', 'C', 'A'], 'VF':[0.00, 0.78, 0.99, 1.00, 0.50],'TYPE':['typeA', 'typeA', 'typeB', 'typeC', 'typeD']} 
new_df = pd.DataFrame(data=d) 


with sns.axes_style("white"):
    g = sns.FacetGrid(data=new_df, col='SITE', col_wrap= 3, height=7, aspect=0.25, 
                      hue='TYPE', palette=['#1E88E5', '#FFC107', '#D81B60'])
    g.map(sns.scatterplot, 'VF', 'TYPE', s=100)

Example FacetGrid

Using another dataframe:

d = {'SITE':['A', 'B', 'C'], 'N':[10, 5, 7]} 

ann_df = pd.DataFrame(data=d) 

Where the SITE matches the original new_df['SITE'], and is not the same dimensions as new_df['SITE'], but has the corresponding length of columns in the FacetGrid.

How do you annotate each subplot using a custom func using not the scatterplot new_df, but the ann_df or custom list, if it matches the original new_df['SITE'] and adds the ann_df['N'] to each subplot as shown below:

enter image description here

So, something along these lines or better:

def annotate(data, **kws):
n = data           # should be the int for each matching SITE 
ax = plt.gca()
ax.text(.1, .2, f"N = {n}", transform=ax.transAxes)

g.map_dataframe(annotate(ann_df)) 
Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Novice
  • 1,101
  • 4
  • 18
  • 30

1 Answers1

0
  • It is recommended from seaborn v0.11.0 to use figure-level functions like seaborn.relplot instead of seaborn.FacetGrid
  • The values used for col= will be plotted alphabetically by default, otherwise specify an order with col_order=, and then make sure ann_df['SITE'] is sorted in the same order.
  • Flatten the seaborn.axisgrid.FacetGrid returned by sns.relplot, iterate through the matplotlib.axes, and add .text to each plot by using i from enumerate with .iloc to index the correct value for 'N'.
  • Similar to this answer, but getting data from a secondary DataFrame instead of a dict.
  • Tested in python 3.10, pandas 1.4.2, matplotlib 3.5.1, seaborn 0.11.2
import seaborn as sns
import pandas as pd

# DataFrame 1
d1 = {'SITE':['A', 'B', 'C', 'C', 'A'],
      'VF':[0.00, 0.78, 0.99, 1.00, 0.50],
      'TYPE':['typeA', 'typeA', 'typeB', 'typeC', 'typeD']} 
df = pd.DataFrame(data=d1)

# DataFrame 2
d2 = {'SITE':['A', 'B', 'C'], 'N':[10, 5, 7]} 
ann_df = pd.DataFrame(data=d2) 

# plot
g = sns.relplot(kind='scatter', data=df, x='VF', y='TYPE', col='SITE',
                col_wrap=3, height=7, aspect=0.5, hue='TYPE', s=100)

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

# iterate through the axes
for i, ax in enumerate(axes):
    ax.text(0, 3, f"N = {ann_df.iloc[i, 1]}")

enter image description here

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158