Pie Chart and Persian Language in Python
When you want to plot a pie chart in Python using matplotlib library, or any other chart, one of the problems you’ll encounter is Persian language. In this post, I’ll explain how to solve this problem.
I didn’t understand what the problem is!
Here’s the problem:
If you ask me, this chart has three problems that we must fix:
- The labels are messed up.
- Numbers are in English.
- The default font is ugly.
To create the chart in the first place, I used this code:
import matplotlib.pyplot as pltlabels = [“گروه اول”, “گروه دوم”, “گروه سوم”, “گروه چهارم”]
sizes = [1, 2, 3, 4]plt.pie(sizes, labels=labels, autopct=’%1.1f%%’)
plt.savefig(“pie.png”, dpi=200)
How to fix it?
First, let’s fix the labels.
To do that, we need two Python libraries, arabic-reshaper and python-bidi. We can install both with pip:
pip install arabic-reshaper
pip install python-bidi
After that, we’ll change our code to the following:
import matplotlib.pyplot as plt
from bidi.algorithm import get_display
from arabic_reshaper import reshapelabels = [“گروه اول”, “گروه دوم”, “گروه سوم”, “گروه چهارم”]
persian_labels = [get_display(reshape(label)) for label in labels]
sizes = [1, 2, 3, 4]plt.pie(sizes, labels=persian_labels, autopct=’%1.1f%%’)
plt.savefig(“pie.png”, dpi=200)
And we can see that labels are shown correctly:
The second problem was that the numbers were written in English, and we wanted them to be in Persian. I didn’t know how to solve it, so I asked it on Stack Overflow and someone answered right away. To achieve what we want, we need to write a function to convert English numbers to Persian:
import matplotlib.pyplot as plt
from bidi.algorithm import get_display
from arabic_reshaper import reshapedef en_to_fa(num, formatter=’%1.1f%%’):
num_as_string = formatter % num
mapping = dict(list(zip(‘0123456789.%’, ‘۰۱۲۳۴۵۶۷۸۹.%’)))
return ‘’.join(mapping[digit] for digit in num_as_string)labels = [“گروه اول”, “گروه دوم”, “گروه سوم”, “گروه چهارم”]
persian_labels = [get_display(reshape(label)) for label in labels]
sizes = [1, 2, 3, 4]
plt.pie(sizes, labels=persian_labels, autopct=en_to_fa)
plt.savefig(“pie.png”, dpi=200)
If we look at the output, we can see that the numbers are in Persian:
Now, we need to find a beautiful font and use it to plot the chart. I chose Sahel, you can choose any other font.
To install the font, I cloned the repository into ~/.fonts and updated the font cache. Something like this:
git clone https://github.com/rastikerdar/sahel-font.git ~/.fonts/sahel
fc-cache -f -v | grep -i “sahel”
But, depending on your operating system, you can choose any other method to install the font. Just make sure that you have the font installed on your system.
Then, we can set it like this:
import matplotlib
font = {“family”: “Sahel”, “size”: 12}
matplotlib.rc(“font”, **font)
So our code becomes like this:
import matplotlib.pyplot as plt
from bidi.algorithm import get_display
from arabic_reshaper import reshape
import matplotlibdef en_to_fa(num, formatter=’%1.1f%%’):
num_as_string = formatter % num
mapping = dict(list(zip(‘0123456789.%’, ‘۰۱۲۳۴۵۶۷۸۹.%’)))
return ‘’.join(mapping[digit] for digit in num_as_string)font = {“family”: “Sahel”, “size”: 12}
matplotlib.rc(“font”, **font)labels = [“گروه اول”, “گروه دوم”, “گروه سوم”, “گروه چهارم”]
persian_labels = [get_display(reshape(label)) for label in labels]
sizes = [1, 2, 3, 4]plt.pie(sizes, labels=persian_labels, autopct=en_to_fa)
plt.savefig(“pie.png”, dpi=200)
Now if we run this code, we can see that all the mentioned problems are solved: