معرفی کتابخانه Matplotlib (قسمت دوم)


Pyplot اما دقیق تر :

رسم نمودار دو بعدی:

اول از همه باید متغیرهایی برای محور x و y تعریف کنیم .برای نمایش نمودار از دستور show به صورت روبرو استفاده میکنیم.

import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4] , [2, 4, 6, 8])
plt.show()

قرار دادن نام برای نمودار، خطوط و محورها:

برای نامگذاری تابع از دستور title و برای نامگذاری محور های ایکس و وای به ترتیب از دستور های xlabel و ylabel استفاده میکنیم:

plt.xlabel('X')
plt.ylabel('Y')
plt.title('Title')

در نمودار های چندخطی برای نامگذاری خطوط از دستور زیر استفاده میکنیم:

x = [1, 2, 3]

y = [4, 5, 6]

x2 = [2, 3, 4]

y2 = [4 , 5, 6]

plt.plot(x, y, label = 'First line')

plt.plot(x2, y2, label = 'Second line')

plt.legend()

همانطور که میبینید x ,y و x2,y2 را به صورت آرایه های سه تایی از اعداد معرفی کرده ایم. سپس دو نمودار با استفاده از پلات ساخته ایم. دستور لیبل برای نامگذاری بخش های مختلف نمودار استفاده میشود که در این جا اولین نمودار را با لیبل First line و دومین نمودار را با لیبل Second line معرفی کرده­ایم. دستور legend نیز برای نمایش نامگذاری نمودار هاست و اگر نوشته نشود، نامگذاری های لیبل ها هم نمایش داده نمیشوند.


رسم نمودار میله ای یا بارچارت:

نمودار های میله ای معمولاً برای مقایسه استفاده میشوند و گروه هایی از داده ها را با هم مقایسه می کنیم ولی برای بررسی توزیع داده ها از نمودار های هیستوگرام استفاده میکنیم که معمولاً به شکل محدوده ای از اعداد هستند.

x = [1, 2, 3, 4]

y = [6, 9, 2, 12]

plt.bar(x, y, label = 'First bar chart')

رسم نمودار هیستوگرام:

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

height = [152, 183, 205, 175, 178, 167, 192, 169, 173, 181 ,145]

bins = [140, 150, 160, 170, 180, 190, 200, 210]

plt.hist(height, bins, histtype = 'bar', rwidth = 0.7)

در قسمت بعد باید گروه بندی محور ایکس ها را انجام دهیم. در این گروه بندی ما دسته هایی با طول 10 سانتی متر از 140 سانتی متر تا 210 سانتی متر ساخته ایم. در histtype باید مدل نمودار هیستوگرام را مشخص کنیم که ما بصورت میله ای مقداردهی کرده ایم. در قسمت آخر نیز باید عرض نمودار را مقداردهی کنیم که برای خوانایی بیشتر پیشنهاد میشود از اعداد کمتر از 1 استفاده کنید.

رسم نمودار نقطه ای:

x = [2, 5, 4.5, 3, 5.25]

y = [1 , 4, 3, 2.5, 7.75]

plt.scatter (x, y, label = 'points')

plt.legend()

نمودار های نقطه ای معمولاٌ ارتباط بین دو متغیر ایکس و وای و یا توزیع یک داده را نشان میدهند.

با تغییر استرینگ label میتوان نام مشخص شده در راهنمای نمودار را عوض کرد.

رسم نمودار های توده ای:

نمودار های توده ای برای بررسی پارامتر هایی که حداقل یک متغیر مشترک دارند استفاده میشنود. مثلاٌ میخواهیم ببینیم که در پنج ماه اول سال ما چه هزینه هایی برای خوردن،کار و هزینه های روزمره کرده ایم.

در ابتدا ما آرایه هایی 5 تایی از ماه، خوردن، کار و هزینه های روزمره میسازیم که به ترتیب در آن ها شماره ماه ها از یک تا پنج، هزینه های خوردن در پنج ماه اول سال، هزینه های کاری در پنج ماه اول سال و هزینه های روزمره در پنج ماه اول سال را قرار میدهیم. برای مقداردهی لجند نمودار برای خوردن رنگ قرمز، برای کار رنگ آبی و برای هزینه های روزمره رنگ سبز را انتخاب میکنیم.

دقت کنید که ترتیب رنگ ها در بخش بعدی نیز باید به همین صورت باشد وگرنه بین لجند و نمودار رسم شده شاهد تناقض هستیم!

در نهایت برای ساخت نمودار توده ای از دستور stackplot استفاده میکنیم، به این صورت که اولین آرایه که همان ماه است به صورت پیشفرض برای محور ایکس و آرایه های بعدی نمودار ما را تشکیل میدهند. از آن جا که رنگ پیشفرض همه نمودار ها با هم یکی است، باید آن ها را رنگ دهی کنیم. برای تغییر رنگ نمودار ها از دستور colors استفاده میکنیم و رنگ ها را به ترتیب وارد میکنیم.

