Visualizing statistical plots with Seaborn | by Pranav Prathvikumar | Towards Data Science

This is the second article on visualization. You can read the first article where I talk about the basics of visualization using matplotlib here.
To recap, visualization allows us to see how the data is distributed, detect outliers and allows us to convey information more effectively. Which is why it is important for data scientists/analysts to know how to visualize and what are the options available to them. In this article I will be covering the usage of seaborn to visualize statistical plots.
To do this we will be making use of some of the datasets present within seaborn itself. This avoids us the trouble of having to download and import datasets. You can see the entire list of available datasets in this link.
We will start off by importing in the required libraries.
import matplotlib.pyplot as pltimport numpy as npimport seaborn as sns
Next lets load the ‘iris’ dataset and have a look at it.
iris = sns.load_dataset('iris')iris.head()
The Iris dataset contains the details of the flowers of three different species. As this dataset contains mainly numerical columns, we will be using this to explore visualizations that is suitable for numeric data.
So the first thing we can do is check the distribution of any one of the columns.
sns.set(style = 'darkgrid')sns.distplot(iris['sepal_length'])
The first line allows you to set the style of graph and the second line build a distribution plot. This ‘distplot’ command builds both a histogram and a KDE plot in the same graph.
But we have the option to customize the above graph or even separate them out.
sns.distplot(iris['sepal_length'], kde = False, bins = 30)
Here we have not only removed the KDE plot but were also able to add more bins into the plot to give a better idea of the distribution. This was achieved by the ‘kde’ and ‘bins’ parameters respectively.
And the KDE plot can be viewed separately with the help of the kdeplot command.
sns.kdeplot(iris['sepal_length'])
One way to make this plot better is to be able to show the presence of various data points to better understand the distribution of the data. Similar to histogram, but with small bins. This is done with the help of rug plots.
sns.kdeplot(iris['sepal_length'])sns.rugplot(iris['sepal_length'])
The above plot is known as rug plot and gives the distribution and density of the points.
Enough with visualizing only a single variable, what if you wanted to see how are two variables distributed with respect to each other.
Suppose we want to see the relation between the sepal and petal lengths of the flower. In this case we can use a jointplot to visualize it.
sns.jointplot(x = 'sepal_length', y = 'petal_length', data = iris)
The above plot not only gives the joint distribution, but also the individual distributions along the axis. From the above figure it seems that there is an almost linear relationship between the two, except at the lower end.
A cool feature in joinplot is the ability to fit a regression line for the data.
sns.jointplot(x = 'sepal_length', y = 'petal_length', data = iris, kind = 'reg')
By passing ‘reg’ to the kind parameter we are able to add a regression line and add kde plots to the histograms on the sides.
And now finally if we want to get a quick understanding of the entire data in one go then we can make use of the pairplot function.
sns.pairplot(iris)
The only parameter to be passed is the dataset name and it will automatically build the above plot for all the numerical columns present in the data. It plots every numerical column against every other numerical column and helps to get a quick overview of the data.
But the above plot still is missing a column, species, which happens to be a categorical column. Can we include information about the categorical column in this?
sns.pairplot(iris, hue = 'species', palette = 'magma')
The categorical data is represented in the form of the colour scheme in each one of the individual plots. The parameter ‘hue’ can be used to pass this information and ‘palette’ controls the colour scheme for the plots.
Now lets look at visualizing data that has more categorical columns in it. For this we will be using the ‘tips’ dataset. Let load it and have a look at it.
tips = sns.load_dataset('tips')tips.head()
The ‘tips’ dataset contains information regarding the tip paid by diners and their information such as bill amount, sex, time etc. Lets start off by looking at the distribution of the tip amounts and its relationship with the total bill amount.
sns.distplot(tips['tip'], kde = False, bins = 30)sns.jointplot(x = 'total_bill', y = 'tip', data = tips, kind = 'kde')
Now lets see if the tip given varies by day or not. This can be done with the help of a boxplot.
sns.boxplot(x = 'day',y = 'tip',  data = tips, palette = 'coolwarm')
Perhaps we want to compare by the sex of the diners. Like in the pairplot, we can specify that by the ‘hue’ parameter as well
sns.boxplot(x = 'day',y = 'tip',  data = tips, hue = 'sex', palette = 'coolwarm')
This creates two boxplots for each day on the basis of sex.
Another way of visualizing the above data in with the help of a violinplot.
sns.violinplot(x = 'day',y = 'tip', data = tips, palette = 'rainbow')
The violin plot can be thought of as a combination of the box and kde plots. The thick line in the center indicates the interquartile range with the kde of the tip on both sides.
Similar to the box plot, we can use ‘sex’ to create two violin plots side by side to compare. But we have a better option in this case.
sns.violinplot(x = 'day',y = 'tip',  data = tips, hue = 'sex', split = True, palette = 'rainbow')
By indicating ‘split’ as true we are able to create two different kdes on each side of the central line. This allows us to see the differences side by side and not crowd out the plot.
Previously we saw that we were able to use pair plots to have a look at the whole data and include one categorical column. But in this case we have multiple categorical columns. These can be integrated into the plots using Facet Grid.
g = sns.FacetGrid(tips, col="time",  row="smoker")
The above command created a 2 x 2 plots to account for the four possibilities across ‘time’ and ‘smoker’. That is one plot each for every combination of what time was the meal and whether the diner was a smoker or not.
To these plots we can add the numerical data and compare how they differ across the above two columns of ‘time’ and ‘smoker’.
g = sns.FacetGrid(tips, col="time",  row="smoker")g = g.map(plt.hist, "tip")
I added the distribution for tip values to see how they differ across ‘time’ and ‘smoker’. Above each plot is a line indicating which ‘time’ and ‘smoker’ value it corresponds to.
Similarly we can also plot two numerical columns and see the relationship between the two and across ‘time’ and ‘smoker’.
g = sns.FacetGrid(tips, col="time",  row="smoker",hue='sex')g = g.map(plt.scatter, "total_bill", "tip").add_legend()
The above plot shows the relationship between the tip and bill amounts and across ‘time’ and ‘smoker’. In addition, the colour scheme of each plot shows the sex as well. By using facet grids we can create plots involving multiple numerical and categorical columns.
Lastly I want to cover heatmaps and clustermaps.
In the below figure I am using a heatmap to show the correlation of all the numerical values against each other.
sns.heatmap(tips.corr(), cmap = 'coolwarm', annot = True)
The command ‘tips.corr’ gives the correlation between all the numerical variables. By indicating ‘annot’ as true we can have the correlation values on the figure as well.
For building the clustermap I first pivoted the tips dataset to get the value of tip amount across day and sex.
tip_pivot = tips.pivot_table(values='tip',index='day',columns='sex')
Using this I can create a clustermap on the value of tips and how close are the days to each other.
sns.clustermap(tip_pivot, cmap = 'coolwarm', standard_scale = 1)
As there are only two sexes, there is not much to see in terms of clustering there. But in the case of days we see that Saturday and Thursday are grouped together indicating the similarity in the tip amounts given on those days.
The above clustermap is pretty simple as there are not many categories on each axis. A clustermap can really shine when there are multiple categories allowing to discern similarities and patterns.
This covers some of the statistical plots and visualisations that can be built using Seaborn. Hope you found it useful.
You can connect with me on LinkedIn as well.