# Rotating Axis Labels in Matplotlib

## A look at all the ways you can rotate axis labels in Matplotlib

An entire post on how to rotate axis labels?? Yes indeed. After playing around with Matplotlib for some time, I could never remember how to rotate axis labels. Part of the reason it's hard to remember is that there are a plethora of ways to do it. In this post, we'll go through all the ways I've uncovered, with a few recommendations of which to use and when.

Just want the answers? Scroll to the very bottom.

## Get our data

Let's get some simple data to use for this example. We'll use the EPA's gas efficiency dataset.

```import matplotlib.pyplot as plt
import pandas as pd

fields = ['Manufacturer', 'Comb FE (Guide) - Conventional Fuel']
df = fuel_economy[fields].copy()
df.rename(columns={'Comb FE (Guide) - Conventional Fuel': 'Combined MPG'},
inplace=True)
# Get the top 10 manufacturers by their average MPG.
dfg = df.groupby('Manufacturer').mean().sort_values(
'Combined MPG', ascending=False)
df = dfg[:10].reset_index()
# Get the rest, we'll use these later for an example.
df2 = dfg[10:].reset_index()

df
```
Manufacturer Combined MPG
0 Honda 28.375000
1 Mitsubishi Motors Co 28.375000
2 MAZDA 28.285714
3 Kia 28.000000
4 Hyundai 26.672727
5 Toyota 26.663366
6 Subaru 25.954545
7 Volvo 25.050000
8 BMW 23.950820
9 Volkswagen Group of 23.746032

## Plot our data

Let's just create a simple bar chart to see what we're working with.

```fig, ax = plt.subplots()

ax.bar(df['Manufacturer'], df['Combined MPG'])
``` It's a mess! We need to rotate the axis labels...

Let's go through all the ways in which we can do this one by one.

### Option 1: `plt.xticks()`

`plt.xticks()` is probably the easiest way to rotate your labels. The only "issue" is that it's using the "stateful" API (not the Object-Oriented API); that sometimes doesn't matter but in general, it's recommended to use OO methods where you can. We'll show an example of why it might matter a bit later.

```fig, ax = plt.subplots()
ax.bar(df['Manufacturer'], df['Combined MPG'])

plt.xticks(rotation=30)
``` Looks better-ish but the alignment is funky. That's because, by default, Matplotlib aligns the center of the text to the tick. When you rotate the text, this no longer works so we need to change the alignment to right-aligned, like this:

```# `ha` is just shorthand for horizontalalignment, which can also be used.
plt.xticks(rotation=30, ha='right')
``` Bueno.

Note: Throughout this post we'll just focus on the x-axis but know you can do the exact same thing for the y-axis as well - just substitute `x` for `y` (e.g. `plt.xticks()` -> `plt.yticks()`)

### Where plt.xticks() doesn't really work

Let's say you now want to plot two bar charts in the same figure.

```fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))

ax1.bar(df['Manufacturer'], df['Combined MPG'])
ax1.set_ylim(0, 30)

ax2.bar(df2['Manufacturer'], df2['Combined MPG'])
ax2.set_ylim(0, 30)

# This only works for the last chart, even if we call it
# right after we create ax1!
plt.xticks(rotation=30, ha='right')
``` As you can see, only the last chart gets adjusted correctly. This is because the `plt` method finds the current `Axes` object (each bar chart here is a separate `Axes` object) and just modifies that one.

If you're just plotting one chart and doing EDA, this method is great. Otherwise, it's probably best to get used to using an OO method below.

## Option 2: `ax.set_ticklabels()`

Let's first try using the `Axes` method `set_ticklabels()`. This method takes the labels themselves as a required first parameter.

```ax.set_xticklabels(df['Manufacturer'], rotation=30, ha='right')
``` But what if you want don't want to manually give the labels? Why can't we just tell Matplotlib to re-use what it already has? You can - using `ax.get_xticklabels()` - but with some nuance.

```ax.set_xticklabels(ax.get_xticklabels(), rotation=30, ha='right')
``` What happened? Long story short, Matplotlib doesn't attach the labels to the chart until the very end, when the chart is drawn. So if you try to call `get_xticklabels()` before that, you get empty strings. A relatively hacky fix is just to draw the chart before calling the method.

```# Draw the chart so labels are actually attached to the Axes object.
plt.draw()

ax.set_xticklabels(ax.get_xticklabels(), rotation=30, ha='right')
``` Let's try adjusting both charts using this method.

```fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))

ax1.bar(df['Manufacturer'], df['Combined MPG'])
ax1.set_ylim(0, 30)

ax2.bar(df2['Manufacturer'], df2['Combined MPG'])
ax2.set_ylim(0, 30)

plt.draw()

ax1.set_xticklabels(ax1.get_xticklabels(), rotation=30, ha='right')
ax2.set_xticklabels(ax2.get_xticklabels(), rotation=30, ha='right')
``` Nice. This is a great method to know how to use but it's relatively verbose and comes with the caveat about needing to make sure the figure has been drawn before calling the `get` method.

### Option 3: `ax.get_xticklabels()`

In this method, you get a list of the labels, loop through each one, and set rotation and alignment for each. A few nice things about this method:

• It uses the OO API
• It's pretty intuitive. Get the labels. For each, set rotation and alignment.
• It doesn't actually touch the value of the labels themselves (like the previous method), it just adjusts the formatting. This means no weird caveats.
```for label in ax.get_xticklabels():
label.set_rotation(30)
label.set_ha('right')
```

Have multiple charts? Just concat the lists together and do it all in one loop.

```for label in ax1.get_xticklabels() + ax2.get_xticklabels():
label.set_rotation(30)
label.set_ha('right')
```

### Option 4: `ax.tick_params()`

This option is relatively simple but comes with a big drawback at the moment - you can't currently set alignment. However, there's an open feature request to allow it, so stay tuned!

```# No horizontal alignment option!
ax.tick_params(axis='x', labelrotation=30)

# Need this as well :/
plt.xticks(ha='right')
```

### Option 5: `plt.setp()`

`plt.setp` is a powerful method that allows you to set the properties of many (all?) Matplotlib objects. Here we use it by handing it the set of tick labels and setting the rotation and alignment properties for them.

```plt.setp(ax.get_xticklabels(), rotation=30, ha='right')
```

While this looks like it's not OO, it actually is since you're using `ax.get_xticklabels()`.

This works equally well when you have multiple charts:

```plt.setp(ax1.get_xticklabels() + ax2.get_xticklabels(), rotation=30, ha='right')
``` ## A Summary

As you can see, there are almost too many options when deciding how to do this. I think it's good to know all the methods honestly, but in the future, when label alignment is available, it will probably be "best" to use `ax.tick_params()`. But really, to each their own.

```# Option 1
plt.xticks(rotation=30, ha='right')

# Option 2
plt.draw()
ax.set_xticklabels(ax.get_xticklabels(), rotation=30, ha='right')

# Option 3
for label in ax.get_xticklabels():
label.set_rotation(30)
label.set_ha('right')

# Option 4
ax.tick_params(axis='x', labelrotation=30)
# Eventually, this shouldn't be needed and an `ha` argument should
# be available for the above.
plt.xticks(ha='right')

# Option 5
plt.setp(ax.get_xticklabels(), rotation=30, ha='right')
```

Have yet MORE ways to do this or have a strong recommendation of which to use? Let me know :)