# Advanced plots in Matplotlib - Part 2

This article comes as a second part in the Advanced Plots in Matplotlib series. In Part 1, we learnt how to use plots like Span selector, Broken Horizontal Bar plot and the table function in our visualisation work. We also learnt how to watermark images and add a twist to the plots in Matplotlib by using the XKCD theme. In part 2, we shall go over some of the other interesting capabilities of Matplotlib in action and use it to jazz up our existing plots.

## 1. Event Plots

Event plots come in handy when one wants to plot identical parallel lines at pre-defined positions. Such plots are commonly used in neuroscience to display the spiking activity of the neurons over time, where it is frequently referred to as a spike raster or simply a raster plot. However, there are other uses for such kind of plots too. Here is an excerpt from the event plot documentation :

It is useful in any situation where you wish to show the timing or position of multiple sets of discrete events, such as the arrival times of people to a business on each day of the month or the date of hurricanes each year of the last century.

Let’s look at an `eventplot` showing sequences of events with various line properties. The plot is shown in both horizontal and vertical orientations. The plot has been adapted from official Matplotlib’s Eventplot documentation.

```import matplotlib.pyplot as plt
import numpy as np

# Creating rows of random data with 50 data points
data = np.random.random([8, 50])
colorsCodes = ['C{}'.format(i) for i in range(8)]

# Set spike colors for each neuron
lineSize = [.2, 0.3, 0.2, 0.8, 0.5, 0.6, 0.7, 0.9]
fig, ax = plt.subplots(1, 2)

# Creating a horizontal plot

ax.eventplot(data, color=colorsCodes, linelengths = lineSize)
ax.set_title('Spike Raster plot- Horizontal')
ax.set(xlabel="Spike",ylabel="Neuron")
ax.eventplot(data, color=colorsCodes, linelengths = lineSize, orientation='Vertical')
ax.set_title('Spike Raster plot- Vertical')
ax.set(ylabel="Spike",xlabel="Neuron")
plt.tight_layout()
plt.savefig('event.png')
plt.show()

```

## 2. Timelines

Did you know that it is possible to create a simple timeline using Matplotlib alone? Well yes. This is because technically, timelines are simply collections of dates and text which can be obtained with simple variations in a stem plot. You can read more about it here.

Here is a timeline showing the Android version history using the code provided in the official documentation.

```import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates
from datetime import datetime

names = ['Gingerbread', 'Ice Cream Sandwich', 'Jelly Bean', 'KitKat', 'Lollipop', 'Marshmallow',
'Nougat', 'Oreo', 'Pie', '10', '11']
dates = ['2011-02-9', '2011-10-19', '2012-11-13', '2013-10-31',
'2014-11-3', '2015-10-5', '2016-08-22', '2017-08-21',
'2018-08-06', '2019-09-3', '2020-02-19']

# Convert date strings (e.g. 2014-10-18) to datetime
dates = [datetime.strptime(d, "%Y-%m-%d") for d in dates]

# Choose some nice levels
levels = np.tile([-5, 5, -3, 3, -1, 1],
int(np.ceil(len(dates)/6)))[:len(dates)]

# Create figure and plot a stem plot with the date
fig, ax = plt.subplots(figsize=(8.8, 4), constrained_layout=True)
ax.set(title="Android version history")
markerline, stemline, baseline = ax.stem(dates, levels,
linefmt="C3-", basefmt="k-",
use_line_collection=True)
plt.setp(markerline, mec="k", mfc="w", zorder=3)

# Shift the markers to the baseline by replacing the y-data by zeros.
markerline.set_ydata(np.zeros(len(dates)))

# annotate lines
vert = np.array(['top', 'bottom'])[(levels > 0).astype(int)]
for d, l, r, va in zip(dates, levels, names, vert):
ax.annotate(r, xy=(d, l), xytext=(-3, np.sign(l)*3),
textcoords="offset points", va=va, ha="right")

# format xaxis with 10 month intervals
ax.get_xaxis().set_major_locator(mdates.MonthLocator(interval=10))
ax.get_xaxis().set_major_formatter(mdates.DateFormatter("%b %Y"))
plt.setp(ax.get_xticklabels(), rotation=30, ha="right")

# remove y axis and spines
ax.get_yaxis().set_visible(False)
for spine in ["left", "top", "right"]:
ax.spines[spine].set_visible(False)
ax.margins(y=0.1)
plt.show()
```

## 3. Bar of Pie

Have you ever wanted to further drill down into a pie chart? Maybe you wanted to expand one of its slices and ‘explode’ it into a bar chart? Matplotlib makes it possible through a ‘Bar of Pie’ functionality. It uses a ConnectionPatch that connects two points (possibly in different axes).

The idea is simple. Create a pie chart and its corresponding bar chart as subplots and then use a connection patch to draw lines between the two subplots.

