هیستوگرامها در کتابخانه Matplotlib پایتون
در مقاله پیشین در مورد نحوه کار با کتابخانه محبوب Matplotlib، و مفاهیم اصلی موجود در آن نکاتی گفته شد در صورتیکه با این کتابخانه آشنایی ندارید توصیه میشود ابتدا مقاله زیر را مطالعه کنید
در این آموزش با نمودارهای هیستوگرام در این کتابخانه قدرتمند که شما را به نمایش بهتر دادههایتان کمک خواهد کرد آشنا خواهیم شد.
هیستوگرامها یا Histograms
هیستوگرامها شکلی از نمایش داده هستند که دادهها را بر اساس توزیع عددی آنها ارائه میدهند. در واقع نوعی نمودار میلهایست که محور X نشان دهنده دامنه توزیع داده و محور Y نمایانگر فراوانی داده در یک بازه معین میباشد. برای ایجاد یک هیستوگرام در کتابخانه Matplotlib لازم است ابتدا دادههای خود را در یک آرایه لیست کنیم. سپس به کمک تابع hist از pyplot هیستوگرام مورد نظر خود را خروجی بگیریم. در مثال زیر تعداد 10000 عدد تصادفی توسط تابع random.randn
در توزیع نرمال استاندارد ایجاد و در یک هیستوگرام با 20 دسته در دامنه توزیع داده نمایش داده شده است:
data = np.random.randn(10000)
plt.hist(data, bins=20)
plt.show()


بدیهی است هر چه تعداد دستهها بیشتر باشد نمودار حالت پیوستهتری خواهد داشت.
data = np.random.randn(100000)
fig, axs = plt.subplots(2, 2, figsize =(8, 5))
axs[0,0].hist(data, bins=5)
axs[0,1].hist(data, bins=15)
axs[1,0].hist(data, bins=30)
axs[1,1].hist(data, bins=50)
plt.show()


در مثال زیر نیز نمودار فراوانی یک آرایه تصادفی از کاراکترها را در هیستوگرام به نمایش درآمده است:
data = ['a', 'a', 'a', 'a', 'b', 'b',
'c', 'c', 'c', 'd', 'e', 'e',
'e', 'e', 'e', 'f', 'f', 'f']
plt.hist(data, bins=[0,1,2,3,4,5,6], align='left',
color='blue', edgecolor='black')
plt.show()


ایجاد ساختار نمایشی متفاوت با colormap
کالرمپها(colormap) اشیایی هستند که اعداد را به رنگ تصویر میکنند. در Matplotlib تعداد بسیاری colormap بصورت built-in وجود دارد. برای نمونه کالرمپ grey، صفر را سیاه و یک را سفید تصویر میکند و یا کالرمپ jet صفر را آبی و یک را قرمز تصویر میکند. در زیر چند نمونه از کالرمپها لیست شده است:




برای نمایش بهتر هیستوگرام با کمک colormapها میتوان برای هر ستون از نمودار با توجه به میزان فراوانی یک رنگ از colormap به آن اختصاص دهیم. برای این منظور تلاش خواهیم کرد برای اولین نمودار هیستوگرام در این مقاله بصورت زیر نمایش بهتری ایجاد کنیم:
frequencies, bins, patches = plt.hist(data, bins=20)
frequencies
لیستی از فراوانی هر دسته، bins
یک آرایه از نقاط ابتدایی هر دسته روی محور x و patches
لیستی از اشیاء matplotlib.patches.Rectangle
برای نمایش مستطیلهای گرافیکی در نمودار میباشند.
ابتدا بصورت زیر فراوانی را به بازه [0,1] تصویر میکنیم:
fracs = frequencies/ frequencies.max()
سپس با کمک تابع zip برای هر شی ستون از هیستوگرام با توجه به مقدار تبدیل شده در آرایه fracs یک رنگ در نظر میگیریم.
for thisfrac, thispatch in zip(fracs, patches):
color = plt.cm.viridis(thisfrac)
thispatch.set_facecolor(color)
تابع
zip(iterator1, iterator2, iterator3, ...)
یک شی zip که یک متغیر tuples میباشد را بازمیگرداند. که اولین عضو آن اولین عناصر از ورودیهای این تابع است و باقی عناصر به همین صورت خواهند بود.
تمامی موارد فوق بصورت زیر نتیجه خواهد داد:
import matplotlib.pyplot as plt
import numpy as np
data = np.random.randn(10000)
fig, axs = plt.subplots(1, 1, figsize =(4, 5))
frequencies, bins, patches = axs.hist(data, bins=20)
fracs = frequencies/frequencies.max()
for thisfrac, thispatch in zip(fracs, patches):
color = plt.cm.viridis(thisfrac)
thispatch.set_facecolor(color)
plt.show()