این نوع نمودار ها در مسائلی مانند BMI (شاخص توده­ی بدنی) بسیار کاربرد دارد.

months = [1, 2 ,3 ,4 ,5]

eating = [200, 175, 350, 300, 420]

work = [500, 450, 700, 680, 380]

daily_payments = [120, 200, 85, 190, 310]

plt.plot([], [], color = 'red', label = 'eating')

plt.plot([], [], color = 'blue', label = 'work')

plt.plot([], [], color = 'green', label = 'daily_payments')

plt.stackplot(months, eating, work, daily_payments, colors = ['red', 'blue', 'green'])

plt.legend()

رسم نمودار های دایره ای:

نمودار های دایره ای معمولاً برای نمایش اندازه نسبی بسیاری از چیزها استفاده میشود مانند:

  • نوع ماشینی که مردم سوار می‌شوند
  • تعداد مشتری‌های یک مغازه در روز‌های مختلف
  • این که کدام نوع موسیقی طرفدار بیشتری دارد.

در مثالی که ما زده ایم، ژانر فیلم های مورد علاقه جوانان بین 25 تا 30 سال را بررسی کرده ایم. در ابتدا آرایه ای برای ژانر های انتخابی ساخته ایم و چهار ژانر مختلف درام، اکشن، کمدی و رومانتیک را در آن مقداردهی کرده ایم. در قسمت بعدی آرایه ای برای ثبت نظرسنجی ساخته ایم و به ترتیب 16، 21، 43 و 20 نفر به فیلم های درام، اکشن، کمدی و رومانتیک رأی داده اند.

برای ساخت نمودار دایره ای از کلیدواژه pieاستفاده میکنیم. این نام به دلیل شباهت نمودار دایره ای به شیرینی پای انتخاب شده است. طبق معمول باید ایکس و وای تعریف کنیم که برای ا یکس ها نتایج نظرسنجی و برای وای ها ژانر ها را میگذاریم. از آنجا که نمودار های دایره ای لااقل دو بخش متفاوت دارد، باید رنگ نمودار ها را تغییر دهیم و برای این کار از کلیدواژه colorsاستفاده میکنیم و به ترتیبی که ژانر ها را معرفی کردیم، برای آن ها رنگ میگذاریم.

Genres = ['Drama', 'Action', 'Comedy', 'Romance']  
slices = [16, 21, 43, 20]  
plt.pie(slices, labels = Genres, colors = ['red', 'blue', 'green', 'pink'])  
plt.show()

استایل و شخصی سازی اشکال (Figure Style):

استایل کلی:

در matplotlib میتوان از طریق متد style شکل کلی نمودار را تغییر داد به گونه ای که تم نمودار (پس زمینه، رنگ خطوط و...) عوض میشوند.

در صفحه ی بعد تمام استایل های موجود در لیست matplotlib.pyplot.style.available نمایش داده میشود

این استایل ها را میتوان توسط متد اصلی برنامه قرار داد:

plt.style.available
['Solarize_Light2',
'default'
'_classic_test_patch',
'bmh',
'classic',
'dark_background',
'fast',
'fivethirtyeight',
'ggplot',
'grayscale',
'seaborn'
'seaborn-bright',
'seaborn-colorblind',
'seaborn-dark',
'seaborn-dark-palette',
'seaborn-darkgrid',
'seaborn-deep',
'seaborn-muted',
'seaborn-notebook',
'seaborn-paper',
'seaborn-pastel',
'seaborn-poster',
'seaborn-talk',
'seaborn-ticks',
'seaborn-white',
'seaborn-whitegrid']


plt.style.use('default')
plt.plot([1, 4, 5, 7])
plt.style.use('seaborn')
plt.plot([1, 4, 5, 7])

با تعیین استایل، تمامی نمودار هایی که در برنامه هستند، به استایل مورد نظر تغییر شکل میدهند.

برای تغییر استایل فقط برای یک نمودار میتوان از کلمه کلیدی with استفاده نمود:

x = np.sin(np.linspace(0, 2 * np.pi))
with plt.style.context('seaborn'):
         plt.plot(x)

در این صورت، با متد contextمتحوای استایل را به شکل نسبت میدهیم.

رنگ محورها:

در پایپلات میتوان رنگ محور ها را حین ایجاد آنها تغییر داد:

  • استفاده از کد هگز رنگ مورد نظر
  • حرف اول برخی رنگ های اصلی
  • نام مخصوص X11/CSS4 رنگ

برای اطلاعات بیشتر میتوانید به جدول راهنما مراجعه کنید.

نوع محور ها:
نمودار lineدارای استایل های مختلفی است که میتوانید با آرگیومنت linestyle=’’ آنها را تعیین کنید:

