Lesser known Seaborn Tips and Tricks

Seaborn Trick Quick Gradient Palette
Seaborn Trick Quick Gradient Palette

Want to learn lesser known Seaborn tips and tricks from Micheal Waskom, the developer of Seaborn? Check out his periodical tweets since early this year. Stumbled upon this thread while searching for a specific Seaborn help and worked through some of the tips. Here are a few examples of lesser known Seaborn tips and tricks.

import seaborn as sns
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
sns.set_context("talk", font_scale=1.1)

1: Plotting inputs of different lengths with Seaborn

Typically, we deal with data in a dataframe, where all variables are of the same length. Sometimes you might come across inputs that are of different length as Pandas Series. You might see this often with time series data. Can you you Seaborn functions to plot the inputs with different lengths.

Here is an example of such input and making a plot using Seaborn.

First we create a dictionary with two Pandas Series of different lengths.

data = {"A": pd.Series(np.random.randn(200).cumsum(), 
                  pd.date_range("2020-01-01",periods=200)),
    "B": pd.Series(np.random.randn(100).cumsum(),
                  pd.date_range("2020-03-05",periods=100))
}

And then make time series plot using the dictionary as data with Seaborn’s relplot().

plt.figure(figsize=(16,8))
sns.relplot(data=data, kind="line", height=4, aspect=2.5)
plt.savefig("input_data_dict_varying_length_seaborn_trick_1.png",
                    format='png',dpi=150)

We get a nice time series plot.

Dict of Series with different lengths as input to Seaborn

Lesser Known Tip 2

Here is another example of similar flavor. This time we have two Pandas Series of differnt length one for x and the other y-axis. We can use this long forms of data with Seaborn functions without using data argument to make plot.

We make a line plot with two Pandas Series in this example.

x= pd.Series([0,1,2,3],[0,1,2,3], name="x")
x
0    0
1    1
2    2
3    3
Name: x, dtype: int64
y = pd.Series([1,2,3],[2,1,3],name="y")
2    1
1    2
3    3
Name: y, dtype: int64

The Series objects are joined together using their indexes while making the line plot using lineplot() function.

sns.lineplot(x=x, y=y, marker="o")
Seaborn plot without specifying data

3. Specify variables using keyword arguments in Seaborn

In the future Seaborn versions, it is going to be mandatory to specify variables using keyword arguments. Among other things, this helps us to pipe different functions together while making Seaborn plots starting with a data of interest. Here is an example of using pipe

sns.load_dataset("planets").head()

method	number	orbital_period	mass	distance	year
0	Radial Velocity	1	269.300	7.10	77.40	2006
1	Radial Velocity	1	874.774	2.21	56.95	2008
2	Radial Velocity	1	763.000	2.60	19.84	2011
3	Radial Velocity	1	326.030	19.40	110.62	2007
4	Radial Velocity	1	516.220	10.50	119.47	2009
(
    sns.load_dataset("planets")
    .query("method in ['Radial Velocity','Transit']")
    .pipe(sns.histplot, x="distance", hue="method", log_scale=True)
    .set(xlabel="Distance from star")
)
Seaborn plot with keyword arguments

4: Customize plots with set method

Michael Waskom highly recommends using set() function as in the previous examples. He says, set method is

the easiest way to customize plots while minimizing matplotlib boilerplate. Use it instead of Axes methods (ax.set_xlabel) or pyplot functions (plt.xlabel) to greatly simplify your code.

FacetGrid has a similar method, which broadcasts across axes:

planets = (
    sns.load_dataset("planets")
    .query("method in ['Radial Velocity','Transit']")
)
planets.head()

Here is an example of using set method to customize axis labels, axis limits and axis tick values.

g = sns.displot(data=planets,  
                x = "distance",
                col= "method",
                log_scale=True,
                height =4
               )
g.set(
    xlim=(0.5,2e4),
    xlabel = "Distance from star",
    yticks = [0,25,50,75,100,125]
)
plt.savefig("Customize_Seaborn_plot_with_set_trick_4.png",
                    format='png',dpi=150)
Customize Seaborn plot with set trick

5 Customize subplots in a FacetGrid with a loop

Using for loop can help customizing a plot made with Seaborn’s FacetGrid. In this example, we use Palmer Penguins data to make subplots using FaceGrid. And we use for loop to customize the title of each subplot. We use Seaborn plot’s axes_dict method to loop through and customize titles of each suboplot.

If that’s the case, the axes_dict attribute gives you a nice mapping from keys to Axes:

plt.figure(figsize=(12,6))
# displot returns an instance of class FacetGrid
g = sns.displot(penguins,
                x="bill_length_mm",
                row="sex",
                col="species",
                height=3.5)
counts = penguins.groupby(["sex","species"]).size()

# customize title
for(row_key, col_key), ax in g.axes_dict.items():
    ax.set_title(f"{row_key} {col_key}(N = {counts[(row_key, col_key)]})")

# save the plot
plt.savefig("Customize_FacetGrid_subplots_with_for_loops_trick_5.png",
                    format='png',dpi=150)
Customize FacetGrid subplots with for loops

6 hsitplot and diplot using categorical variables

Did you know that histplot and displot understand categorical variables? You can even use them to make plots that aren’t (currently) possible in countplot:

planets = sns.load_dataset("planets")
plt.figure(figsize=(9,6))
sns.displot(planets,
            y="method",
            height=4,
            aspect=2.25
           )
Seaborn displot Categorical Variable
plt.figure(figsize=(12,6))
sns.displot(planets,
            y="method",
            hue=pd.cut(planets.year, [1989,1994,1999,2004,2009,2014]),
            multiple="fill",
            palette="light:b",
            height=6,
            aspect=2.25
           ).set(xlabel="Proportion",
                ylabel="")
plt.savefig("Seaborn_displot_stacked_proportion_Seaborn_trick.png",
                    format='png',dpi=150)
Seaborn displot stacked proportion plot

7: Generate gradient palette from a starting color

We can use palette="light:{color}" to quickly create a gradient palette from a bases or seed color. Here are two examples of the scatter plot, but colored with two different palettes created with palette="light:{color}".

f, axs = plt.subplots(1,2, 
                    figsize=(10,6),
                    sharey=True, 
                    constrained_layout=True)
variables = dict(data=penguins,
                 x="bill_length_mm", 
                 y= "bill_depth_mm",
                 hue="body_mass_g")
sns.scatterplot(**variables, palette='dark:crimson', ax=axs[0])
sns.scatterplot(**variables, palette='blend:#226,#aae', ax=axs[1])
Seaborn Trick Quick Gradient Palette