Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing Diagonal line (line of equality) on Seaborn Jointplot

I'm using a seaborn jointplot for scatterplotting purposes, but I can't seem to get a simple diagonal line going across... I'm getting a AttributeError: 'JointGrid' object has no attribute 'get_xlim'. Does anyone know a workaround using Seaborn?

Here's my code (also the title doesn't show up! what gives):

ax = sns.jointplot(x="Av Tomato-meter", y="Av Audience Score", data=director_combined_ratings, stat_func = None, 
                   size = 8, xlim=(0,100), ylim=(0,100))

ax.plot(ax.get_xlim(), ax.get_ylim(), ls="--", c=".3") #this is the error line.

ax.title = "Average Tomato-meter vs Audience Score for Directors with over 10 Movies"

thanks in advance everyone.

like image 841
SpicyClubSauce Avatar asked Jul 13 '15 19:07

SpicyClubSauce


People also ask

How do you draw a diagonal line on a scatter plot in Python?

Plotting a diagonal line based from the bottom-left to the top-right of the screen is quite simple, you can simply use ax. plot(ax. get_xlim(), ax. get_ylim(), ls="--", c=".

What is a Jointplot in Seaborn?

The function jointplot() in Seaborn library creates a scatter plot with two histograms at the top and right margins of the graph by default. Let us load the 'tips' dataset and pass the column data to the jointplot() function for our analysis.

What is the advantage of using Jointplot to plot data?

Draw a plot of two variables with bivariate and univariate graphs. This function provides a convenient interface to the JointGrid class, with several canned plot kinds. This is intended to be a fairly lightweight wrapper; if you need more flexibility, you should use JointGrid directly.


1 Answers

The error was a useful hint: a JointGrid organizes several subplots, you have to find the specific ax to plot onto. :

import numpy as np
import pandas as pd
import seaborn as sns
from matplotlib.pyplot import show
sns.set_style('darkgrid')

# Generate a random correlated bivariate dataset
# https://stackoverflow.com/questions/16024677/generate-correlated-data-in-python-3-3

rs = np.random.RandomState(5)
mean = [0, 0]
cov = [[2, .1],
       [.5, 3]]  # make it asymmetric as a better test of x=y line
y = np.random.multivariate_normal(mean, cov, 500, tol=1e-4)

# Show the joint distribution using kernel density estimation
g = sns.jointplot(x=y[:,0], y=y[:,1],
                  kind="kde",
                  fill="true", height=5, space=0, levels=7)

# Draw a line of x=y 
x0, x1 = g.ax_joint.get_xlim()
y0, y1 = g.ax_joint.get_ylim()
lims = [max(x0, y0), min(x1, y1)]
g.ax_joint.plot(lims, lims, '-r')
show()

A jointplot shows the density view of a "mountain", with the projections along the X and Y axes plotted above and to the right. The x=y line is plotted in red.

I figured this out in an interpreter: dir(g), then g.plot?, g.plot_joint? -- those are plotting functions specific to the jointplot -- what else was there? -- dir(g.ax_joint); aha, there's set_ylim, etc.

The diagonal line is the x=y line, but note that it isn't the 45deg diagonal of the pixels of the central plot. The seaborn jointplot function always draws a square central plot. When the data is asymmetric the X and Y axes of the plot will change to fit into the square. The variable lims holds the edges of the display in data coordinates.

There's a comment suggesting a diagonal plotted that will always be the diagonal of the display, but it isn't the line of equality of the data. Here are a few lines to add to test this and figure out which you want:

# This will always go from corner to corner of the displayed plot
g.ax_joint.plot([0,1], [0,1], ':y', transform=g.ax_joint.transAxes)

# This is the x=y line using transforms
g.ax_joint.plot(lims, lims, 'w', linestyle='dashdot', transform=g.ax_joint.transData)

# This is a simple way of checking which is x=y
g.ax_joint.scatter(x=[0, 2],y=[0,2], s=30,c= 'w',marker='o')
show()

The previous plot, with two more lines plotted, one the 45deg diagonal of the center plot, the other x=y. Also (0,0) and (2,2) have been plotted as points to verify x=y.

like image 196
cphlewis Avatar answered Sep 18 '22 07:09

cphlewis