Transform your graphs with Seaborn

Mallika Dey
May 28 · 5 min read

Creating graphs using a Python package offers great flexibility in terms of aesthetics. This is useful not just to make the graph look pretty, but also to provide relevant information in the most impactful manner possible.

While default functions available with any package can generate decent looking graphs, we can enhance them using the wide range of options and methods that the packages offer.

Here is a simple, step by step example of how you can use the Python Seaborn package to generate a bar chart and control some aesthetic aspects of the graph.

Step 1: Import the Seaborn package

Let us start by importing the required Python libraries. I assume that you already know how to install these packages and have done so. In case you want help click here.

import pandas as pdimport seaborn as sns

Step 2: Generate the data to be visualized

For purposes of this example, I create a Pandas data frame. You however, would be using the data required in your respective project or experiment. In my example, I generate two columns — the number of Starbucks outlets in a city, and the city name.

df = pd.DataFrame({'City':['Seoul','New York City','Shanghai','London','Chicago','Toronto','Mexico City','Seattle','Beijing','Las Vegas'], 
'Number of Starbucks': [284,277,256,202,164,160,160,142,137,136]})

Let us take a look at some rows in the data frame (to make sure data was generated properly):

df.head()

Step 3: Plot the chart using a color palette

Before we plot the chart, let us set the size of the chart — width of 10 units and height of 12 units

sns.set(rc={‘figure.figsize’:(10,12)})

I want this to be a horizontal bar chart with city names in the Y axis. Let’s plot the bar chart and name this object as ‘ax’. I use a color palette to represent the number with the intensity of the color.

You can find plenty of color palette options here.

ax = sns.barchart(y=”City”,x=’Number of Starbucks’, data=df,palette=”GnBu_d”)

Here is an example of the bar chart generated -

Step 4: Label the bars

Now, a trickier challenge. I wish to print the number of Starbucks as a label against each bar in the bar chart. I add the following snippet in order to do so.

initialx=0for p in ax.patches:ax.text(p.get_width(),initialx+p.get_height()/8,”{:1.0f}”.format(p.get_width()))initialx+=1

Here is my final output! It is much more useful were I to actually see the values that the different bars correspond to.

My staircase analogy

Here is an explanation of what happens:

  • We use the text method to print a text label in a particular position in the chart object.
  • In order to do this for each bar, we will create a loop and print the respective label at the end of each loop
  • We now need to determine two (actually three) attributes within each run of the loop : i. the value of the label (i.e. the number of outlets), and ii.The positional parameters (x and y) determining the position (just outside the bar) at which we should print this label
  • Every bar (and its corresponding background area) is known as a patch within the bar chart object. Therefore, we create a loop iterating through every patch within patches
  • The ax.text() method requires (for our purpose) these three parameters.
  1. x: x co-ordinate of the label. In this case, we need to display the label just after the end of each bar. Therefore, we provide the width of each bar as one parameter.
  2. y: y co-ordinate of the label. Similar to above, we would like to center the label within each bar. For that, we need to provide the height of each bar in this case.
  3. s: the text string to be printed. This should be the same as the value of the bar width in this case. This number is formatted as float with 0 digits of precision “{:1.0f}”
  • An important fact to remember — the x, y starts at 0,0 from the top left of the chart object, not the typical bottom left corner we are used to working with whenever we graph co-ordinates. Therefore, keeping this in mind, we create another variable initialx, which starts at 0, and then gets incremented by 1 in each step of the loop.
  • Let me provide you my staircase analogy: think of this whole process as descending a staircase. In each step (of the staircase, as well as the loop):
  1. We advance our feet to the edge of the stair (this is the width parameter)
  2. We write our ‘label’ just outside this step (imagine yourself twirling your foot for a second)
  3. We descend one step , and initialx gets incremented by 1,
  4. And then start the process all over again
  • One other point — the height and placement of the label would be the height of the bar chart and to adjust the position to show at the center, we start at 1/8th of the bar height to make sure the text is positioned in the middle of the bar.

Why 1/8th? I arrived at this after some trials, but then figured out that what actually happens is that the height of each bar is 1 inch (think of it as one unit) by default. Since, for visual purposes, there is some padding (or a gap) between different bars, I understood that the bar took up 80 % (or 0.8) of the bar height. The 1/8th of the bar height is a way to get the text to draw in such a way that it looks centered.

Note that there are other options, one can use the va / ha switches for vertical and horizontal alignment respectively. Read the documentation to learn more.

A bonus tip

By now (and if you have also read the documentation thoroughly), you might have also realized that Seaborn is based on the more widely used matplotlib package. Therefore, this same tip can also potentially be applied for a graph generated through matplotlib as well. As one should always do, make sure to read the documentation of both packages carefully to understand the differences.

In conclusion

This is just one of many ways in which you can control, tweak and manipulate the layout, elements and aesthetics of a chart generated within Seaborn. This tip in itself, is just the tip of the iceberg! I would love it if you all could play further and share your tips, tricks and experience forward! Happy analysis!