Professional visualizations with Matplotlib and Seaborn.

November 28, 2021

From the archive. I wrote this in 2021 for an earlier version of this site. It is kept as it was then, apart from the layout and a few links.

Summary

When it comes to presenting data it is vital that your visual content is of great quality. It is possible to create stunning visuals with Python, but the code can be verbose and quite complex.

In this post I will show you an example that you can easily re-use for your own purposes.

Why use Python for visualizations?

There are plenty of great data tools available which make it easy to create decent looking visualizations with just a few mouse clicks. Tableau, PowerBI, but also Excel are commonly referred as great tools for the job.

However, since I use Python for most of my data exploration and analysis, for me it feels more efficient to also create my visualizations in Python. Furthermore, in the long run it will strengthen my in-depth knowledge and muscle memory of 1 tool (Python), instead of average knowledge in multiple tools.

Another important consideration is reproducibility. Personally I think it is one of the most important aspects of working with data, since it allows your colleague or team member to exactly replicate your analysis / visualization. Creating your visualizations with code instead of by mouse clicks makes this possible.

What options do we have in Python?

Given that we are going to use Python, there is a clear choice when it comes to visualization: Matplotlib. This is a very comprehensive, flexible, and well-documented library for creating static, animated, and interactive visualizations.

With flexible I mean that you can manipulate almost every single detail of any visualization. However great that may sound, this comes with a price tag. Matplotlib is sometimes referred to as having low-level syntax (low abstraction), which means you have to write a lot of code to tell Matplotlib explicitly what you want it to do. To cope with this challenge, other libraries have emerged which are based on Matplotlib, but have a higher level of abstraction.

Seaborn is probably the most popular example of such a library, and it allows you to create beatiful graphs with less code.

Walk the walk.

Instead of talking about low-level and high-level syntax, let’s create a simple boxplot for multiple groups with Seaborn and Matplotlib, and compare the differences in code and preparation. We will use one of the example datasets that are part of the standard library of Seaborn.

import matplotlib.pyplot as plt
import seaborn as sns

tips = sns.load_dataset("tips")

sns.set_style('ticks')
sns.set_context('poster')
sns.boxplot(x="day", y="total_bill", data=tips)

Boxplot with multiple groups created with Seaborn.

With just 3 lines of code we already have a reasonable looking visualization:

The first 2 list items are caused by the structure of the input data, which is a Pandas dataframe. Seaborn works well with these dataframes and recognizes the column names and the data type of each column we try to visualize, and acts accordingly.

The last 2 list items are caused by both sns.set_* lines. Seaborn has several of these functions which manipulate the underlying set of visualization rules. This is very convenient since it only takes 1 line of code to adjust a number of rules. Now that we have seen and discussed the Seaborn visualization, let’s move on to Matplotlib.

Before we can visualize the boxplot, we need to change the input data. The boxplot function of Matplotlib cannot handle arrays of different length in one dataframe, so we need to create a list of arrays based on each day. We also include the same sns.set_* lines of code to give the visualization a head start.

sns.set_style('ticks')
sns.set_context('poster')

input_data = []

for day in tips['day'].unique():
    input_data.append(tips.loc[tips['day'] == day, 'total_bill'].values)

fig, ax = plt.subplots()

ax.boxplot(input_data)

Boxplot with multiple groups created with Matplotlib.

With more than 3 lines of code, this visualization actually looks far from decent:

By having to use a list of arrays instead of a dataframe with metadata, the meaning of the data is mostly gone, which makes it impossible to interpret the visualization. With regard to the code, we also first have to initialize a fig and ax variable in order to assign the visualization to the axis (ax). This visualization would need a lot of work (code) before it resembles the Seaborn boxplot.

Although this is just a single example, it should give you an idea of the added value of Seaborn when you want to quickly create decent looking visualizations. In the next section, we are going to combine Matplotlib and Seaborn to try to go beyond decent and create a professional-looking visualization.

A professional visualization.

Although the Seaborn visualization already looks decent, it lacks some critical aspects. An important characteristic of a professional visualization is that it should be self-explanatory and contain at least:

Regardless of whether you are using Matplotlib or Seaborn, you will have to write additional code for these adjustments. Since Seaborn is build on top of Matplotlib, you can actually combine code from both libraries to create the professional visualization we are looking for.

from matplotlib.ticker import FormatStrFormatter

import numpy as np

sns.set_style('ticks')
sns.set_context('poster')

fig, ax = plt.subplots(figsize=(24, 12))

sns.boxplot(x="day", y="total_bill", data=tips)

ax.set_title("The average bill is higher during the weekend in comparison \n to Thursday and Friday.",
              pad=30, size=32, weight='heavy')

ax.set_xlabel('Day of the week', size=24)

ax.set_ylabel('Total bill', size=24)
ax.set_ylim(0, 60)
ax.set_yticks(np.arange(0, 65, 10))
ax.yaxis.set_major_formatter(FormatStrFormatter('$%1.0f'))

fig.text(s="The data originates from the Seaborn 'bills' example dataset (n=244).",
          x=0.1, y=0.03, size=18, style='italic')

fig.savefig('professional_visualization.jpg')

Professional looking boxplot created with Matplotlib and Seaborn.

With a few extra lines of code we added the requirements from the list and we made - in my opinion - a visualization worth using in any presentation or work-related report. Due to the high quality of these two libraries most of the code explains itself, but if you are unsure what a certain line of code does I encourage you to simply try it out or search the official documentation.

Final thoughts.

Seaborn has many out-of-the-box visualizations, so most of the time you only have to change the sns.boxplot() line to change the type of visualization you want to use. In some cases you may need to add ax=ax but this is usually well documented.

If you find yourself copy-pasting large amounts of code on a regular basis, an interesting next step might be to create your own style and context. Have a look at the sns.set_context and sns.plotting_context() for more information.

No sponsored or affiliate links. If something here is new to you, the link is an easy way in.