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
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.
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()- 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
| Sual | Qrafik | matplotlib |
|---|---|---|
| Zamanla necə dəyişir? | xətti qrafik | ax.plot |
| Kateqoriyalar necə müqayisə olunur? | sütunlu diaqram | ax.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 |
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.
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:
- 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.
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 = 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ərHəllini gizlət
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.
- nᵢi-ci intervala düşən müşahidələr
- fᵢsütunun hündürlüyü
density=Truerejimində (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.
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ərHəllini gizlət
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.
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.
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ı
- Bir qrafik — bir fikir. Başlıqda nəticəni yaz: «Martda Bakı filialı liderdir».
- Sütunlu diaqramda Y oxu 0-dan başlamalıdır, çünki göz sütunun uzunluğunu müqayisə edir.
- Rənglər məna daşısın: vurğulamaq istədiyin seriyaya parlaq rəng, qalanlarına boz ver.
- 3D effektlər, kölgələr və çoxlu dilimli dairəvi diaqramlardan qaç — onlar qiymətləri təhrif edir.
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()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.
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
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ış.
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
viridisseç.
Özünü yoxla
10 sual. Hər düzgün cavab XP qazandırır.