We previously have covered how to do some basic graphics using matplotlib. In this notebook we introduce a package called seaborn. seaborn builds on top of matplotlib by doing 2 things:
seaborn could be made by matplotlib, but you shouldn't have to worry about doing this)Before we start, make sure that you have seaborn installed. If not, then you can install it by
conda install seaborn
This notebook was created by Dave Backus, Chase Coleman, and Spencer Lyon for the NYU Stern course Data Bootcamp.
In [1]:
import matplotlib as mpl
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
import sys
%matplotlib inline
As per usual, we begin by listing the versions of each package that is used in this notebook.
In [2]:
# check versions (overkill, but why not?)
print('Python version:', sys.version)
print('Pandas version: ', pd.__version__)
print('Matplotlib version: ', mpl.__version__)
print('Seaborn version: ', sns.__version__)
There are some classical datasets that get used to demonstrate different types of plots. We will use several of them here.
In [3]:
tips = sns.load_dataset("tips")
ansc = sns.load_dataset("anscombe")
tita = sns.load_dataset("titanic")
Recall that in our previous notebook that we used plt.style.use to set styles. We will begin by setting the style to "classic"; this sets all of our default settings back to matplotlib's default values.
Below we plot open and closing prices on the top axis and the implied returns on the bottom axis.
In [28]:
plt.style.use("classic")
def plot_tips():
fig, ax = plt.subplots(2, figsize=(8, 6))
tips[tips["sex"] == "Male"].plot(x="total_bill", y="tip", ax=ax[0], kind="scatter",
color="blue")
tips[tips["sex"] == "Female"].plot(x="total_bill", y="tip", ax=ax[1], kind="scatter",
color="#F52887")
ax[0].set_xlim(0, 60)
ax[1].set_xlim(0, 60)
ax[0].set_ylim(0, 15)
ax[1].set_ylim(0, 15)
ax[0].set_title("Male Tips")
ax[1].set_title("Female Tips")
fig.tight_layout()
plot_tips()
# fig.savefig("/home/chase/Desktop/foo.png")
In [29]:
# sns.set() resets default seaborn settings
sns.set()
plot_tips()
What did you notice about the differences in the settings of the plot?
Which do you like better? We like the second better.
Investigate other styles and create the same plot as above using a style you like. You can choose from the list in the code below.
If you have additional time, visit the seaborn docs and try changing other default settings.
In [8]:
plt.style.available
Out[8]:
We could do the same for a different style (like ggplot)
In [24]:
sns.axes_style?
In [26]:
sns.set()
plot_tips()
Exercise: Find a style you like and recreate the plot above using that style.
In [ ]:
While having seaborn set sensible defaults is convenient, it isn't a particularly large innovation. We could choose sensible defaults and set them to be our default. The main benefit of seaborn is the types of graphs that it gives you access to -- All of which could be done in matplotlib, but, instead of 5 lines of code, it would require possibly hundreds of lines of code. Trust us... This is a good thing.
We don't have time to cover everything that can be done in seaborn, but we suggest having a look at the gallery of examples.
We will cover:
kdeplotjointplotviolinplotpairplot
In [ ]:
# Move back to seaborn defaults
sns.set()
In [30]:
fig, ax = plt.subplots()
ax.hist(tips["tip"], bins=25)
ax.set_title("Histogram of tips")
plt.show()
In [33]:
fig, ax = plt.subplots()
sns.kdeplot(tips["tip"], ax=ax)
ax.hist(tips["tip"], bins=25, alpha=0.25, normed=True, label="tip")
ax.legend()
fig.suptitle("Kernel Density with Histogram");
Exercise: Create your own kernel density plot using sns.kdeplot of "total_bill" from the tips dataframe
In [43]:
fig, ax = plt.subplots()
sns.kdeplot(tips.total_bill, ax=ax)
sns.kdeplot(tips.tip, ax=ax)
# ax.hist(tips.total_bill, alpha=0.3, normed=True)
Out[43]:
In [44]:
sns.jointplot(x="total_bill", y="tip", data=tips)
Out[44]:
We can also plot everything as a kernel density estimate -- Notice the main plot is now a contour map.
In [45]:
sns.jointplot(x="total_bill", y="tip", data=tips, kind="kde")
Out[45]:
Like an contour map
Exercise: Create your own jointplot. Feel free to choose your own x and y data (if you can't decide then use x=size and y=tip). Interpret the output of the plot.
In [51]:
sns.jointplot(x="size", y="tip", data=tips,
kind="kde")
Out[51]:
In [53]:
sns.jointplot(x="size", y="tip", data=tips)
Out[53]:
In [54]:
tita.head()
Out[54]:
In [55]:
tips.head()
Out[55]:
In [65]:
sns.violinplot?
In [67]:
sns.violinplot(x="fare", y="deck", hue="survived", split=True, data=tita)
# sns.swarmplot(x="class", y="age", hue="sex", data=tita)
Out[67]:
In [58]:
sns.boxplot(x="class", y="age", hue="sex", data=tita)
Out[58]:
Exercise: We might also want to look at the distribution of prices across ticket classes. Make a violin plot of the prices over the different ticket classes.
In [ ]:
In [ ]:
sns.swarmplot(x="sex", y="age", hue="survived", data=tita)
Pair plots show us two things. They show us the histograms of the variables along the diagonal and then the scatter plot of each pair of variables on the off diagonal pictures.
Why might this be useful? It allows us to look get an idea of the correlations across each pair of variables and gives us an idea of their relationships across the variables.
In [69]:
sns.pairplot(tips[["tip", "total_bill", "size"]], size=2.5)
Out[69]:
Below is the same plot, but slightly different. What is different?
In [70]:
sns.pairplot(tips[["tip", "total_bill", "size"]], size=2.5, diag_kind="kde")
Out[70]:
What's different about this plot?
Different colors for each company.
In [71]:
tips.head()
Out[71]:
In [73]:
sns.pairplot(tips[["tip", "total_bill", "size", "time"]], size=3.5,
hue="time", diag_kind="kde")
Out[73]:
We often want to think about running regressions of variables. A statistician named Francis Anscombe came up with four datasets that:
Below we show the scatter plot of the datasets to give you an idea of how different they are.
In [74]:
fig, ax = plt.subplots(2, 2, figsize=(8, 6))
ansc[ansc["dataset"] == "I"].plot.scatter(x="x", y="y", ax=ax[0, 0])
ansc[ansc["dataset"] == "II"].plot.scatter(x="x", y="y", ax=ax[0, 1])
ansc[ansc["dataset"] == "III"].plot.scatter(x="x", y="y", ax=ax[1, 0])
ansc[ansc["dataset"] == "IV"].plot.scatter(x="x", y="y", ax=ax[1, 1])
ax[0, 0].set_title("Dataset I")
ax[0, 1].set_title("Dataset II")
ax[1, 0].set_title("Dataset III")
ax[1, 1].set_title("Dataset IV")
fig.suptitle("Anscombe's Quartet")
Out[74]:
lmplot plots the data with the regression coefficient through it.
In [75]:
sns.lmplot(x="x", y="y", data=ansc, col="dataset", hue="dataset",
col_wrap=2, ci=None)
Out[75]:
In [76]:
sns.lmplot(x="total_bill", y="tip", data=tips, hue="sex")
Out[76]:
regplot also shows the regression line through data points
In [79]:
sns.regplot(x="total_bill", y="tip", data=tips)
Out[79]:
In [ ]: