آموزش هوش مصنوعی

نمودار میله‌ای یا دایره‌ای؟ نمایش تعداد و نسبت در گزارش داده با Matplotlib

مقدماتی مطالعه در ۹ دقیقه بخش ۱۷ از ۱۷ در مبانی هوش مصنوعی و علم داده
mahdyar
نمودار میله‌ای یا دایره‌ای؟ نمایش تعداد و نسبت در گزارش داده با Matplotlib

نمودار میله‌ای رایج‌ترین نمودار در گزارش‌های داده است و دلیل خوبی هم دارد. چشم انسان طول را خیلی دقیق‌تر از زاویه و مساحت مقایسه می‌کند. با این حال، بسیاری از گزارش‌ها هنوز پر از نمودار دایره‌ای با ده برش هم‌رنگ است که هیچ‌کس نمی‌تواند درست بخواندشان. انتخاب نمودار یک تصمیم ارتباطی است، نه سلیقه‌ای.

در قسمت قبل با تحلیل اکتشافی، داده را شناختیم. حالا وقت نشان دادن یافته‌هاست. این قسمت اول از سه قسمت مصورسازی است و روی تعداد و نسبت تمرکز دارد. با یک مجموعه‌داده از پرندگان ایالت مینه‌سوتا کار می‌کنیم و با کتابخانه‌ی Matplotlib نمودار می‌سازیم.

کدام نمودار برای کدام سؤال؟

پیش از رسم هر نمودار، بپرسید چه داستانی می‌خواهید بگویید. نوع داده و سؤال شما نوع نمودار را تعیین می‌کند. جدول زیر راهنمای سریع انتخاب است.

سؤال شمانمودار مناسب
روند در طول زمانخطی، ستونی
مقایسه‌ی مقدار چند دستهمیله‌ای، ستونی
سهم بخش‌ها از کلدایره‌ای، دونات، وافل، میله‌ای انباشته
توزیع یک متغیرهیستوگرام، جعبه‌نمودار
رابطه‌ی دو متغیرپراکنش، حبابی

Matplotlib و داده‌ی پرندگان

Matplotlib پایه‌ی بیشتر کتابخانه‌های نمودار در پایتون است. کتابخانه‌هایی مثل seaborn روی آن ساخته شده‌اند. داده‌ی این قسمت اطلاعات حدود چهارصد گونه پرنده را دارد؛ نام، دسته، راسته، وضعیت حفاظت و اندازه‌هایی مثل طول بال.

python
import pandas as pd
import matplotlib.pyplot as plt

birds = pd.read_csv("birds.csv")
print(birds[["Name", "Category", "ConservationStatus", "MaxWingspan"]].head())

پیدا کردن داده پرت با نمودار

نمودار فقط برای ارائه نیست؛ ابزار کشف هم هست. فرض کنید می‌خواهید بیشینه‌ی طول بال پرندگان را ببینید. ساده‌ترین کار رسم یک نمودار خطی از این ستون است.

نمودار خطی برای داده‌ی غیرزمانی؟

با birds["MaxWingspan"].plot() یک نمودار خطی می‌گیرید. اولین چیزی که به چشم می‌آید چند قله‌ی بسیار بلند است. یک یا دو پرنده طول بالی بیش از پنج متر دارند. این برای پرندگان مینه‌سوتا غیرممکن است.

اما نمودار خطی برای این داده انتخاب درستی نیست. خط بین نقطه‌ها یعنی ترتیب و پیوستگی، در حالی که ترتیب پرندگان در فایل معنایی ندارد. برای داده‌ی غیرزمانی، نمودار نقطه‌ای یا پراکنش صادقانه‌تر است.

نمودار نقطه‌ای و برچسب داده‌ی پرت

در نسخه‌ی بهتر، هر پرنده یک نقطه است. فقط نقطه‌هایی که از ۵۰۰ سانتی‌متر بیشترند برچسب نام می‌گیرند. این‌طور نمودار شلوغ نمی‌شود و داده‌ی پرت فوراً شناسایی می‌شود:

python
fig, ax = plt.subplots(figsize=(10, 4))
ax.scatter(range(len(birds)), birds["MaxWingspan"], s=10)
for i, row in birds[birds["MaxWingspan"] > 500].iterrows():
    ax.annotate(row["Name"], (i, row["MaxWingspan"]))
ax.set_ylabel("Wingspan (cm)")
ax.set_xticks([])
plt.show()

نتیجه دو پرنده را نشان می‌دهد؛ عقاب سرسفید و شاهین دشتی. هر دو پرنده‌ی بزرگی‌اند، اما نه تا این حد. احتمالاً یک صفر اضافه هنگام ورود داده تایپ شده است. پس این دو را از تحلیل طول بال حذف یا اصلاح می‌کنیم.

بیشتر بخوانید: روش سیستماتیک پیدا کردن داده‌ی پرت و مقادیر عجیب را در تحلیل اکتشافی داده (EDA) توضیح داده‌ایم.

نمایش تعداد با نمودار میله‌ای

وقتی طول بال پاک شد، سؤال‌های تازه‌ای مطرح می‌شود. چند دسته پرنده داریم و هرکدام چند گونه دارد؟ چند گونه در معرض خطرند؟ این سؤال‌ها درباره‌ی شمارش دسته‌هاست و نمودار میله‌ای بهترین پاسخ است.

تعداد گونه در هر دسته

با value_counts تعداد هر دسته را حساب می‌کنیم و نمودار میله‌ای افقی می‌کشیم. میله‌ی افقی برای برچسب‌های طولانی بهتر است، چون متن کج نمی‌شود:

python
counts = birds["Category"].value_counts().sort_values()
ax = counts.plot.barh(figsize=(7, 5), color="#2f9265")
ax.set_xlabel("Number of species")
ax.bar_label(ax.containers[0], padding=3)
plt.tight_layout()
plt.show()

دو نکته در این کد مهم است. اول، مرتب کردن میله‌ها بر اساس مقدار که مقایسه را بسیار آسان‌تر می‌کند. دوم، bar_label که عدد را کنار هر میله می‌نویسد. خواننده دیگر لازم نیست از روی محور حدس بزند.

میله‌ای گروهی و انباشته

گاهی می‌خواهید دو متغیر دسته‌ای را هم‌زمان ببینید؛ مثلاً دسته‌ی پرنده و وضعیت حفاظت. نمودار میله‌ای گروهی میله‌های هر وضعیت را کنار هم می‌گذارد. نمودار میله‌ای انباشته آن‌ها را روی هم می‌چیند.

نسخه‌ی گروهی برای مقایسه‌ی دقیق بین وضعیت‌ها بهتر است. نسخه‌ی انباشته برای دیدن کل و سهم هر بخش مناسب‌تر است. در pandas، ساخت هر دو با pd.crosstab و سپس plot.bar(stacked=True) یا بدون stacked ممکن است.

نمایش نسبت با نمودار دایره‌ای، دونات و وافل

وقتی سؤال درباره‌ی سهم از کل است، نمودارهای نسبت به کار می‌آیند. مثلاً چند درصد گونه‌ها در معرض خطرند؟ نمودار زیر چهار قدم انتخاب و ساخت نمودار نسبت را نشان می‌دهد.

چهار قدم انتخاب نمودار میله‌ای یا نمودار نسبت برای گزارش داده

دایره‌ای و دونات؛ فقط برای چند بخش

نمودار دایره‌ای کل را صد درصد نشان می‌دهد و هر برش سهم یک بخش است. این نمودار فقط وقتی خوب کار می‌کند که بخش‌ها کم باشند؛ معمولاً حداکثر پنج. با بیشتر از آن، برش‌های کوچک از هم قابل تشخیص نیستند.

نمودار دونات همان دایره‌ای با سوراخ وسط است. فضای وسط می‌تواند عدد کل یا عنوان را نشان دهد. در Matplotlib با wedgeprops={"width": 0.4} دایره به دونات تبدیل می‌شود. برای وضوح، برش‌های کوچک را در یک بخش «سایر» جمع کنید.

نمودار وافل؛ درصد ملموس

نمودار وافل شبکه‌ای ده در ده از مربع‌هاست. هر مربع یک درصد است و به رنگ دسته‌ی خودش درمی‌آید. خواندن درصد در آن بسیار ساده است؛ فقط مربع‌ها را می‌شمارید.

کتابخانه‌ی pywaffle این نمودار را آماده دارد. برای گزارشی که مخاطبش مدیر یا عموم مردم است، وافل معمولاً از دایره‌ای گویاتر است. اما برای مقایسه‌ی دقیق چند نسبت کنار هم، باز هم نمودار میله‌ای برنده است.

متن فارسی در نمودار Matplotlib

اگر برچسب‌های نمودار را فارسی بنویسید، احتمالاً حروف جدا از هم و از چپ به راست نمایش داده می‌شوند. دلیلش این است که Matplotlib حروف فارسی را به هم نمی‌چسباند و جهت متن را برنمی‌گرداند. خوشبختانه راه‌حل ساده است.

آماده‌سازی متن با reshaper و bidi

دو کتابخانه‌ی arabic-reshaper و python-bidi متن را پیش از رسم آماده می‌کنند. یک فونت فارسی هم باید تنظیم شود:

python
import arabic_reshaper
from bidi.algorithm import get_display

def fa(text):
    return get_display(arabic_reshaper.reshape(text))

plt.rcParams["font.family"] = "Vazirmatn"
ax = counts.plot.barh()
ax.set_title(fa("تعداد گونه در هر دسته"))

