%matplotlib inline
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
plt.rcParams['figure.figsize'] = (20.0, 10.0)
plt.rcParams['font.family'] = "serif"

"""
Explanation: seaborn.jointplot

Seaborn's jointplot displays a relationship between 2 variables (bivariate) as well as 1D profiles (univariate) in the margins. This plot is a convenience class that wraps JointGrid.
End of explanation
"""


# Generate some random multivariate data
x, y = np.random.RandomState(8).multivariate_normal([0, 0], [(1, 0), (0, 1)], 1000).T
df = pd.DataFrame({"x":x,"y":y})


"""
Explanation: The multivariate normal distribution is a nice tool to demonstrate this type of plot as it is sampling from a multidimensional Gaussian and there is natural clustering. I'll set the covariance matrix equal to the identity so that the X and Y variables are uncorrelated -- meaning we will just get a blob
End of explanation
"""


p = sns.jointplot(data=df,x='x', y='y')

"""
Explanation: Default plot
End of explanation
"""


p = sns.jointplot(data=df,x='x', y='y',kind='scatter')

"""
Explanation: Currently, jointplot wraps JointGrid with the following options for kind:
    - scatter
    - reg
    - resid 
    - kde 
    - hex 
Scatter is the default parameters
End of explanation
"""


p = sns.jointplot(data=df,x='x', y='y',kind='reg')

"""
Explanation: 'reg' plots a linear regression line. Here the line is close to flat because we chose our variables to be uncorrelated
End of explanation
"""


x2, y2 = np.random.RandomState(9).multivariate_normal([0, 0], [(1, 0), (0, 1)], len(x)).T
df2 = pd.DataFrame({"x":x,"y":y2})

p = sns.jointplot(data=df,x='x', y='y',kind='resid')

"""
Explanation: 'resid' plots the residual of the data to the regression line -- which is not very useful for this specific example because our regression line is almost flat and thus the residual is almost the same as the data.
End of explanation
"""


p = sns.jointplot(data=df,x='x', y='y',kind='kde')

"""
Explanation: kde plots a kernel density estimate in the margins and converts the interior into a shaded countour plot
End of explanation
"""


p = sns.jointplot(data=df,x='x', y='y',kind='hex')

"""
Explanation: 'hex' bins the data into hexagons with histograms in the margins. At this point you probably see the "pre-cooked" nature of jointplot. It provides nice defaults, but if you wanted, for example, a KDE on the margin of this hexplot you will need to use JointGrid.
End of explanation
"""


from scipy.stats import tmin
p = sns.jointplot(data=df, x='x', y='y',kind='kde',stat_func=tmin)

# tmin is computing roughly the equivalent of the following
print(df.loc[df.x>df.y,'x'].min())

"""
Explanation: stat_func can be used to provide a function for computing a summary statistic from the data. The full x, y data vectors are passed in, so the function must provide one value or a tuple from many. As an example, I'll provide tmin, which when used in this way will return the smallest value of x that was greater than its corresponding value of y.
End of explanation
"""


p = sns.jointplot(data=df,
                  x='x',
                  y='y',
                  kind='kde',
                  color="#99ffff")

p = sns.jointplot(data=df,
                  x='x',
                  y='y',
                  kind='kde',
                  ratio=1)

"""
Explanation: Change the color
End of explanation
"""


p = sns.jointplot(data=df,
                  x='x',
                  y='y',
                  kind='kde',
                  space=2)

"""
Explanation: Create separation between 2D plot and marginal plots with space
End of explanation
"""


p = sns.jointplot(data=df,
                  x='x',
                  y='y',
                  kind='kde',
                  xlim=(-15,15),
                  ylim=(-15,15))

"""
Explanation: xlim and ylim can be used to adjust the field of view
End of explanation
"""


p = sns.jointplot(data=df,
                  x='x',
                  y='y',
                  kind='kde',
                  marginal_kws={'lw':5,
                                'color':'red'})


"""
Explanation: Pass additional parameters to the marginal plots with marginal_kws. You can pass similar options to joint_kws and annot_kws
End of explanation
"""


from itertools import chain
p = sns.jointplot(data=df,
                  x='x',
                  y='y',
                  kind='kde',
                  xlim=(-3,3),
                  ylim=(-3,3),
                  marginal_kws={'lw':3}).set_axis_labels('X','Y')
p.ax_marg_x.set_facecolor('#ccffcc')
p.ax_marg_y.set_facecolor('#ccffcc')
for l in chain(p.ax_marg_x.axes.lines,p.ax_marg_y.axes.lines):
    l.set_linestyle('--')
    l.set_color('black')


[d for d in dir(p.ax_marg_x.axes) if "line" in d]

for l in p.ax_marg_x.axes.lines:
    print(dir(l))

"""
Explanation: Finalize
End of explanation
"""


