I have a pie chart that I created with matplotlib
, and I've used Persian text for the labels:
In [1]: import matplotlib.pyplot as plt
In [2]: from bidi.algorithm import get_display
In [3]: from arabic_reshaper import reshape
In [4]: labels = ["گروه اول", "گروه دوم", "گروه سوم", "گروه چهارم"]
In [5]: persian_labels = [get_display(reshape(l)) for l in labels]
In [6]: sizes = [1, 2, 3, 4]
In [7]: plt.rcParams['font.family'] = 'Sahel'
In [8]: plt.pie(sizes, labels=persian_labels, autopct='%1.1f%%')
In [9]: plt.savefig("pie.png", dpi=200)
And the result is as I expected:
Now I want to change the percentage numbers to Persian as well. So instead of [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
, it must use [۰, ۱, ۲, ۳, ۴, ۵, ۶, ۷, ۸, ۹]
.
I can convert English digits to Persian quite easily with a function like this:
def en_to_fa(text):
import re
mapping = {
'0': '۰',
'1': '۱',
'2': '۲',
'3': '۳',
'4': '۴',
'5': '۵',
'6': '۶',
'7': '۷',
'8': '۸',
'9': '۹',
'.': '.',
}
pattern = "|".join(map(re.escape, mapping.keys()))
return re.sub(pattern, lambda m: mapping[m.group()], str(text))
But I don't know how I can apply this function to the percentages produced by matplotlib
. Is it even possible?
You can pass in a function for autopct
, not just a string formatter. So basically, you can just pass your en_to_fa
to autopct
, with a few minor modifications: you just need to first convert your number to a string with the appropriate number formatting, then do the language conversion. My machine is not setup for Farsi, but the following demonstrates the approach (mapping digits to the first 10 letters of the alphabet):
import matplotlib.pyplot as plt
def num_to_char(num, formatter='%1.1f%%'):
num_as_string = formatter % num
mapping = dict(list(zip('0123456789.%', 'abcdefghij.%')))
return ''.join(mapping[digit] for digit in num_as_string)
sizes = range(1, 5)
plt.pie(sizes, autopct=num_to_char)
plt.savefig("pie.png", dpi=200)