وقتی میخواین توی پایتون با کمک کتابخونهی matplotlib نمودار دایرهای، یا هر نمودار دیگه، رسم کنین، یکی از مشکلاتی که بهش برمیخورین زبان فارسی هست. توی این پست توضیح میدم که چه شکلی میشه این مشکل رو حل کرد.
مشکل اینجاست:
این نمودار از نظر من ۳ تا ایراد داره که باید برطرف کنیم:
برای درست کردن این نمودار از کد زیر استفاده کردم:
import matplotlib.pyplot as plt labels = ["گروه اول", "گروه دوم", "گروه سوم", "گروه چهارم"] sizes = [1, 2, 3, 4] plt.pie(sizes, labels=labels, autopct='%1.1f%%') plt.savefig("pie.png", dpi=200)
اول بیایم نمایش متن فارسی رو درست کنیم.
برای این کار به دو کتابخونهی arabic-reshaper و python-bidi نیاز داریم که هر دو رو میشه با همین اسامی به کمک pip نصب کرد. بعد کافیه این شکلی کدمون رو تغییر بدیم تا متن برچسبها درست بشه:
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)
میبینیم که این مشکل حل شد:
مشکل دوم این بود که درصدها به انگلیسی هست و ما میخوایم به فارسی باشه. نمیدونستم چه شکلی درستش کنم، توی Stack Overflow پرسیدم و دوست خوبی جواب داد. برای این کار یک تابع مینویسیم که اعداد انگلیسی رو به فارسی تبدیل کنه:
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)
اگر خروجی رو نگاه کنیم، میبینم حالا درصدها هم به فارسی هست:
حالا کافیه یک فونت فارسی قشنگ انتخاب کنیم و ازش توی نمودار استفاده کنیم. من فونت ساحل رو انتخاب کردم.
روش من برای نصب فونت این بود که به کمک دستور git clone محتوی repository رو داخل پوشهی fonts./~ ریختم و مخازن فونتهام رو آپدیت کردم. اینگونه:
git clone https://github.com/rastikerdar/sahel-font.git ~/.fonts/sahel fc-cache -f -v | grep -i "sahel"
شما با توجه به سیستمعاملتون از هر روش دیگهای که بخواین میتونین فونت رو نصب کنین. فقط کافیه مطمئن شین که فونت موردنظر روی سیستمتون نصب هست. بعد این شکلی میتونیم فونت رو تنظیم کنیم:
import matplotlib font = {"family": "Sahel", "size": 12} matplotlib.rc("font", **font)
در نهایت کدمون این میشه:
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)
اگر این کد رو اجرا کنیم میبینیم که همهی مشکلاتی که اول پست گفتیم حل شده: