I am attempting to change the format of my axis to be comma seperated in Matplotlib running under Python 2.7 but am unable to do so.
I suspect that I need to use a FuncFormatter but I am at a bit of a loss.
Can anyone help?
I am attempting to change the format of my axis to be comma seperated in Matplotlib running under Python 2.7 but am unable to do so.
I suspect that I need to use a FuncFormatter but I am at a bit of a loss.
Can anyone help?
Yes, you can use matplotlib.ticker.FuncFormatter
to do this.
Here is the example:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as tkr
def func(x, pos): # formatter function takes tick label and tick position
s = str(x)
ind = s.index('.')
return s[:ind] + ',' + s[ind+1:] # change dot to comma
y_format = tkr.FuncFormatter(func) # make formatter
x = np.linspace(0,10,501)
y = np.sin(x)
ax = plt.subplot(111)
ax.plot(x,y)
ax.yaxis.set_major_formatter(y_format) # set formatter to needed axis
plt.show()
This results in the following plot:
I know the question is old, but as I currently am searching for similar solutions, I decided to leave a comment for future reference if others need this.
For an alternative solution, use the locale
module and activate locale-formatting in matplotlib.
E.g., in major parts of Europe, comma is the desired separator. You can use
#Locale settings
import locale
locale.setlocale(locale.LC_ALL, "deu_deu")
import matplotlib as mpl
mpl.rcParams['axes.formatter.use_locale'] = True
#Generate sample plot
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0,10,501)
y = np.sin(x)
ax = plt.subplot(111)
ax.plot(x,y)
ax.yaxis.set_major_formatter(y_format) # set formatter to needed axis
plt.show()
to produce the same plot as in Andrey's solution, but you can be sure it behaves correctly also in corner-cases.
I think the question really refers to presenting say 300000 on the y-axis as 300,000.
To borrow from Andrey's answer, with a minor tweak,
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as tkr
def func(x, pos): # formatter function takes tick label and tick position
s = '{:0,d}'.format(int(x))
return s
y_format = tkr.FuncFormatter(func) # make formatter
x = np.linspace(0,10,501)
y = np.sin(x)
ax = plt.subplot(111)
ax.plot(x,y)
ax.yaxis.set_major_formatter(y_format) # set formatter to needed axis
plt.show()
I would like to expand on Thorsten Kranz answer, it seems that matplotlib (2.02) may have a bug, in that it does not use the thousand sep field of the locale to do the separation of thousands. This happens even if set_locale(True) is used.
Therefore if you set the locale to the UK locale, it should still separate the thousands by a comma but it does not. It does it for the German locale since the decimal point is used.
UK ('English_United Kingdom.1252') Locale:
{'currency_symbol': '\xa3',
'decimal_point': '.',
'frac_digits': 2,
'grouping': [3, 0],
'int_curr_symbol': 'GBP',
'int_frac_digits': 2,
'mon_decimal_point': '.',
'mon_grouping': [3, 0],
'mon_thousands_sep': ',',
'n_cs_precedes': 1,
'n_sep_by_space': 0,
'n_sign_posn': 3,
'negative_sign': '-',
'p_cs_precedes': 1,
'p_sep_by_space': 0,
'p_sign_posn': 3,
'positive_sign': '',
'thousands_sep': ','}
German ('German_Germany.1252') locale:
{'currency_symbol': '\x80',
'decimal_point': ',',
'frac_digits': 2,
'grouping': [3, 0],
'int_curr_symbol': 'EUR',
'int_frac_digits': 2,
'mon_decimal_point': ',',
'mon_grouping': [3, 0],
'mon_thousands_sep': '.',
'n_cs_precedes': 0,
'n_sep_by_space': 1,
'n_sign_posn': 1,
'negative_sign': '-',
'p_cs_precedes': 0,
'p_sep_by_space': 1,
'p_sign_posn': 1,
'positive_sign': '',
'thousands_sep': '.'}
Edit: Looking at the code in the Scalar formatter, Matplotlib does not use the grouping flag:
def pprint_val(self, x):
"""The last argument should be True"""
xp = (x - self.offset) / (10. ** self.orderOfMagnitude)
if np.absolute(xp) < 1e-8:
xp = 0
if self._useLocale:
return locale.format_string(self.format, (xp,)) # <-- there should be a True as the last argument to this method which sets to grouping to True
else:
return self.format % xp
I would like to post another solution here similar to the one presented by Thorsten Kranz.
Use the following first lines in your code:
import locale
locale.setlocale(locale.LC_ALL, "Portuguese_Brazil.1252")
import matplotlib as mpl
mpl.rcParams['axes.formatter.use_locale'] = True
This way, your code will be settled to Brazil standard text formating. I believe it could help you out.