230

I have a simple factorplot

import seaborn as sns
g = sns.factorplot("name", "miss_ratio", "policy", dodge=.2, 
    linestyles=["none", "none", "none", "none"], data=df[df["level"] == 2])

enter image description here

The problem is that the x labels all run together, making them unreadable. How do you rotate the text so that the labels are readable?

dan
  • 3,742
  • 6
  • 24
  • 38

10 Answers10

366

I had a problem with the answer by @mwaskorn, namely that

g.set_xticklabels(rotation=30)

fails, because this also requires the labels. A bit easier than the answer by @Aman is to just add

plt.xticks(rotation=45)
Gijs
  • 9,355
  • 4
  • 26
  • 35
216

You can rotate tick labels with the tick_params method on matplotlib Axes objects. To provide a specific example:

ax.tick_params(axis='x', rotation=90)
ecm
  • 2,379
  • 4
  • 19
  • 26
mwaskom
  • 41,082
  • 11
  • 113
  • 120
  • I get an error: IndexError: too many indices. My Code! g = sns.factorplot("month_date", "num_proposals", "account", sorted_data, col="account",col_wrap=3,sharex=False); g.set_xticklabels(rotation=30) – yoshiserry Dec 09 '14 at 02:29
  • what if I plot `DataFrame` with `sns.pairplot`? how to cast it to every graph? – soupault Sep 18 '15 at 15:49
  • ok, I came up with the following: `for ax in g.axes.flatten(): \n for t in ax.get_xticklabels(): \n t.set(rotation=30)` – soupault Sep 18 '15 at 16:05
  • 10
    @soupault - this worked for me, similar to what you came up with but perhaps a bit cleaner- for ax in g.axes.flatten(): ax.set_xticklabels(ax.get_xticklabels(),rotation=30) – odedbd Feb 07 '17 at 09:15
  • 9
    Use `ha="right"` to center align x-axis labels to their tick marks. i.e. `g.set_xticklabels([label1, label2], rotation=30, ha='right')` – Manavalan Gajapathy Sep 02 '17 at 03:32
  • 101
    similar to a couple comments above, this gave me an error until I changed `g.set_xticklabels(rotation=30)` to `g.set_xticklabels(g.get_xticklabels(), rotation=30)` thanks to this answer: https://stackoverflow.com/a/39689464/1870832 – Max Power Nov 02 '17 at 17:51
  • with updation in seaborn lib, this solution doesn't works. I have shared a relatively easier approach here : https://stackoverflow.com/a/52639848/8687063 – HimanshuGahlot Oct 04 '18 at 05:53
  • This worked for me. I am using `catplot`. ```p = sns.catplot("Assignee",col="Premium",data=df, kind='count') p.set_xticklabels(rotation=90)``` – Climbs_lika_Spyder Jan 28 '19 at 19:17
  • 1
    Some Seaborn plotting methods return a `FacetGrid` object, some return a Matplotlib `Axes` object. For the former, not setting the labels will work, for the latter, it won't. You can see which are `FacetGrid` objects by looking at the documentation: https://seaborn.pydata.org/api.html . For instance, if you use `g = sns.catplot()` this will work, but `sns.barplot()` will not because it returns an `Axes` object. – getup8 May 15 '19 at 06:58
  • In my case using `g.set_xticklabels(rotation=30)` on `FacetGrid` made tick labels disapper. Iterating over `g.fig.axes` as shown in [this answer](https://stackoverflow.com/a/43256409/7204581) worked. – Dmitriy Work May 07 '20 at 10:52
36

This is still a matplotlib object. Try this:

# <your code here>
locs, labels = plt.xticks()
plt.setp(labels, rotation=45)
Aman
  • 42,679
  • 7
  • 34
  • 37
17

Any seaborn plots suported by facetgrid won't work with (e.g. catplot)

g.set_xticklabels(rotation=30) 

however barplot, countplot, etc. will work as they are not supported by facetgrid. Below will work for them.

g.set_xticklabels(g.get_xticklabels(), rotation=30)

Also, in case you have 2 graphs overlayed on top of each other, try set_xticklabels on graph which supports it.

rishi jain
  • 1,288
  • 1
  • 18
  • 22
11

If anyone wonders how to this for clustermap CorrGrids (part of a given seaborn example):

import seaborn as sns
import matplotlib.pyplot as plt
sns.set(context="paper", font="monospace")

# Load the datset of correlations between cortical brain networks
df = sns.load_dataset("brain_networks", header=[0, 1, 2], index_col=0)
corrmat = df.corr()

# Set up the matplotlib figure
f, ax = plt.subplots(figsize=(12, 9))

# Draw the heatmap using seaborn
g=sns.clustermap(corrmat, vmax=.8, square=True)
rotation = 90 
for i, ax in enumerate(g.fig.axes):   ## getting all axes of the fig object
     ax.set_xticklabels(ax.get_xticklabels(), rotation = rotation)


g.fig.show()
user5875384
  • 139
  • 1
  • 7
11

You can also use plt.setp as follows:

import matplotlib.pyplot as plt
import seaborn as sns

plot=sns.barplot(data=df,  x=" ", y=" ")
plt.setp(plot.get_xticklabels(), rotation=90)

to rotate the labels 90 degrees.

Robvh
  • 969
  • 9
  • 21
6

For a seaborn.heatmap, you can rotate these using (based on @Aman's answer)

pandas_frame = pd.DataFrame(data, index=names, columns=names)
heatmap = seaborn.heatmap(pandas_frame)
loc, labels = plt.xticks()
heatmap.set_xticklabels(labels, rotation=45)
heatmap.set_yticklabels(labels[::-1], rotation=45) # reversed order for y
serv-inc
  • 32,612
  • 9
  • 143
  • 165
4

One can do this with matplotlib.pyplot.xticks

import matplotlib.pyplot as plt

plt.xticks(rotation = 'vertical')

# Or use degrees explicitly 

degrees = 70  # Adjust according to one's preferences/needs
plt.xticks(rotation=degrees)

Here one can see an example of how it works.

Gonçalo Peres
  • 6,010
  • 3
  • 36
  • 66
1

Use ax.tick_params(labelrotation=45). You can apply this to the axes figure from the plot without having to provide labels. This is an alternative to using the FacetGrid if that's not the path you want to take.

Stefan
  • 86
  • 2
0

If the labels have long names it may be hard to get it right. A solution that worked well for me using catplot was:

import matplotlib.pyplot as plt
fig = plt.gcf()
fig.autofmt_xdate()
Pau
  • 172
  • 1
  • 11