Search code examples
pythonmatplotlibseabornjointplot

Seaborn jointplot annotate with correlation


Before the release of the latest seaborn version, I was able to use the following to annotate my plot with the pearson Rho.

Using the latest version I am unable to find a way to do the same as #ax.annotate(stats.pearsonr) throws an error.

import matplotlib as mpl
import scipy.stats as stat
import matplotlib.pyplot as plt
import pandas as pd, numpy as np
import scipy.stats as stats
import seaborn as sns

X = np.random.rand(10,2)

df = pd.DataFrame(X, columns=['v1', 'v2'])

a = df.v1.values
b = a*2 + a**5

print("The Rho is {}".format(np.corrcoef(a,b)[0][1]))

ax = sns.jointplot(a, b, kind='reg',color='royalblue')
#ax.annotate(stats.pearsonr)
ax.ax_joint.scatter(a,b)
ax.set_axis_labels(xlabel='a', ylabel='b', size=15)
plt.tight_layout()
plt.show()

Old output that I cannot get anymore:

enter image description here


Solution

  • sns.jointplot doesn't return an ax, but a JointGrid. You can use ax_joint, ax_marg_x, and ax_marg_y as normal matplotlib axes to make changes to the subplots, such as adding annotations.

    Here is an example using axis fraction coordinates for positioning.

    import matplotlib.pyplot as plt
    import numpy as np
    import scipy.stats as stats
    import seaborn as sns
    
    a = np.random.rand(10)
    b = a * 2 + a ** 5
    
    print("The Rho is {}".format(np.corrcoef(a, b)[0][1]))
    
    g = sns.jointplot(x=a, y=b, kind='reg', color='royalblue')
    # ax.annotate(stats.pearsonr)
    r, p = stats.pearsonr(a, b)
    g.ax_joint.annotate(f'$\\rho = {r:.3f}, p = {p:.3f}$',
                        xy=(0.1, 0.9), xycoords='axes fraction',
                        ha='left', va='center',
                        bbox={'boxstyle': 'round', 'fc': 'powderblue', 'ec': 'navy'})
    g.ax_joint.scatter(a, b)
    g.set_axis_labels(xlabel='a', ylabel='b', size=15)
    plt.tight_layout()
    plt.show()
    

    example plot