Pie Chart and Persian Language in Python

Amir A. Shabani
3 min readJun 15, 2020

--

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:

Pie chart with lots of problems
Pie chart with lots of problems.

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 reshape
labels = [“گروه اول”, “گروه دوم”, “گروه سوم”, “گروه چهارم”]
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:

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 reshape
def 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:

Numbers are now 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 matplotlib
def 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:

All problems are solved.

--

--