Məzmuna keç
Educora
Universitet25 dəq33 / 42

matplotlib ilə vizuallaşdırma

Xətti qrafik, sütunlu diaqram, səpələnmə diaqramı, histoqram və alt qrafiklər qur, oxları, başlıqları və şərti işarələri düzgün yaz, intervalların sayını seç və dürüst, oxunaqlı qrafik çəkməyin qaydalarını öyrən.

Özünü yoxla
Bu dərsdə öyrənəcəksən
  • fig, ax = plt.subplots() ilə obyektyönlü üsulda qrafik qurmaq və ona başlıq, ox adları, şərti işarələr əlavə etmək
  • Suala uyğun qrafik növünü seçmək: xətt, sütun, səpələnmə, histoqram
  • Histoqram üçün intervalların sayını Sturges və Freedman–Diaconis qaydaları ilə əsaslandırmaq
  • Aldadıcı qrafikləri tanımaq və dürüst, oxunaqlı qrafik çəkmək

1973-cü ildə statistik Frensis Anskomb dörd kiçik verilənlər dəsti dərc etdi: onların orta qiymətləri, dispersiyaları, korrelyasiya əmsalı və reqressiya xətti demək olar ki, eynidir. Amma qrafikdə biri düz xətt ətrafında səpələnib, biri əyri boyunca düzülüb, üçüncüsündə bir kənar nöqtə hər şeyi dəyişir, dördüncüsündə isə biri istisna olmaqla bütün nöqtələr bir şaquli xətdədir. Nəticə: rəqəmlərə etibar etməzdən əvvəl verilənlərə baxmaq lazımdır. Python-da bunun əsas aləti matplotlib-dir.

Figure və Axes: qrafikin quruluşu

Tərif
Figure və Axes

Figure — bütün şəkil, «kətan». Axes — onun içindəki bir qrafik sahəsi: oxlar, xətlər, başlıq, şərti işarələr. Bir Figure-da bir neçə Axes ola bilər. Metodlar əsasən Axes-ə aiddir: ax.plot, ax.set_title, ax.legend.

matplotlib-in iki üslubu var: plt.plot(...) kimi qısa «pyplot» üslubu və obyektyönlü üslub. Həmişə ikincisi ilə başla: fig, ax = plt.subplots() — belə kod bir neçə qrafikdə də aydın qalır. Brauzerdə şəkil kodun altında avtomatik görünür; kompüterində plt.show() pəncərə açır, fig.savefig('chart.png', dpi=200) isə faylı saxlayır.

Python
import matplotlib.pyplot as plt

months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
baku = [279, 153, 426, 390, 455, 510]
ganja = [150, 306, 168, 210, 240, 265]

fig, ax = plt.subplots(figsize=(7, 4))
ax.plot(months, baku, marker='o', label='Baku')
ax.plot(months, ganja, marker='s', linestyle='--', label='Ganja')
ax.set_title('Monthly revenue by branch, 2026')
ax.set_xlabel('Month')
ax.set_ylabel('Revenue, AZN')
ax.grid(alpha=0.3)
ax.legend()
plt.show()
Xətti qrafik zamanla dəyişməni göstərir. Markerlər ölçmə nöqtələrini, müxtəlif xətt üslubları isə rəngləri ayırd edə bilməyənlər üçün seriyaları fərqləndirir.
  • Başlıq — qrafik nəyi göstərir, harada və nə vaxt.
  • Ox adları vahidlərlə: «Revenue, AZN», «Height, cm».
  • Şərti işarələr (legend) — birdən çox seriya varsa.
  • Zəif tor (grid(alpha=0.3)) — qiymətləri oxumağı asanlaşdırır, diqqəti yayındırmır.

Qrafik növünü seçmək

SualQrafikmatplotlib
Zamanla necə dəyişir?xətti qrafikax.plot
Kateqoriyalar necə müqayisə olunur?sütunlu diaqramax.bar, ax.barh
İki ədədi dəyişən əlaqəlidirmi?səpələnmə diaqramıax.scatter
Qiymətlər necə paylanıb?histoqram, qutu diaqramıax.hist, ax.boxplot
Python
import numpy as np
import matplotlib.pyplot as plt