Here is an example from the official documentation.

## 4. Style sheets reference

While creating plots in matplotlib, a lot of times, we tend to stick with the default style. However, Matplotlib offers a bunch of great style options which make even the mundane visualisations really stand out. To list all of the styles, enter the following line of code.

```print(plt.style.available)

Output: ['Solarize_Light2', '_classic_test_patch', 'bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn', 'seaborn-bright', 'seaborn-colorblind', 'seaborn-dark', 'seaborn-dark-palette', 'seaborn-darkgrid', 'seaborn-deep', 'seaborn-muted', 'seaborn-notebook', 'seaborn-paper', 'seaborn-pastel', 'seaborn-poster', 'seaborn-talk', 'seaborn-ticks', 'seaborn-white', 'seaborn-whitegrid', 'tableau-colorblind10']
```

Here I’ll showcase some of the popular ones. In case you are interested, you can find the complete list here. Let’s create a basic line plot and then apply some of the different styles. When no style has been specified, matplotlib will use the default style:

```import matplotlib.pyplot as plt

plt.plot([1, 3, 9, 5, 2, 1, 1], marker='o')
plt.plot([4, 5, 5, 7, 9, 8, 6], marker='v')
plt.plot([2, 3, 4, 3, 4, 5, 3], marker='s')
plt.show()

```

```plt.style.use('stylename') #Replace 'stylename' with the desired style
```

### Commonly used styles:

Let’s see some of the commonly used styles:

### Classic

Classic is Matplotlib’s older style.

```import matplotlib.pyplot as plt

plt.style.use("classic")

plt.plot([1, 3, 9, 5, 2, 1, 1], marker='o')
plt.plot([4, 5, 5, 7, 9, 8, 6], marker='v')
plt.plot([2, 3, 4, 3, 4, 5, 3], marker='s')
plt.show()
```

### ggplot

This style emulates the aesthetics of ggplot (a popular plotting package for R)

```import matplotlib.pyplot as plt

plt.style.use("ggplot")

plt.plot([1, 3, 9, 5, 2, 1, 1], marker='o')
plt.plot([4, 5, 5, 7, 9, 8, 6], marker='v')
plt.plot([2, 3, 4, 3, 4, 5, 3], marker='s')

plt.show()

```

### FiveThirtyEight

This shows an example of the “fivethirtyeight” styling, which tries to replicate the styles from fivethirtyeight.com.

```import matplotlib.pyplot as plt

plt.style.use("fivethirtyeight")

plt.plot([1, 3, 9, 5, 2, 1, 1], marker='o')
plt.plot([4, 5, 5, 7, 9, 8, 6], marker='v')
plt.plot([2, 3, 4, 3, 4, 5, 3], marker='s')

plt.show()
```

### Bayesian Methods for Hackers — bmh

This example demonstrates the style used in the Bayesian Methods for Hackers online book.

```import matplotlib.pyplot as plt

plt.style.use("bmh")

plt.plot([1, 3, 9, 5, 2, 1, 1], marker='o')
plt.plot([4, 5, 5, 7, 9, 8, 6], marker='v')
plt.plot([2, 3, 4, 3, 4, 5, 3], marker='s')

plt.show()
```

### Cyberpunk style

Recently, I stumbled upon a package named mplcyberpunk, which is a Python package on top of `matplotlib` to create ‘cyberpunk’ style plots with just three additional lines of code. How cool is that 🤘?

To use the cyberpunk style; you will need to install and import the library first.

```!pip install mplcyberpunk

import matplotlib.pyplot as plt
import mplcyberpunk

plt.style.use("cyberpunk")

plt.plot([1, 3, 9, 5, 2, 1, 1], marker='o')
plt.plot([4, 5, 5, 7, 9, 8, 6], marker='v')
plt.plot([2, 3, 4, 3, 4, 5, 3], marker='s')

plt.show()
```

## 5. adjustText — automatic label placement for `matplotlib`

Lastly, let’s look at a useful Third-party package in Matplotlib. As the name suggests, third party packages build and extend the existing Matplotlib capabilities. An important point to keep in mind is that these packages are not included in Matplotlib by default and have to be installed separately.

A lot of times, we struggle to adjust the text positions in a graph. This happens when there are multiple labels, and these labels start overlapping. adjustText is a pretty useful library for such situations as it automates the placement of labels.

#### Installation

As already stated, you’ll need to install the library first, which can be done by either of the three ways:

```pip install adjustText # pip install
or
conda install -c conda-forge adjusttext # conda
or

#### Usage

Let’s look at a basic example from adjustText‘s documentation itself to highlight the power of adjustText. The figures on the left shows the overlapping labels while the figure on the right shows the auto adjusted labels obtained after calling the `adjust_text` function.