نکته‌های نمودار فارسی

ارقام را هم در برچسب‌ها فارسی کنید تا با متن گزارش یکدست باشند. ترتیب محور افقی را برای خواننده‌ی فارسی‌زبان در نظر بگیرید. در نمودار زمانی، بعضی گزارش‌ها زمان را از راست به چپ نشان می‌دهند.

مهم‌تر از همه، عنوان نمودار را به شکل یک جمله‌ی نتیجه بنویسید. «تعداد گونه در هر دسته» توصیف است. جمله‌ای مثل «یک دسته به‌تنهایی یک‌سوم گونه‌ها را دارد» نتیجه است. خواننده‌ی پرمشغله فقط عنوان را می‌خواند.

تمرین عملی؛ دو نمودار برای یک سؤال

از داده‌ی پروژه‌ی خودتان یک ستون دسته‌ای انتخاب کنید و این کارها را انجام دهید:

  • نمودار میله‌ای: تعداد هر دسته را با میله‌ی افقی مرتب و برچسب عددی رسم کنید.
  • نمودار نسبت: همان داده را با دونات یا وافل نشان دهید و دسته‌های کوچک را در «سایر» جمع کنید.
  • مقایسه: از دو نفر بپرسید کدام نمودار را سریع‌تر فهمیدند.
  • عنوان نتیجه‌محور: برای نمودار برنده، یک عنوان به شکل جمله‌ی نتیجه بنویسید.
  • متن فارسی: همه‌ی برچسب‌ها را با تابع fa فارسی و خوانا کنید.

سخن پایانی

انتخاب نمودار از سؤال شروع می‌شود. برای مقایسه‌ی تعداد دسته‌ها، نمودار میله‌ای مرتب با برچسب عددی تقریباً همیشه بهترین است. برای سهم از کل با چند بخش محدود، دایره‌ای، دونات یا وافل مناسب‌اند. برای داده‌ی غیرزمانی هم خط نکشید؛ نقطه صادقانه‌تر است.

نمودار ابزار کشف هم هست. در داده‌ی پرندگان، یک نمودار نقطه‌ای ساده دو خطای تایپی را نشان داد که در جدول به چشم نمی‌آمد. نمودار را هم برای خودتان بکشید و هم برای مخاطب، اما برای هرکدام جداگانه طراحی کنید.

این آموزش بر پایه‌ی درس‌های Visualizing Quantities و Visualizing Proportions از مجموعه‌ی آزاد Data Science for Beginners مایکروسافت (مجوز MIT) به فارسی بازنویسی و تکمیل شده است.

پرسش‌های پرتکرار

کی از نمودار میله‌ای استفاده کنیم؟

وقتی می‌خواهید تعداد یا مقدار چند دسته را با هم مقایسه کنید؛ مثل تعداد پرسش در هر موضوع یا فروش هر محصول. چشم انسان طول میله‌ها را دقیق مقایسه می‌کند، پس نمودار میله‌ای برای مقایسه‌ی دقیق بهترین انتخاب است.

کی نمودار دایره‌ای مناسب است؟

فقط وقتی می‌خواهید سهم چند بخش از یک کل را نشان دهید و تعداد بخش‌ها کم است؛ معمولاً حداکثر پنج بخش. اگر مقایسه‌ی دقیق بین بخش‌ها مهم است یا دسته‌ها زیادند، نمودار میله‌ای بهتر است.

نمودار وافل چیست؟

نمودار وافل شبکه‌ای از مربع‌های کوچک، معمولاً ده در ده، است که هر مربع یک درصد را نشان می‌دهد و به رنگ دسته‌ی خودش درمی‌آید. نسبت‌ها را ملموس‌تر از نمودار دایره‌ای نشان می‌دهد و خواندن درصد در آن آسان‌تر است.

چرا متن فارسی در Matplotlib به‌هم‌ریخته نمایش داده می‌شود؟

چون Matplotlib حروف فارسی را به هم نمی‌چسباند و جهت راست‌به‌چپ را اعمال نمی‌کند. با دو کتابخانه‌ی arabic-reshaper و python-bidi متن را پیش از رسم آماده کنید و یک فونت فارسی مثل وزیرمتن تنظیم کنید.

دیدگاه‌ها

هنوز دیدگاهی ثبت نشده است. شروع‌کننده باشید — پرسش و اصلاح را با آغوش باز می‌پذیریم.

دیدگاه بگذارید

برای **پررنگ**، *مورب*، `کد` و لینک از Markdown استفاده کنید. لینک‌ها nofollow هستند.

پنج رقم داخل تصویر را وارد کنید. اعداد فارسی و انگلیسی پذیرفته می‌شوند.

تصویر کد امنیتی پنج‌رقمی

در حال دریافت کد امنیتی…

مهلت کد تمام شد. روی «کد جدید» بزنید.