در این نمودار همچنین میتوان از آرگیومنت marker=’ ‘ برای علامت گذاری نقاط تعیین شده استفاده کرد:

این علامت گذاری ها برای نمودار scatter نیز قابل استفاده است. نمونه ی همه­ی این استایل ها در ادامه، نشانه ی انعطاف پذیری بالای این کتابخانه است.

در مثالی که قبلا در مورد نمودار نقطه¬ای زده بودیم دیدیم که استایل پیشفرض از نقطه¬های آبی برای نمایش نمودار استفاده کرده است. حال نوع و رنگ نقاط را میخواهیم به دلخواه تغییر دهیم:

x = [2, 5, 4.5, 3, 5.25]

y = [1 , 4, 3, 2.5, 7.75]

plt.scatter (x, y, label = 'points', color = 'red', s = 15, marker = '*')

plt.legend()
فعلی
فعلی
قبلی
قبلی

نکته: برای استایل های نمودار خطی میتوان از پنج مورد کوتاه شده استفاده نمود و نیازی به نام کامل آنها نیست. ('-', '--', ':', '-.', '.')

نکته: در نمودار های خطی میتوان رنگ، نوع خط و نوع علامت (marker) را در یک رشته خلاصه کرد.

x = np.sin(np.linspace(0, 2 * np.pi))

    with plt.style.context('dark_background'):

    plt.plot(x, color='r', linestyle='-', marker='o')


x = np.sin(np.linspace(0, 2 * np.pi))

    with plt.style.context('dark_background'):

    plt.plot(x)

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

x = np.sin(np.linspace(0, 2 * np.pi))

with plt.style.context('dark_background'):

    plt.plot(x, 'r-o')

مثال چرخه ی تولید یک نمودار:

?برای نمودارهایی که توضیحات محور های افقی یا عمودی آنها بزرگ است، احتمال دارد که نوشته ها تو در تو و نا خوانا باشند. به مثال زیر توجه کنید:

fig, ax = plt.subplots()

ax.barh(group_names, group_data)

مپ رو به رو را در دو متغیر تعریف شده ریخته و سپس نمودار را رسم میکنیم:

import numpy as np
import matplotlib.pyplot as plt
data = {'Barton LLC': 109438.50,

        'Frami, Hills and Schmidt': 103569.59,

        'Fritsch, Russel and Anderson': 112214.71,

        'Jerde-Hilpert': 112591.43,

        'Keeling LLC': 100934.30,

        'Koepp Ltd': 103660.54,

        'Kulas Inc': 137351.96,

        'Trantow-Barrows': 123381.38,

        'White-Trantow': 135841.99,

        'Will LLC': 104437.60}

group_data = list(data.values())

group_names = list(data.keys())

group_mean = np.mean(group_data);

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

fig, ax = plt.subplots()

ax.barh(group_names, group_data)

labels = ax.get_xticklabels()

plt.setp(labels, rotation=45, horizontalalignment='right')

از طریق متد get_xticklabels قصد داریم تا تمامی رفرنس اعداد محور افقی را در متغیر labels قرار دهیم. در خط بعدی نیز، مشخصات مربوطه را وارد و اعداد را چهل و پنج درجه میچرخانیم.

در مرحله ی بعدی، از طول اضافی نمودار میکاهیم تا نوشته ها کامل نمایش داده شوند.

به همین خاطر از rcParams استفاده میکنیم. دیکشنری rcParams مرجعی کامل، برای کلاس pyplot است که تمام ساختار نمودار ها در آن ذخیره

plt.rcParams.update({'figure.autolayout': True})
 
fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')

حال برای زیباسازی بیشتر و ایجاد جزئیات، به برچسب عمودی و افقی نیاز است:

fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
  title='Company Revenue')

حال سایز نمودار را تغییر میدهیم:

fig, ax = plt.subplots(figsize=(8, 4))
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
  title='Company Revenue')

اکنون برای اینکه نمودار برای نمایش عمومی مناسب باشد، باید از تعداد صفرها کاهید. به همین منظور متدی باید تعبیه کرد که هزار و میلیون را به اعداد کوتاه تر تبدیل کند.

پس از اضافه کردن این متد، شکل آماده­ی استفاده است.

با مقایسه­ی این نمودار اولیه با نتیجه­ی نهایی، تفاوت داده­ی پردازش شده با شکل ساده را میتوان مشاهده کرد.

def currency(num, pos):
  if num >= 1e6:
  s = '${:1.1f}M'.format(num*1e-6)
  else:
  s = '${:1.0f}K'.format(num*1e-3)
  return s
fig, ax = plt.subplots(figsize=(6, 8))
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
 
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
  title='Company Revenue')
ax.xaxis.set_major_formatter(currency)

ادامه مطلب را در قسمت بعدی بخوانید...

انجمن هوش مصنوعی دانشگاه اصفهان
ابولفضل شیشه­ گر
امیرمحسن براهیمی
علیرضا عشقی