5 Visualization Libraries for Python
By: Alan Jones
Tags: Statistics, Data Visualization, Finance, Matplotlib, Python

5 Visualization Libraries for Python

Example charts — image by author

Visualization is key to data communication. Whether you are trying to get something across to your boss, your client or your peers, a well-constructed chart or graph can often make your point more clearly than a table of numbers.

There are an awful lot of charting libraries for Python but I am going to take a quick look at just 5 of my favorites.

Matplotlib is the grandaddy of Python visualization libraries and is the basis for all of the ones I consider. But Matplotlib can be a little unwieldy and the other libraries have been built on top of it in order simplify things.

Each of the libraries have their strengths: Matplotlib is flexible and powerful, Pandas plotting is simple, Seaborn is good for statistical charting, Plotnine implements R’s ggplot and the Grammar of Graphics while MplFinance is specifically aimed at financial data.

I hope to give you a flavor of each of them.

But first we need some data to plot.

Gapminder data

Gapminder is an organization dedicated to dispelling public misconceptions about global trends and it’s website is well worth a visit. It uses a lot of data sets in its mission and we will use some of that data here. It is a table of the population, life expectancy and GDP per capita for each country from 1952 to 2007. This data is hosted by Jenny Bryan* on Github.

We set the url for the data source thus:

popDataURL = "https://raw.githubusercontent.com/jennybc/gapminder/master/inst/extdata/gapminder.tsv"

And then download the data into a Pandas Dataframe.

import pandas as pd

popData = pd.read_csv(popDataURL,

delimiter='\t',

dtype=({'year':int}))

popData['pop']=popData['pop']/1000000

I’ve divided the population count by 1 million to make the numbers a little clearer in the following charts. And I’ve changed to year column to be an integer, rather than a floating point number to make comparisons easier. The DataFrame looks like this:

The dataframe — image by author

There’s too much data here for my purposes so I have split it into subsets for the countries Spain, the UK, India and the US, like this:

SpainData = popData[popData['country']=='Spain']

UKData = popData[popData['country']=='United Kingdom']

IndiaData = popData[popData['country']=='India']

USData = popData[popData['country']=='United States']

We’ll use these subsets in the examples, below.

Matplotlib

If you can’t do what you want to do in Mathplotlib, then you can’t do it in any of the other libraries either. Matplotlib is the basis for each of the other libraries that I will discuss and so all of the examples below can be coded in Matplotlib — the other libraries, however, make life a little more convenient.

So, let’s start with a very simple Matplotlib example before moving on.

I’m using the UKData dataframe for this example and plotting the population growth over the last few decades. The code is straightforward: first we import the library (of course), next we specify the plot with x and y data, these being the columns 'year' and 'pop' from the dataframe (with the default parameters we get a line plot), then we set labels for the x and y axes, and finally, we call the method plt.show() which will display the graph below.

import matplotlib.pyplot as plt

plt.plot(UKData['year'],UKData['pop'])

plt.ylabel('Population in millions')

plt.xlabel('Year')

plt.show()

Example Matplotlib chart — image by author

In this example, Matplotlib expects to be given the data as array-like parameters — in this case we are supplying the year and pop data as Pandas columns (which are, in fact, Pandas series). We could also pass normal Python lists or Numpy arrays.

Here is another example: a scatter plot.

data = popData[popData['year']==2007] plt.scatter('country', 'gdpPercap', s='pop', data=data)

plt.xticks([])

plt.xlabel('Countries')

plt.ylabel('GDP Per Cap')

plt.show()

Example Matplotlib scatter chart — image by author

In this case only one parameter is required for the data — the data for the year 2007 — and we specify the Pandas dataframe columns for the x and y values. The s parameter is the size of the dots in the scatter diagram and it uses the value of the pop column, so the larger the population, the bigger the dot. I've also suppressed the ticks on the xaxis because there are so many country names they would be unreadable.

There is a great deal to Matplotlib but that’s where we will leave it in order to focus on the other libraries.

Pandas plot

Pandas plotting functions provide a set of basic plotting functions that are simple to program. With Pandas plot you can create line, bar and scatter charts, box plots and histograms and it is, of course, completely integrated with Pandas dataframes.

To create a plot from a dataframe we call the plot() method for that dataframe and supply the x and y data as columns from the dataframe.

Here is a line plot of the GDP per Capita for the US in one line of code.

USData.plot.bar(x='year',y='gdpPercap')

Note that we imported the Pandas library earlier when creating the dataframe.

Example Pandas charts— image by author

You can read more about Pandas plotting in a previous article:

Seaborn

Seaborn takes over where Pandas stops when it comes to statistical plots. Below is a plot of the Spanish population over time. It is not a simple line graph as we have seen in previous examples, it is Seaborn regplot which is a scatter diagram that incorporates a regression plot line.

The code below plots the data with a linear regression but, as you might be able to see, the data doesn’t really conform well to a straight line model.

import seaborn as sns

sns.regplot(x="year", y="pop", data=SpainData)

Example Seaborn regplot — image by author

I chose Spain to plot here, deliberately, as I happen to know that the population growth there is not growing linearly but has been gradually slowing over the past few years. So, a linear regression does not really fit the data. We can get a better idea of the way the data is changing by changing the order of the regression. It defaults to 1, a linear regression, but here we’ll change it to 2, which gives us a quadratic curve. I’ve also turned off the confidence interval, ci=None .

sns.regplot(x="year", y="pop", data=SpainData, order=2, ci=None)

Example Seaborn second order regplot — image by author

The quadratic curve doesn’t fit the data exactly but it gives a better impression of the slowing trend. Seaborn does not allow you to extract the model for prediction purposes; the regplot is for illustration purposes, only. Seaborn, themselves, suggest that if you want to do this, you should use the Statsmodels library for Python.

Seaborn includes several statistical chart types but for simple line and bar charts Pandas plot is probably more suitable.

Plotnine

Plotnine is an implementation of ggplot2 (the well-known graphics package for R) in Python. It takes a layered approach to the definition of a graph. In the example below the first line of code specifies the data source, the second, the type of graphic (a line chart) and the line size and color. The remaining lines add one of the built-in themes, modify that theme to change the size of the figure, and finally to set a title for the figure.

from plotnine import * (ggplot(IndiaData,aes('year','pop'))

+ geom_line(color='Blue',size=2)

+ theme_light()

+ theme(figure_size=(6,3))

+ ggtitle('India Population Growth')

)

Example Plotnine chart — image by author

This way of building a chart is quite satisfying and consistent across all chart types. Here’s another example that demonstrates how to build multiple facets into a single figure.

(ggplot(popData, aes('year','pop', fill='continent'))

+ geom_col(show_legend=False)

+ facet_wrap('continent', scales='free')

+ theme_light()

+ theme(panel_spacing=0.5, figure_size=(10,5))

)

Example facetted Plotnine chart — image by author

And finally a figure similar to the earlier example in Matplotlib but with the addition of color (representing the continent where the country is located). This gives us a rather messy figure, so I’ve chosen the void theme which basically removes all of the labels, ticks, etc. and then added a vertical label and a base line.

(ggplot(popData[popData['year']>=2007], aes('country','gdpPercap',size='pop',color='continent'))

+ geom_point()

+ theme_void()

+ theme(axis_line_x=element_line(), axis_title_y=element_text(rotation=90))

+ ggtitle('Countries')

)

Example scatter chart from Plotnine — image by author

The result is not perfect but playing around with the theme might give a better result.

Plotnine let’s you plot any number of chart types that are built up from standard components and might be a good choice if you are coming from an R background.

I’ve written more about Plotnine, here:

MplFinance

Mplfinance is specifically aimed at financial data and expects that data to be in a standard format. The number of chart it allows is relatively limited but then it is for a limited domain.

Here, I illustrate the most comprehensive chart. It is a combination of a set of box and whisker charts that show the price movement of a stock over a period, and a bar chart that shows the volume of trade over the same time.

We can’t use our Gapminder data for this library, so I’ve included the yfinance library that scrapes data from Yahoo Finance and fetches data for the Alphabet (Google’s parent company) for a day. The prices are given for each 30 minute period.

import yfinance as yp

import mplfinance as mpf



googl = yp.Ticker('GOOGL')

df = googl.history(period="1d", interval="30m")



mpf.plot(df,type='candle',mav=3,volume=True)

Example Mplfinance chart — image by author

Mplfinance is obviously a specialist product and not suitable for general use. But if it is financial data that you are interested in then, it’s a nice easy to use package.

Conclusion

Some of the reasons for choosing a charting library will be personal: if you like the Grammar of Graphics approach used by ggplot2 then Plotnine will be a good choice for you. For simple, straightforward graphics the plotting built in to Pandas is a good choice and simple to program. Seaborn, on the other hand, is less good for simple charts but gives you a lot of options for statistical charting. And Mplfinance is good at what it does but not suitable for general graphing.

Lastly, since all of the libraries I’ve looked at are based on Matplotlib, you could use Matplotlib to produce any of the charts that are supported by the other libraries. To do this, though, you will need to understand the complexities of Matplotlib and will need to do rather more programming.

Finally, you may be asking yourself why I have ignored Plotly, Bokeh or Altair. The main reason is that these are a different family of libraries that are more suitable for web-based applications, whereas the ones that I have looked at are more suitable for producing static documents.

Thanks for reading and I hope that this has whetted your appetite and you will want to explore the opportunities afforded by these libraries.

If you’d like to know when I publish other articles, please consider subscribing to my free and occasional newsletter here.

Code

You can find a Jupyter Notebook of all of the above code as well as code from my other articles on my Github page.

*Acknowledgements

We use the data from the Github repository maintained by Jennifer Bryan which can be found at https://github.com/jennybc/gapminder.

The original Gapminder data can also be found at http://www.gapminder.org/data/

Gapminder’s data is released under the Creative Commons Attribution 3.0 Unported license.