products = np.array(['Coffee', 'Cake', 'Tea', 'Juice', 'Sandwich'])
revenue = np.array([564, 540, 378, 212, 305])
order = np.argsort(revenue)

fig, ax = plt.subplots(figsize=(6, 3.5))
bars = ax.barh(products[order], revenue[order], color='#4C72B0')
ax.bar_label(bars, fmt='%d AZN', padding=3)
ax.set_xlim(0, 680)
ax.set_xlabel('Revenue, AZN')
ax.set_title('Revenue by product, Q1 2026')
print(products[order][-1], revenue.max())
plt.show()
▸ Gözlənilən nəticə
Coffee 564

Səpələnmə diaqramı iki ədədi dəyişən arasındakı əlaqəni göstərir. Rəng üçüncü dəyişəni daşıya bilər (c=, cmap=), np.polyfit(x, y, 1) isə ən kiçik kvadratlar üsulu ilə trend xəttini tapır. Aşağıdakı verilənlər uydurmadır: mənzilin sahəsi, otaq sayı və qiyməti.

Python
import numpy as np
import matplotlib.pyplot as plt

rng = np.random.default_rng(3)
area = rng.uniform(40, 140, 60)
rooms = np.clip(area // 30, 1, 4).astype(int)
price = 1.5 * area + 10 * rooms + rng.normal(0, 15, 60)
slope, intercept = np.polyfit(area, price, 1)
print(f'slope: {slope:.2f} thousand AZN per m2')
print(f'correlation r = {np.corrcoef(area, price)[0, 1]:.3f}')

fig, ax = plt.subplots(figsize=(6, 4))
points = ax.scatter(area, price, c=rooms, cmap='viridis', alpha=0.8)
xs = np.array([40, 140])
ax.plot(xs, slope * xs + intercept, color='red', label='trend line')
fig.colorbar(points, ax=ax, label='rooms')
ax.set_xlabel('Area, m²')
ax.set_ylabel('Price, thousand AZN')
ax.legend()
plt.show()
▸ Gözlənilən nəticə
slope: 2.00 thousand AZN per m2
correlation r = 0.960
viridis rəng şkalası həm ağ-qara çapda, həm də rəngləri seçməkdə çətinlik çəkənlər üçün oxunaqlıdır. Korrelyasiya əmsalı r növbəti dərsdə ətraflı izah olunur.

Histoqram və intervalların sayı

Histoqram qiymətlər oxunu bərabər intervallara (bins) bölür və hər intervala düşən müşahidələri sayır. İntervallar çox azdırsa, paylanmanın forması itir; çox çoxdursa, qrafik küylü «daraq»a çevrilir. İki məşhur qayda başlanğıc nöqtəsi verir:

k = ⌈log₂ n⌉ + 1 h = 2 · IQR · n^(−1/3)
burada:
  • kintervalların sayı (Sturges qaydası)
  • hintervalın eni (Freedman–Diaconis qaydası), verilənlərin vahidi ilə
  • nmüşahidələrin sayı
  • IQRkvartillərarası məsafə Q3 − Q1

Sturges normal paylanmaya yaxın və çox böyük olmayan verilənlər üçün yaxşıdır; Freedman–Diaconis kənar qiymətlərə davamlıdır. ax.hist(x, bins='fd') ikincisini avtomatik tətbiq edir.

Python
import numpy as np
import matplotlib.pyplot as plt

rng = np.random.default_rng(42)
heights = rng.normal(170, 8, 500)
k = int(np.ceil(np.log2(heights.size))) + 1
print('Sturges bins:', k)
print(f'mean = {heights.mean():.1f} cm, std = {heights.std(ddof=1):.1f} cm')

fig, ax = plt.subplots(figsize=(6, 4))
ax.hist(heights, bins=k, edgecolor='white')
ax.axvline(heights.mean(), color='red', linestyle='--', label='mean')
ax.set_xlabel('Height, cm')
ax.set_ylabel('Number of people')
ax.legend()
plt.show()
▸ Gözlənilən nəticə
Sturges bins: 10
mean = 169.9 cm, std = 7.7 cm
Nümunə 1: 500 nəfərin boyu üçün intervallar

n = 500, boylar təxminən normal paylanıb, σ ≈ 8 sm. Sturges və Freedman–Diaconis qaydaları ilə intervalları hesabla. Normal paylanmada IQR ≈ 1,35σ.

Həllini göstər
Sturges: log₂ 500 ≈ 8,97 → ⌈8,97⌉ = 9 → k = 9 + 1 = 10 interval (kodla eyni).
Freedman–Diaconis: IQR ≈ 1,35 · 8 = 10,8 sm; n^(1/3) = 500^(1/3) ≈ 7,94.
h = 2 · 10,8 / 7,94 ≈ 2,7 sm.
Diapazon təxminən 170 ± 3σ, yəni ~48 sm → 48 / 2,7 ≈ 18 interval.
FD daha incə təfsilat verir; n böyüdükcə Sturges intervalları çox yavaş artırır.
fᵢ = nᵢ / (n · h) ∑ fᵢ · h = 1fᵢ = nᵢ / (n · h) ∑ fᵢ · h = 1
burada:
  • nᵢi-ci intervala düşən müşahidələr
  • fᵢsütunun hündürlüyü density=True rejimində (sıxlıq)
  • hintervalın eni

ax.hist(x, density=True) sütunların sahələrinin cəmini 1 edir — belə histoqramı ehtimal sıxlığının əyrisi ilə müqayisə etmək olar.

Nümunə 2: sıxlıq histoqramı

200 ölçmə eni h = 2 olan intervallara bölünüb. Bir intervalda 30 ölçmə var. density=True ilə bu sütunun hündürlüyü nə qədərdir? Bu sütunun sahəsi nəyi göstərir?

Həllini göstər
f = 30 / (200 · 2) = 0,075.
Sahə = f · h = 0,075 · 2 = 0,15, yəni ölçmələrin 15%-i bu intervaldadır (30 / 200).
Bütün sütunların sahələrinin cəmi 1-dir (100%).

Bir şəkildə bir neçə qrafik

plt.subplots(2, 2) 2 × 2 ölçülü Axes massivi qaytarır; hər qrafikə axes[sətir, sütun] ilə müraciət edilir. layout='constrained' başlıqların və oxların üst-üstə düşməsinin qarşısını alır, sharex=True isə oxları ortaq edir.

Python
import numpy as np
import matplotlib.pyplot as plt

rng = np.random.default_rng(0)
x = np.linspace(0, 2 * np.pi, 100)
fig, axes = plt.subplots(2, 2, figsize=(8, 6), layout='constrained')
axes[0, 0].plot(x, np.sin(x))
axes[0, 0].set_title('Line: sin x')
axes[0, 1].bar(['A', 'B', 'C'], [5, 3, 7])
axes[0, 1].set_title('Bar')
axes[1, 0].scatter(rng.random(30), rng.random(30))
axes[1, 0].set_title('Scatter')
axes[1, 1].hist(rng.normal(size=300), bins=15)
axes[1, 1].set_title('Histogram')
fig.suptitle('Four basic chart types')
print(axes.shape)
plt.show()
▸ Gözlənilən nəticə
(2, 2)

pandas-ın özündə matplotlib üzərində qurulmuş .plot() metodu var: DataFrame-in hər sütunu ayrıca seriya olur, indeks isə X oxuna düşür. Metod Axes qaytarır, ona görə sonra adi matplotlib əmrləri ilə qrafiki tamamlamaq olar.

Python
import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({'month': ['Jan', 'Feb', 'Mar'],
                   'Baku': [279, 153, 426],
                   'Ganja': [150, 306, 168]}).set_index('month')
ax = df.plot(kind='bar', figsize=(6, 3.5), rot=0, title='Revenue by month, AZN')
ax.set_ylabel('AZN')
print(df.sum())
plt.show()
▸ Gözlənilən nəticə
Baku     858
Ganja    624
dtype: int64

Yaxşı qrafikin qaydaları

  1. Bir qrafik — bir fikir. Başlıqda nəticəni yaz: «Martda Bakı filialı liderdir».
  2. Sütunlu diaqramda Y oxu 0-dan başlamalıdır, çünki göz sütunun uzunluğunu müqayisə edir.
  3. Rənglər məna daşısın: vurğulamaq istədiyin seriyaya parlaq rəng, qalanlarına boz ver.
  4. 3D effektlər, kölgələr və çoxlu dilimli dairəvi diaqramlardan qaç — onlar qiymətləri təhrif edir.
Python
import matplotlib.pyplot as plt

branches = ['Baku', 'Ganja']
satisfied = [96, 98]
fig, (bad, good) = plt.subplots(1, 2, figsize=(8, 3.5), layout='constrained')
bad.bar(branches, satisfied, color=['gray', 'orange'])
bad.set_ylim(95, 98.5)
bad.set_title('Misleading: axis starts at 95')
good.bar(branches, satisfied, color=['gray', 'orange'])
good.set_ylim(0, 100)
good.set_title('Honest: axis starts at 0')
for ax in (bad, good):
    ax.set_ylabel('Satisfied customers, %')
plt.show()
Solda Gəncənin sütunu Bakınınkından üç dəfə uzun görünür, halbuki fərq cəmi 2 faiz bəndidir.
Tapşırıq

revenue lüğətindən üfüqi sütunlu diaqram qur (ax.barh), başlığı 'Revenue by product' et və X oxunu 'AZN' adlandır. Sonra ayrı sətirlərdə çap et: 1) qrafikin başlığı (ax.get_title()); 2) qrafikdəki sütunların sayı (len(ax.patches)); 3) gəliri ən böyük olan məhsul.

