نمودار دایره‌ای و زبان فارسی در پایتون

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