با افزودن مواردی دیگر خروجی نهایتا میتواند بصورت زیر هم باشد:
import matplotlib.pyplot as plt
import numpy as np
data = np.random.randn(10000)
fig, axs = plt.subplots(1, 1, figsize =(10, 7), tight_layout = True)
# Remove axes splines
for s in ['top', 'bottom', 'left', 'right']:
axs.spines[s].set_visible(False)
# Remove x, y ticks
axs.xaxis.set_ticks_position('none')
axs.yaxis.set_ticks_position('none')
# Add padding between axes and labels
axs.xaxis.set_tick_params(pad = 5)
axs.yaxis.set_tick_params(pad = 10)
# Add x, y gridlines
axs.grid(b=True, color='grey', linestyle='-.',
linewidth=0.5, alpha=0.6)
# Creating histogram
frequencies, bins, patches = axs.hist(data, bins=20)
# Setting color
fracs = frequencies/frequencies.max()
for thisfrac, thispatch in zip(fracs, patches):
color = plt.cm.viridis(thisfrac)
thispatch.set_facecolor(color)
# Adding extra features
plt.xlabel("X-axis")
plt.ylabel("y-axis")
plt.legend(['distribution'] )
plt.title('Customized histogram')
plt.show()


این امکان نیز در کتابخانه Matplotlib فراهم شده است که بتوانیم چندین هیستوگرام را با یکدیگر در یک نمودار مقایسه کنیم برای این منظور تنها کافی است که دیتاهای متفاوت را در یک آرایه 2-بعدی لیست کنیم. به مثال زیر دقت کنید:
data1 = np.random.randn(10000)
data2 = np.random.randn(10000)
colors = ['#D55E00', '#56B4E9']
names = ['1st distribution', '2nd distribution']
plt.hist([data1, data2], bins=15, color=colors, label=names)
plt.legend()
plt.show()


همانطور که مشاهده میکنید برای نمایش بهتر با استفاده از دو خاصیت label و color برای هر هیستوگرام نام و رنگ متفاوتی در نظر گرفته شده است. همچنین میتوان نمودار را بصورت stack دربیاورید برای این منظور تنها کافیست خاصیت stacked را برابر مقدار True قرار دهید:


تابع هیستوگرام در کتابخانه Matplotlib اشکال متفاوتی دارد که برای اعمال هر یک از آنها در هیستوگرامهای خود لازم است خاصیت histtype
تعیین شود. مقادیر قابل قبول 'barstacked' ،'step' ،'stepfilled' و 'bar' میباشند که در مثال زیر تمامی حالتهای ممکن را ترسیم کردهام:
data1 = np.random.randn(400)
data2 = np.random.randn(500) + 3
data3 = np.random.randn(450) + 6
data4a = np.random.randn(200) + 9
data4b = np.random.randn(100) + 10
plt.hist(data1, bins=5, color='g', edgecolor='black', alpha=0.75, label='bar hist') # default histtype='bar'
plt.hist(data2, color='b', edgecolor='black', alpha=0.65, histtype='stepfilled', label='stepfilled hist')
plt.hist(data3, color='r', histtype='step', label='step hist')
plt.hist((data4a, data4b), color=('r','m'), alpha=0.55, histtype='barstacked', label=('barstacked a', 'barstacked b'))
plt.xlabel("Value")
plt.ylabel("Frequency")
plt.legend()
plt.grid(True)
plt.show()


ترسیم هیستوگرام 2-بعدی
برای ترسیم گراف 2-بعدی تنها چیزی که نیاز دارید دو بردار با طول یکسان مربوط به هر محور هیستوگرام است.
fig, axs = plt.subplots(1, 1,figsize=(5,5))
data1 = np.random.randn(10000)
data2 = np.random.randn(10000)
axs.hist2d(data1, data2, bins=40)
plt.show()


این امکان نیز وجود دارد برای هر محور تعداد سفارشیسازی شدهای دسته تعریف کنیم:


نمودار چگالی
نمودار چگالی (Density Plot) نسخه هموار و پیوستهای از هیستوگرام است. برای ترسیم این شکل از نمودارها روش سرراستی در کتابخانه matplotlib وجود ندارد. برای این منظور میتوانیم از کتابخانه seaborn استفاده کنید. البته امکان ترسیم این شکل از نمودارها با کمک کتابخانه pandas نیز وجود دارد که در مقاله آموزش pandas به آن اشاره خواهد شد.
import seaborn as sns
sns.set(style="darkgrid")
d1 = np.random.randn(1000)
d2 = np.random.randn(1000) + 3
sns.histplot(data=d1, kde=True, label="data1", color="skyblue")
sns.histplot(data=d2, kde=True, label="data2", color="red")
plt.legend()
plt.show()


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