Tapşırıq · Python
import matplotlib.pyplot as plt

revenue = {'Coffee': 564, 'Cake': 540, 'Tea': 378, 'Juice': 212, 'Sandwich': 305}
fig, ax = plt.subplots()
# draw the bars, set the title and the X label, then print the three results
▸ Gözlənilən nəticə
Revenue by product
5
Coffee
Tapşırıq

Test ballarının 5 intervallı histoqramını qur. ax.hist üç şey qaytarır: saylar, intervalların sərhədləri və sütunlar. Ayrı sətirlərdə çap et: 1) hər intervaldakı say tam ədədlərin siyahısı kimi; 2) bir intervalın eni, 2 onluq rəqəmə qədər yuvarlaqlaşdırılmış.

Tapşırıq · Python
import matplotlib.pyplot as plt

scores = [55, 62, 68, 70, 71, 75, 78, 80, 82, 85, 88, 90, 94, 97]
fig, ax = plt.subplots()
# counts, edges, _ = ax.hist(...)
▸ Gözlənilən nəticə
[2, 3, 3, 3, 3]
8.4

Əsas fikirlər

  • Figure bütün şəkil, Axes isə onun içindəki qrafikdir; fig, ax = plt.subplots() ilə başla.
  • Zaman → xətt, kateqoriyalar → sütun, iki ədədi dəyişən → səpələnmə, paylanma → histoqram.
  • Hər qrafikdə başlıq, vahidli ox adları və lazım olanda şərti işarələr olmalıdır.
  • İntervallar: Sturges k = ⌈log₂ n⌉ + 1, Freedman–Diaconis h = 2 · IQR · n^(−1/3).
  • Sütunlu diaqramın oxu 0-dan başlayır; rəng şkalası üçün viridis seç.

Özünü yoxla

10 sual. Hər düzgün cavab XP qazandırır.

1 / 10
Beş filialın illik gəlirini müqayisə etmək üçün ən uyğun qrafik hansıdır?