How to format axis tick labels from number to thousands or Millions (125,436 to 125.4K)
Asked Answered
K

6

47
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import seaborn as sns
import pandas as pd
sns.set(style="darkgrid")    
fig, ax = plt.subplots(figsize=(8, 5))    
palette = sns.color_palette("bright", 6)
g = sns.scatterplot(ax=ax, x="Area", y="Rent/Sqft", hue="Region", marker='o', data=df, s=100, palette= palette)
g.legend(bbox_to_anchor=(1, 1), ncol=1)
g.set(xlim = (50000,250000))

enter image description here

How can I can change the axis format from a number to custom format? For example, 125000 to 125.00K

Kindless answered 12/12, 2018 at 16:25 Comment(0)
S
59

IIUC you can format the xticks and set these:

In[60]:
#generate some psuedo data
df = pd.DataFrame({'num':[50000, 75000, 100000, 125000], 'Rent/Sqft':np.random.randn(4), 'Region':list('abcd')})
df

Out[60]: 
      num  Rent/Sqft Region
0   50000   0.109196      a
1   75000   0.566553      b
2  100000  -0.274064      c
3  125000  -0.636492      d

In[61]:
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import seaborn as sns
import pandas as pd
sns.set(style="darkgrid")    
fig, ax = plt.subplots(figsize=(8, 5))    
palette = sns.color_palette("bright", 4)
g = sns.scatterplot(ax=ax, x="num", y="Rent/Sqft", hue="Region", marker='o', data=df, s=100, palette= palette)
g.legend(bbox_to_anchor=(1, 1), ncol=1)
g.set(xlim = (50000,250000))
xlabels = ['{:,.2f}'.format(x) + 'K' for x in g.get_xticks()/1000]
g.set_xticklabels(xlabels)

Out[61]: 

enter image description here

The key bit here is this line:

xlabels = ['{:,.2f}'.format(x) + 'K' for x in g.get_xticks()/1000]
g.set_xticklabels(xlabels)

So this divides all the ticks by 1000 and then formats them and sets the xtick labels

UPDATE Thanks to @ScottBoston who has suggested a better method:

ax.xaxis.set_major_formatter(ticker.FuncFormatter(lambda x, pos: '{:,.2f}'.format(x/1000) + 'K'))

see the docs

Selfhelp answered 12/12, 2018 at 16:48 Comment(2)
You can also, try using ticker.FuncFormatter: ax.xaxis.set_major_formatter(ticker.FuncFormatter(lambda x, pos: '{:,.2f}'.format(x/1000) + 'K'))Mitchmitchael
Note that the ax.xaxis.set_major_formatter approach doesn't work if you your figure is a FacetGrid.Bab
M
41

The canonical way of formatting the tick labels in the standard units is to use an EngFormatter. There is also an example in the matplotlib docs.

Also see Tick locating and formatting

Here it might look as follows.

import numpy as np; np.random.seed(42)
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import seaborn as sns
import pandas as pd

df = pd.DataFrame({"xaxs" : np.random.randint(50000,250000, size=20),
                   "yaxs" : np.random.randint(7,15, size=20),
                   "col"  : np.random.choice(list("ABC"), size=20)})
    
fig, ax = plt.subplots(figsize=(8, 5))    
palette = sns.color_palette("bright", 6)
sns.scatterplot(ax=ax, x="xaxs", y="yaxs", hue="col", data=df, 
                marker='o', s=100, palette="magma")
ax.legend(bbox_to_anchor=(1, 1), ncol=1)
ax.set(xlim = (50000,250000))

ax.xaxis.set_major_formatter(ticker.EngFormatter())

plt.show()

enter image description here

Midlothian answered 12/12, 2018 at 18:28 Comment(1)
FYI: for anyone running this code with matplotlib 3.3.1 and seaborn 0.10.1, you'll get ValueError: zero-size array to reduction operation minimum which has no identity. To resolve that issue, change hue='col' to hue=df.col.tolist(). This is a known bug.Reft
N
11

Using Seaborn without importing matplotlib:

import seaborn as sns
sns.set()

chart = sns.relplot(x="x_val", y="y_val", kind="line", data=my_data)

ticks = chart.axes[0][0].get_xticks()

xlabels = ['$' + '{:,.0f}'.format(x) for x in ticks]

chart.set_xticklabels(xlabels)
chart.fig

Thank you to EdChum's answer above for getting me 90% there.

Nicosia answered 14/5, 2019 at 8:39 Comment(1)
If you want to use formatters (matplotlib.org/stable/api/ticker_api.html) and not import matplotlib, you can use: chart.ax.xaxis.set_major_formatter(formatter)Loosen
A
6

Here's how I'm solving this: (similar to ScottBoston)

from matplotlib.ticker import FuncFormatter

f = lambda x, pos: f'{x/10**3:,.0f}K'
ax.xaxis.set_major_formatter(FuncFormatter(f))
Allow answered 3/3, 2020 at 6:20 Comment(0)
M
1

We could used the APIs: ax.get_xticklabels() , get_text() and ax.set_xticklabels do it.

e.g,

xlabels = ['{:.2f}k'.format(float(x.get_text().replace('−', '-')))/1000 for x in g.get_xticklabels()]
g.set_xticklabels(xlabels)
Margarethe answered 25/10, 2021 at 1:47 Comment(1)
Code-only answers are strongly discouraged. Please include an explanation of how and why this solves the problem. This will help future readers to better understand your solution. - From ReviewBrunette
C
0

Here's a clean example for set_major_formatter

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as pltticker
import seaborn as sns
sns.set_style(style="whitegrid")

dfp = pd.DataFrame({'symbol':[f"{n:c}" for n in range(97, 97+10)],'val':range(10)})
dfp['val']=dfp['val']/100

g = sns.barplot(data=dfp, y="val", x="symbol", color='b')
g.yaxis.set_major_formatter(pltticker.FuncFormatter(lambda x, pos: f"{x:+.1%}"))

Carleencarlen answered 7/4 at 16:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.