Relational plot lar
Relational plot bitta savolga javob beradi: bir numeric o'zgaruvchi ikkinchisi bilan qanday harakatlanadi? Seaborn bu sarlavha ostida uchta function ni birlashtiradi — sns.scatterplot(), sns.lineplot() va figure-level wrapper bo'lgan sns.relplot(). Ularning hammasi seaborn.relational module ida joylashgan va ichkarida qo'shimcha column larni rang, o'lcham hamda marker shakliga map qilish uchun bir xil mexanizmdan foydalanadi.
Bu bobdagi hamma narsa long-form (tidy) data ga asoslanadi: har bir observation uchun bitta row, har bir o'zgaruvchi uchun bitta column. Aynan shuning uchun chaqiruvlar sns.scatterplot(data=tips, x="total_bill", y="tip") ko'rinishida bo'ladi — siz column nomlarini aytasiz, seaborn esa qiymatlar, dtype lar va label larni DataFrame dan o'zi o'qib oladi.
import seaborn as sns import matplotlib.pyplot as plt sns.set_theme(style="whitegrid") # ranglar, shrift va grid uchun seaborn default lari tips = sns.load_dataset("tips") # 244 row: restoran hisoblari penguins = sns.load_dataset("penguins") # 344 row: tana o'lchovlari flights = sns.load_dataset("flights") # 144 row: 1949-1960 oylik aviayo'lovchilar titanic = sns.load_dataset("titanic") # 891 row: yo'lovchilar ro'yxati
Seaborn — matplotlib ustidagi qatlam. sns.scatterplot() pirovardida ax.scatter() ni chaqiradi, sns.lineplot() esa ax.plot() ni. Seaborn qo'shadigan narsa — semantic mapping layer: u sizning DataFrame column laringizni tekshiradi, o'zgaruvchi categorical yoki numeric ekanini aniqlaydi, palette quradi, takrorlanuvchi observation larni aggregate qiladi hamda legend va axis label larini yozadi. Butun qiymat shunda — chizish ishini matplotlib bajaradi, statistika va hisob-kitob seaborn zimmasida.
Uchta function bir qarashda
| Function | Nimani ko'rsatadi | Qachon ishlatiladi |
|---|---|---|
sns.scatterplot() |
Har bir row uchun bitta marker: ikkita numeric o'zgaruvchining birgalikdagi taqsimoti | Correlation, cluster lar, outlier lar; x da tabiiy tartib yo'q |
sns.lineplot() |
x tartibida ulangan nuqtalar, takrorlanuvchi x qiymatlari aggregate qilinib mean va noaniqlik band iga aylanadi | Time series, trend lar, dose-response; x da ma'noli tartib bor |
sns.relplot(kind="scatter") |
scatterplot bilan bir xil, lekin subplot lar grid ida chiziladi | Sizga col= / row= facet kerak yoki o'z o'lchamini o'zi belgilaydigan figure kerak |
sns.relplot(kind="line") |
lineplot bilan bir xil, subplot lar grid ida | Har bir guruh uchun bitta time series, yonma-yon |
plt.scatter() / plt.plot() |
Sof matplotlib: aggregation yo'q, legend yo'q, label yo'q | To'liq qo'lda nazorat yoki siz allaqachon matplotlib ichida chuqur ishlayotgan bo'lsangiz |
scatterplot, lineplot) bitta matplotlib Axes ga chizadi va o'shani qaytaradi. Figure-level function lar (relplot) butun figure ni yaratadi va egallaydi hamda FacetGrid qaytaradi.15.1 scatterplot
sns.scatterplot() DataFrame ning har bir row i uchun bitta marker chizadi. Hech narsa aggregate qilinmaydi, hech narsa silliqlanmaydi, x yoki y qiymati yetishmayotganlaridan tashqari hech qanday row tashlab yuborilmaydi.
sns.scatterplot(data=tips, x="total_bill", y="tip") plt.show()
Eng sodda scatterplot: har bir nuqta — bitta hisob.
Nima ko'rasiz: 244 ta ko'k nuqta. x axis bo'ylab hisoblar taxminan 3 dan 51 dollargacha, y axis bo'ylab tip lar 1 dan 10 gacha. Bulut yuqoriga qiya ketadi — katta hisoblarga katta tip beriladi — va o'ngga qarab yoyilib boradi (hisob o'sgani sari variance ham o'sadi). Bir necha nuqta bulutdan aniq yuqorida turadi: kichik hisobga saxiy tip berganlar. x label total_bill, y label esa tip deb yoziladi — to'g'ridan-to'g'ri column nomlaridan olingan.
Scatterplot ni o'qish: e'tibor beriladigan to'rt narsa
- Yo'nalish — y x bilan ko'tariladimi yoki tushadimi? Bu yerda ko'tariladi, demak correlation musbat (Pearson r taxminan 0.68).
- Shakl — to'g'ri chiziqmi, egri chiziqmi yoki umuman shaklsizmi?
tipsda taxminan linear. - Kuch / tarqoqlik — tor tasma kuchli bog'liqlikni, semiz bulut esa kuchsizini bildiradi. Bu yerdagi voronka shakliga e'tibor bering: bu heteroscedasticity va agar talaba keyinchalik bu data ga ordinary least squares fit qilsa, bu muhim bo'ladi.
- Outlier lar va tuzilma — ajralib turgan nuqtalar, bo'shliqlar, yo'l-yo'llar.
tipsda butun dollarli tip larda xira gorizontal yo'llarni ko'rish mumkin: odamlar yaxlitlaydi.
Amalda ishlatadigan parametrlar
| Parametr | Ma'nosi | Odatiy qiymat |
|---|---|---|
data |
DataFrame | tips |
x, y |
Ikki axis uchun column nomlari (string) | "total_bill" |
hue |
Marker rangiga map qilinadigan column | "sex" |
size |
Marker yuzasi ga map qilinadigan column | "size" |
style |
Marker shakli ga map qilinadigan column | "time" |
s |
Kvadrat point da o'lchanadigan bitta qat'iy marker yuzasi (matplotlib kwarg) | s=15 |
alpha |
Shaffoflik, 0 dan 1 gacha — overplotting ga qarshi birinchi chora | alpha=0.4 |
palette |
hue uchun rang sxemasi |
"deep", "viridis" |
sizes |
size uchun (min, max) marker yuzasi diapazoni |
(20, 200) |
markers |
style uchun marker shakllari |
["o", "X"] |
legend |
"auto", "brief", "full" yoki False |
"brief" |
ax |
Chizish uchun mavjud matplotlib Axes | ax=axes[0] |
size="size" DataFrame dagi size nomli column ni (tips da stol atrofidagi odamlar soni) marker yuzasiga map qiladi va legend qo'shadi. Kichik harfli s=60 esa matplotlib keyword i bo'lib, har bir marker uchun bitta qat'iy yuza belgilaydi va legend ga hech narsa qo'shmaydi. Talabalar bularni doim aralashtirib yuboradi, ustiga-ustak tips da rostdan ham size degan column bor, shuning uchun chalkashlik ikki barobar.
Mavjud figure ichiga chizish
scatterplot axes-level bo'lgani uchun oddiy matplotlib bilan birga ishlaydi. Ko'p panelli layout ni qo'lda shunday quriladi:
fig, axes = plt.subplots(1, 2, figsize=(11, 4)) sns.scatterplot(data=penguins, x="bill_length_mm", y="bill_depth_mm", ax=axes[0]) sns.scatterplot(data=penguins, x="flipper_length_mm", y="body_mass_g", ax=axes[1]) axes[0].set_title("Bill shape") axes[1].set_title("Flipper vs mass") fig.tight_layout() plt.show()
Ikkala panel ham penguins dan foydalanadi. Chap panel species bo'yicha ranglamaguningizcha shaklsiz dog'ga o'xshab turadi — bu kichraytirilgan Simpson paradoksi va 15.3 bo'lim buni tuzatadi. O'ng panel esa toza yuqoriga yo'nalgan tasma: flipper uzunroq bo'lsa, qush og'irroq.
ax = sns.scatterplot(...) matplotlib Axes ni qaytaradi. Shundan keyin barcha matplotlib metodlari qo'lingizda: ax.set_xlim(0, 60), ax.axhline(tips["tip"].mean(), color="red", ls="--"), ax.set_title("Tips vs bill"). Bu axes-level function lar haqidagi eng foydali fakt.
15.2 lineplot
sns.lineplot() nuqtalarni x ning o'sish tartibida to'g'ri kesmalar bilan bog'laydi. Uni x da ma'noli tartib bo'lganda — vaqt, doza, harorat, index — va ketma-ket nuqtalar orasidagi bog'lanish biror ma'no anglatganda ishlating.
sns.lineplot(data=flights, x="year", y="passengers") plt.show()
lineplot takrorlanuvchi x qiymatlarni o‘rtachaga jamlaydi va 95% confidence interval ni soyalaydi. Band — data ning tarqoqligi emas, o‘rtachaning noaniqligi.
Nima ko'rasiz: 1949 da taxminan 125 (mingta) yo'lovchidan 1960 da taxminan 475 gacha ko'tariladigan bitta chiziq, ustiga uning atrofida vaqt o'tishi bilan kengayib boradigan yarim shaffof band. Bu band sizning data ngizda yo'q. U qayerdan kelib chiqishini tushunish — bu bobdagi eng muhim g'oya.
lineplot default bo'yicha aggregate qiladi
flights DataFrame ida 144 ta row bor: 12 yilning har biri uchun 12 oydan. Demak x="year" uchun x = 1949 da o'nikkita passengers qiymati, x = 1950 da yana o'nikkita va hokazo. Chiziq esa har bir x uchun faqat bitta y dan o'ta oladi, shuning uchun seaborn quyidagini qiladi:
estimator="mean" qiymatini hisoblaydi, so'ng o'sha mean atrofida n_boot=1000 ta bootstrap resample asosida errorbar=("ci", 95) band ini chizadi.Ya'ni chiziq — yiliga to'g'ri keladigan o'rtacha oylik yo'lovchilar soni, band esa o'sha mean uchun 95% confidence interval. Band vaqt o'tishi bilan kengayadi, chunki aviatsiya sanoati o'sgani sari yil ichidagi mavsumiy o'zgaruvchanlik ham ortadi — data ishonchsizroq bo'lib qolgani uchun emas.
# Chiziq haqiqatan mean ekaniga o'zingiz ishonch hosil qiling: print(flights.groupby("year")["passengers"].mean().head(3)) # year # 1949 126.666667 # 1950 139.666667 # 1951 170.166667
year 1949 126.666667 1950 139.666667 1951 170.166667 Name: passengers, dtype: float64
Xom 144 ta nuqtani aggregation siz chizish uchun yo har bir oyga alohida chiziq bering, yo estimator ni o'chiring:
# Har bir oyga bitta chiziq: 12 ta chiziq, aggregation kerak emas sns.lineplot(data=flights, x="year", y="passengers", hue="month") # Yoki aggregation ni butunlay o'chiring (har bir xom nuqtadan zig-zag o'tadi) sns.lineplot(data=flights, x="year", y="passengers", estimator=None)
estimator=None bilan tishli arra ko'rinishidagi chiziq olasiz: chiziq endi saralangan x tartibida har bir xom observation ga borgani uchun har yil ichida o'n ikki marta yuqoriga-pastga sakraydi. Bu xunuklik halol — u sizga x o'zgaruvchi unikal emasligini aytmoqda.
lineplot ni sinf jurnali deb tasavvur qiling. Siz "1951 da ball qancha edi?" deb so'raysiz va javob bergan o'n ikkita o'quvchi bor. scatterplot sizga o'n ikkita javobning hammasini alohida nuqta qilib ko'rsatadi. lineplot esa sinf o'rtachasini aytadi va o'sha o'rtachaga qanchalik ishonch borligini ko'rsatuvchi error bar chizadi. Ikkalasi ham noto'g'ri emas — lekin chiziqni o'sha o'n ikkita javob deb o'ylasangiz, plot ni noto'g'ri o'qigan bo'lasiz.
To'g'ri index langan time series
x har bir row uchun unikal bo'lsa, hech qanday aggregation bo'lmaydi va hech qanday band paydo bo'lmaydi:
import pandas as pd # To'g'ri oylik date index quramiz: har bir (year, month) uchun bitta row fl = flights.copy() fl["date"] = pd.to_datetime( fl["year"].astype(str) + "-" + fl["month"].astype(str), format="%Y-%b" ) sns.lineplot(data=fl, x="date", y="passengers") plt.show()
Endi haqiqiy series ni ko'rasiz: ko'tarilayotgan trend ustiga kuchli mavsumiy to'lqin, har iyul va avgustda cho'qqi, har noyabrda tushish. Confidence band yo'q, chunki har bir sanaga aniq bitta observation to'g'ri keladi. Mavsumiylikni o'rgatayotganda sinfga aynan shu versiyani ko'rsatasiz.
Bilishga arziydigan lineplot parametrlari
| Parametr | Ma'nosi |
|---|---|
estimator |
Takrorlanuvchi x uchun aggregation: "mean" (default), "median", "sum", istalgan callable yoki o'chirish uchun None |
errorbar |
Noaniqlik band i: default ("ci", 95), "sd", ("se", 1), ("pi", 50) yoki None |
err_style |
"band" (default, soyalangan lenta) yoki "bars" (diskret error bar lar) |
sort |
Default True — chizishdan oldin row larni x bo'yicha saralaydi. Trayektoriyalar uchun False qiling |
units |
Takroriy o'lchov subyektlarini aniqlovchi column; estimator=None bilan har biriga bitta xira chiziq chizadi |
markers, dashes |
Nuqta marker larini ko'rsatish; style uchun dash pattern larini boshqarish |
n_boot, seed |
CI uchun bootstrap resample lar soni va takrorlanuvchanlik uchun seed |
orient |
Boshqa axis bo'ylab aggregate qilish uchun "x" (default) yoki "y" |
Agar siz yo'lni chizsangiz — robotning marshruti, gisterezis sirtmog'i, iterativ optimizer ning qadamlari — row lar tartibining o'zi ma'lumotdir. lineplot avval x bo'yicha saralaydi va bu yo'lni monoton zig-zag ga aylantirib yuboradi. sns.lineplot(..., sort=False, estimator=None) ishlating yoki oddiygina plt.plot() ni chaqiring.
15.3 Uchinchi o'zgaruvchini kodlash: hue, size, style
Ikki axis ikkita o'zgaruvchini ushlaydi. Seaborn sizga o'sha panelning o'zida yana uchta kanal beradi: rang (hue), marker yuzasi (size) va marker shakli yoki dash pattern i (style). Har biri column nomini oladi.
sns.scatterplot( data=penguins, x="bill_length_mm", y="bill_depth_mm", hue="species", # rang: Adelie / Chinstrap / Gentoo style="sex", # marker shakli: Male / Female size="body_mass_g", # marker yuzasi: 2700 g dan 6300 g gacha sizes=(20, 200), # eng kichik va eng katta marker yuzasi alpha=0.8, ) plt.legend(bbox_to_anchor=(1.02, 1), loc="upper left", borderaxespad=0) plt.tight_layout() plt.show()
Bitta grafikda to‘rtta o‘zgaruvchi — va bu allaqachon o‘qish chegarasiga yaqin.
Bu — 15.1 bo'limdagi shaklsiz dog'ni qutqaradigan plot. hue siz bill length va bill depth deyarli bog'liq emasdek ko'rinadi. hue="species" bilan esa uchta toza cluster paydo bo'ladi va har birining qiyaligi musbat: Adelie (kalta, chuqur bill) yuqori chapda, Chinstrap (uzun, chuqur) yuqori o'ngda, Gentoo (uzun, sayoz) pastki o'ngda. Umumlashtirilgan bog'liqlik manfiy, ammo har bir guruh ichidagi bog'liqlik musbat — bu darslik darajasidagi Simpson paradoksi va besh daqiqalik ajoyib ma'ruza mavzusi.
Seaborn o'zgaruvchi turini qanday aniqlaydi
| Column dtype | Qanday qabul qilinadi | Rang xatti-harakati | Legend |
|---|---|---|---|
object / category / bool |
Categorical | Sifat palette si, har bir level ga alohida rang | Har bir level uchun bitta yozuv |
int / float |
Numeric | Uzluksiz colormap (default "ch:" cubehelix ramp) |
Bir nechta vakil tick ("brief") |
Bu aniqlashni bekor qilish mumkin. Numeric column ni categorical sifatida qabul qilishga majburlash uchun uni cast qiling:
# pclass int sifatida saqlangan 1/2/3 -> seaborn uzluksiz ramp yasab qo'yardi sns.scatterplot( data=titanic, x="age", y="fare", hue=titanic["pclass"].astype("category"), # endi 3 ta diskret rang alpha=0.6, )
E'tibor bering, column nomi o'rniga Series uzatish mumkin. Seaborn legend sarlavhasi uchun Series ning name atributidan foydalanadi, shuning uchun legend baribir "pclass" deb o'qiladi.
Qaysi o'zgaruvchiga qaysi kanal
hue— eng kuchli va eng oson o'qiladigan kanal. Unga eng muhim guruhlovchi o'zgaruvchingizni bering. 6 ta level yoki undan kam bilan cheklaning; undan ortiqda ranglarni farqlab bo'lmay qoladi.size— idrok jihatidan kuchsiz. Odam yuzani yomon baholaydi va kichik marker lar ko'zdan yo'qoladi. Uni faqat taxminiy kattalik uchun (aholi, massa) qoldiring, aniq taqqoslash uchun hech qachon ishlatmang.style— scatter uchun eng kuchsizi (kichik o'lchamda shakllarni ajratish qiyin), lekin chiziqlar uchun juda yaxshi, chunki u yerda solid / dashed / dotted ga aylanadi. 4 ta level bilan cheklang.
Bosma tarqatma materiallar, yomon proyeksiya qilingan slayd lar yoki rangni ajrata olmaydigan talabalar uchun bitta column ni ikkita kanalga map qiling: hue="species", style="species". Endi guruhlar ham rang, ham shakl bo'yicha farq qiladi, shuning uchun figure oq-qora bosmada ham saqlanib qoladi. Seaborn ularni avtomatik ravishda bitta legend ga birlashtiradi.
Palette ni boshqarish
# Nomlangan sifat palette si sns.scatterplot(data=penguins, x="flipper_length_mm", y="body_mass_g", hue="species", palette="Set2") # Aniq dict: turli figure larda bir guruhga bir xil rangni kafolatlaydi species_colors = {"Adelie": "#4C72B0", "Chinstrap": "#DD8452", "Gentoo": "#55A868"} sns.scatterplot(data=penguins, x="flipper_length_mm", y="body_mass_g", hue="species", palette=species_colors) # Uzluksiz hue: ketma-ket colormap va cheklangan diapazon sns.scatterplot(data=tips, x="total_bill", y="tip", hue="size", palette="viridis", hue_norm=(1, 6))
Uzunligi hue level lari soniga mos kelmaydigan ranglar list ini uzatsangiz, ValueError: The palette list has the wrong number of colors xatosi chiqadi. Dict xavfsizroq: u level nomi bo'yicha kalitlanadi, shuning uchun yetishmayotgan level larga chidamli va data ni filter qilganingizda ham ranglarni barqaror saqlaydi.
15.4 relplot hamda axes-level va figure-level
sns.relplot() — o'sha ikki plot ga figure-level interfeys. Uning kind argumenti qaysi birini tanlashni belgilaydi:
sns.relplot(data=tips, x="total_bill", y="tip", kind="scatter") # default sns.relplot(data=flights, x="year", y="passengers", kind="line")
relplot figure-level, shuning uchun col="time" data ni panellarga bo‘ladi — buni yolg‘iz scatterplot qila olmaydi.
O'z-o'zicha bu axes-level chaqiruvdan yaxshiroq emas. relplot ning mavjud bo'lish sababi — faceting: data ni col= va row= yordamida kichik ko'p nusxalarga bo'lish.
g = sns.relplot( data=tips, x="total_bill", y="tip", hue="smoker", col="time", # har bir level ga bitta column: Lunch, Dinner row="sex", # har bir level ga bitta row: Male, Female height=3.5, # HAR BIR facet ning inch dagi balandligi aspect=1.2, # kenglik = balandlik * aspect ) g.figure.suptitle("Tipping by time of day and sex", y=1.03) g.set_axis_labels("Total bill ($)", "Tip ($)") g.set_titles("{row_name} — {col_name}") plt.show()
Siz 2 ga 2 grid olasiz, to'rttala panel bir xil x va y chegaralarini baham ko'radi, shuning uchun ko'z ularni bevosita taqqoslay oladi, butun figure ning o'ng tomonida esa bitta umumiy legend joylashadi. Dinner panellari lunch panellariga qaraganda sezilarli zichroq; male-dinner panelida eng katta hisoblar bor.
Ikki interfeys yonma-yon
Axes-level (scatterplot, lineplot) |
Figure-level (relplot) |
|
|---|---|---|
| Nima qaytaradi | matplotlib.axes.Axes |
seaborn.FacetGrid |
| Figure ga egalik qiladimi? | Yo'q — joriy yoki berilgan axes ga chizadi | Ha — o'z figure ini yaratadi |
| Faceting | Mavjud emas | col=, row=, col_wrap= |
| O'lchamni boshqarish | plt.subplots(figsize=(8, 5)) |
Har bir facet uchun height= va aspect= |
ax= qo'llab-quvvatlanadimi |
Ha | Yo'q — TypeError beradi |
| Legend joylashuvi | Axes ichida | Grid tashqarisida, umumiy |
| Sarlavha | ax.set_title(...) |
g.figure.suptitle(...) |
| Axis label lari | ax.set_xlabel(...) |
g.set_axis_labels(x, y) |
| Nima uchun eng yaxshi | Boshqa matplotlib kontenti bilan birlashtirish | Mustaqil tadqiqiy kichik ko'p nusxalar |
Foydali FacetGrid metodlari
g = sns.relplot(data=penguins, x="flipper_length_mm", y="body_mass_g", hue="species", col="island", col_wrap=2, height=3.5) g.set_axis_labels("Flipper length (mm)", "Body mass (g)") g.set_titles("Island: {col_name}") g.set(xlim=(160, 240), ylim=(2000, 7000)) # har bir facet ga qo'llanadi g.figure.suptitle("Penguin size by island", y=1.02) g.legend.set_title("Species") g.tight_layout() g.savefig("penguins.png", dpi=150)
Atribut / metodNima qiladi
g.figureAsosidagi matplotlib Figure (g.fig eski alias)
g.axesAxes obyektlarining 2 o'lchamli numpy array i
g.axes_dictFacet qiymati bo'yicha kalitlangan dict — bitta panelga yetib borishning toza yo'li
g.set_titles(template)O'rin egallovchilar: {col_name}, {row_name}, {col_var}
g.set(...)Istalgan Axes setter ini har bir facet ga uzatadi
g.map_dataframe(fn, ...)Har bir facet ga qo'shimcha qatlam chizadi
g.refline(y=0)Barcha facet larga mos yozuvlar chizig'ini qo'shadi
g.legendUmumiy legend obyekti (legend=False bo'lsa None)
Bitta facet ga murojaat qilish, masalan faqat Dream orollari panelini izohlash uchun:
ax = g.axes_dict["Dream"]
ax.axhline(4000, color="grey", ls="--", lw=1)
ax.text(165, 4100, "4 kg reference", fontsize=8, color="grey")
col_wrap=3 uzun facet lentasini uchtalik row larga o'raydi. U faqat row= berilmaganda ishlaydi — ikki o'lchamli grid ni o'rab bo'lmaydi. Uni ko'p level li narsa bo'yicha facet qilganda ishlating, masalan col="day" yoki 12 level li oy o'zgaruvchisi.
15.5 lineplot aggregation va errorbar band i
lineplot atrofidagi soyalangan lenta errorbar= bilan boshqariladi, u seaborn 0.12 da eski ci= parametrini almashtirgan. U yo string, yo (method, level) tuple qabul qiladi.
| Qiymat | Lenta nimani ko'rsatadi | n o'sgani sari torayadimi? | Qachon ishlatiladi |
|---|---|---|---|
("ci", 95) (default) |
Mean ning bootstrap 95% confidence interval i | Ha | Siz mean haqida da'vo qilyapsiz |
("ci", 68) |
68% CI — taxminan bitta standart xatolik | Ha | Psixofizika va neyrotasvirlashda keng tarqalgan |
"se" = ("se", 1) |
Mean ning ±1 standart xatoligi, analitik hisoblanadi | Ha | Sizga tezlik va parametrik interval kerak |
"sd" = ("sd", 1) |
Observation larning ±1 standart chetlanishi | Yo'q | Siz data ning tarqoqligini ta'riflayapsiz |
("pi", 50) |
Percentile interval — xom qiymatlarning 25 dan 75 persentiligacha | Yo'q | Qiyshiq taqsimlangan data; noparametrik tarqoqlik |
None |
Umuman band yo'q | — | Katta data yoki band ma'nosiz bo'lganda |
fig, axes = plt.subplots(1, 3, figsize=(14, 4), sharey=True) sns.lineplot(data=flights, x="year", y="passengers", errorbar=("ci", 95), ax=axes[0]) axes[0].set_title('errorbar=("ci", 95) — CI of the mean') sns.lineplot(data=flights, x="year", y="passengers", errorbar="sd", ax=axes[1]) axes[1].set_title('errorbar="sd" — spread of the data') sns.lineplot(data=flights, x="year", y="passengers", errorbar=None, ax=axes[2]) axes[2].set_title("errorbar=None — mean only") fig.tight_layout() plt.show()
Uchala chiziq bir xil; faqat lentalar farq qiladi. "sd" lentasi ("ci", 95) lentasidan sezilarli kengroq, chunki yiliga n = 12 oy bo'lganda standart xatolik standart chetlanishning 12 ning kvadrat ildiziga bo'lingani, ya'ni taxminan uchdan bir kenglikda bo'ladi. Data miqdorini ikki barobar oshirsangiz, CI lentasi torayadi, SD lentasi esa yo'q — butun farq shunda va bu tez-tez uchraydigan intervyu savoli.
Maxsus estimator lar va har bir subyekt uchun chiziqlar
# Mean o'rniga median, noparametrik interval bilan sns.lineplot(data=flights, x="year", y="passengers", estimator="median", errorbar=("pi", 50)) # Callable estimator ham ishlaydi import numpy as np sns.lineplot(data=flights, x="year", y="passengers", estimator=lambda s: np.percentile(s, 90), errorbar=None) # units=: har bir oyga bitta xira chiziq, aggregation yo'q sns.lineplot(data=flights, x="year", y="passengers", units="month", estimator=None, alpha=0.4)
units pattern i takroriy o'lchov data sini ko'rsatishning standart usuli: har bir subyekt uchun bitta ingichka yarim shaffof chiziq, shunda o'quvchi faqat guruh o'rtachasini emas, balki alohida trayektoriyalarni ham ko'radi. Ikkalasini ustma-ust qo'yish esa eng yaxshi variant:
ax = sns.lineplot(data=flights, x="year", y="passengers", units="month", estimator=None, alpha=0.25, color="grey", legend=False) sns.lineplot(data=flights, x="year", y="passengers", errorbar=("ci", 95), color="crimson", lw=2.5, ax=ax) ax.set_title("Individual months (grey) and the yearly mean (red)") plt.show()
Bootstrap ning narxi
Default CI data ni har bir unikal x qiymati uchun n_boot=1000 marta qayta namuna olish orqali hisoblanadi. 5000 ta har xil timestamp li series da bu besh million resample degani va plot ko'p soniyalar davomida qotib qoladi. Uchta chora, afzalligi bo'yicha tartibda:
errorbar=None— x unikal bo'lgan series da band ni baribir xohlamagan bo'lsangiz kerak.errorbar="se"yokierrorbar="sd"— analitik hisoblanadi, bootstrap yo'q.n_boot=200, seed=0— kamroq resample va takrorlanadigan natija.
sns.lineplot(..., ci=95) seaborn 0.12 va 0.13 da hali ishlaydi, lekin FutureWarning chiqaradi va olib tashlanadi. ci="sd" — errorbar="sd" ning eski yozilishi, ci=None esa errorbar=None niki. 2022 yildan oldin yozilgan o'quv materiallarini yangilang — eski Stack Overflow javoblarini ko'chirayotgan talabalar bunga duch keladi.
15.6 Tuzoqlar
1. Katta data da overplotting
244 ta row da scatterplot yaxshi. 50 000 ta row da esa u qattiq qora dog'ga aylanadi va taqsimotning shakli ko'rinmay qoladi — marker laringizning 80% i yuqori qatlam ostida yashiringan bo'lishi mumkin.
big = tips.sample(50_000, replace=True, random_state=0) # katta dataset ni simulyatsiya qilamiz # 1-chora: shaffoflik + kichik marker lar. Zichlik qoramtirlik orqali ko'rinadi. sns.scatterplot(data=big, x="total_bill", y="tip", alpha=0.02, s=8, edgecolor=None) # 2-chora: tasodifiy qismini chizing — odatda shaklni ko'rishga yetarli sns.scatterplot(data=big.sample(2000, random_state=0), x="total_bill", y="tip", alpha=0.4) # 3-chora: nuqta chizish o'rniga bin lang (2 o'lchamli histogram) sns.histplot(data=big, x="total_bill", y="tip", bins=40, cbar=True) # 4-chora: 2 o'lchamli zichlik bahosining kontur lari sns.kdeplot(data=big, x="total_bill", y="tip", fill=True, levels=8)
Overplotting ning alohida turi diskret numeric x da yuz beradi, masalan tips["size"] (qiymatlari 1 dan 6 gacha). Har bir nuqta oltita vertikal chiziqdan biriga tushadi va chiziqda 5 ta nuqta bormi yoki 500 tami — bilib bo'lmaydi. Yechim — jitter, lekin scatterplot uni taqdim etmaydi — sns.stripplot(..., jitter=0.25) dan foydalaning yoki shovqinni o'zingiz qo'shing:
sns.stripplot(data=tips, x="size", y="tip", jitter=0.25, alpha=0.5)
- lineplot ning sassiz aggregate qilishi va band ni data deb o'ylash
Bu 15.2 da ko'rib chiqilgan edi, lekin takrorlashga arziydi, chunki bu eng ko'p uchraydigan noto'g'ri o'qish. Talabalar sns.lineplot(data=tips, x="size", y="tip") ni chaqiradi, lentali silliq chiziqni ko'radi va uni "tip lar" deb ta'riflaydi. Aslida bu oltita mean va oltita bootstrap interval. Doim so'rang: bu DataFrame da x unikalmi?
# Diagnostika: takrorlanuvchi x qiymatlari bormi? print(tips["size"].duplicated().any()) # True -> lineplot AGGREGATE QILADI print(tips.groupby("size").size()) # har bir x ga nechta row to'g'ri keladi
True size 1 4 2 156 3 38 4 37 5 5 6 4 dtype: int64
- Uzluksiz o'zgaruvchida hue
Ko'p xil qiymatli numeric column ni hue ga map qilish ko'z deshifrlay olmaydigan rang ramp ini beradi, agar seaborn legend="full" ga o'tib ketsa, plot ni butunlay siqib qo'yadigan yuzlab yozuvli legend olishingiz mumkin.
# Yomon: fare da ~250 ta har xil qiymat bor sns.scatterplot(data=titanic, x="age", y="fare", hue="fare") # Yaxshiroq 1: uni tartiblangan kategoriyalarga bin lang t = titanic.copy() t["fare_band"] = pd.qcut(t["fare"], 4, labels=["Q1", "Q2", "Q3", "Q4"]) sns.scatterplot(data=t, x="age", y="fare", hue="fare_band", palette="viridis") # Yaxshiroq 2: uzluksiz qoldiring, legend ni olib tashlang, haqiqiy colorbar qo'shing fig, ax = plt.subplots() sns.scatterplot(data=titanic, x="age", y="fare", hue="fare", palette="viridis", legend=False, ax=ax) norm = plt.Normalize(titanic["fare"].min(), titanic["fare"].max()) sm = plt.cm.ScalarMappable(cmap="viridis", norm=norm) fig.colorbar(sm, ax=ax, label="Fare") plt.show()
plt.scatter(c=...) dan farqli o'laroq, seaborn ning relational function lari uzluksiz hue uchun hech qachon colorbar yaratmaydi. Ular buning o'rniga bir nechta namunaviy qiymatli legend hosil qiladi. Sizga haqiqiy colorbar kerak bo'lsa, yuqoridagidek ScalarMappable ni o'zingiz qurishingiz va fig.colorbar ga ax= uzatishni unutmasligingiz kerak — uni tashlab ketish so'nggi matplotlib versiyalarida xato beradi.
4. relplot dan keyin plt.title() noto'g'ri ish qiladi
g = sns.relplot(data=tips, x="total_bill", y="tip", col="day") plt.title("Tips by day") # NOTO'G'RI: faqat OXIRGI facet ga sarlavha qo'yadi plt.xlabel("Bill") # NOTO'G'RI: faqat OXIRGI facet ga label qo'yadi
plt.title() joriy axes ustida ishlaydi, relplot dan keyin esa joriy axes — oxirgi chizilgan facet, bu yerda yakshanba. Sizning sarlavhangiz to'rttadan bitta kichik panelga tushadi. Figure-level ekvivalentlari quyidagilar:
g = sns.relplot(data=tips, x="total_bill", y="tip", col="day", col_wrap=2) g.figure.suptitle("Tips by day", y=1.02) # butun figure uchun sarlavha g.set_axis_labels("Total bill ($)", "Tip ($)") # tashqi facet lardagi label lar g.set_titles("{col_name}") # har bir facet uchun sarlavha g.tight_layout()
Xuddi shu mantiq relplot dan oldin yozilgan plt.figure(figsize=(12, 6)) nega hech nima qilmasligini tushuntiradi: relplot o'z figure ini yaratadi va sizniknisiga e'tibor bermaydi (ortidan bo'sh figure qoldirib ketadi). Figure-level plot ning o'lchamini height va aspect bilan belgilang.
5. DataFrame o'rniga numpy array uzatish
import numpy as np x = np.random.normal(size=200) y = 2 * x + np.random.normal(size=200) sns.scatterplot(x=x, y=y) # ishlaydi, lekin ikkala axis label i ham bo'sh
Vektorlar qabul qilinadi, lekin numpy array ning nomi yo'q, shuning uchun seaborn axis larni label lay olmaydi va siz avtomatik legend sarlavhalaridan ayrilasiz. Ikkita chora:
# A chorasi: nomlangan pandas Series uzating sx = pd.Series(x, name="predictor") sy = pd.Series(y, name="response") sns.scatterplot(x=sx, y=sy) # axis lar label langan # B chorasi (afzalroq): DataFrame quring va column nomlaridan foydalaning df = pd.DataFrame({"predictor": x, "response": y}) sns.scatterplot(data=df, x="predictor", y="response")
- load_dataset ga internet kerak
sns.load_dataset("tips") seaborn-data GitHub repository sidan CSV yuklab oladi. Cheklangan laboratoriya kompyuterida, imtihon tarmog'ida yoki samolyotda u URLError yoki socket timeout beradi va butun sinf birinchi cell da to'xtab qoladi.
# CSV larni interneti bor kompyuterda bir marta cache qiling: for name in ["tips", "penguins", "flights", "titanic"]: sns.load_dataset(name).to_csv(f"data/{name}.csv", index=False) # Keyin offline holatda ularni lokal o'qing: tips = pd.read_csv("data/tips.csv") flights = pd.read_csv("data/flights.csv")
Bilishga arziydigan ikki tafsilot. Birinchidan, seaborn yuklab olganlarini allaqachon ~/seaborn-data da cache qiladi (sns.load_dataset(name, data_home="./seaborn-data") bilan o'zgartiriladi), shuning uchun notebook ni bir marta ishga tushirgan kompyuter keyinchalik offline ham ishlaydi. Ikkinchidan, load_dataset xom CSV da yo'q kichik tuzatishlarni qo'llaydi — masalan u flights["month"] ni tartiblangan categorical qiladi, shunda oylar kalendar tartibida chiziladi. pd.read_csv dan keyin buni o'zingiz tiklashingiz kerak:
month_order = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] flights["month"] = pd.Categorical(flights["month"], categories=month_order, ordered=True)
- Nomlashga arziydigan mayda tuzoqlar
Yetishmayotgan qiymatlar sassiz tashlab yuboriladi. penguins da o'lchovlari yo'q 2 ta row va sex i yo'q 11 ta row bor. style="sex" qo'shish 11 ta nuqtani sekingina olib tashlaydi. Chizishdan oldin penguins.isna().sum() bilan tekshiring.
Legend yozuvlari o'zgaruvchilarni aralashtiradi. hue, size va style ni bir vaqtda ishlatish uchta kichik sarlavhali baland, ustma-ust legend hosil qiladi va u axes dan oson toshib ketadi. Uni tashqariga chiqaring: plt.legend(bbox_to_anchor=(1.02, 1), loc="upper left").
Wide-form data. x/y siz keng DataFrame ni data= ga uzatish seaborn ni har bir column ni index ga qarshi chizishga majbur qiladi. Qulay, lekin siz long-form ni nazarda tutgan bo'lsangiz, ma'nosiz plot olasiz. Avval df.melt() qiling.
Ustma-ust chaqiruvlar axes ni baham ko'radi. Bitta cell dagi ikkita scatterplot chaqiruvi bir xil axes ga chizadi — ba'zan bu siz xohlagan narsa, ko'pincha esa kutilmagan hodisa. Ular orasida plt.figure() ni chaqiring yoki aniq ax= uzating.
lineplot da datetime x. Agar sanalar hali ham string bo'lsa, ular fayl tartibidagi kategoriyalar deb qabul qilinadi va x axis ma'nosiz bo'lib qoladi. Doim avval pd.to_datetime() qiling.
relplot ax= ni qabul qilmaydi. sns.relplot(..., ax=ax) TypeError beradi. Plot mavjud figure ichida kerak bo'lsa, axes-level function dan foydalaning.
15.7 Mashqlar to'plami
import seaborn as sns import matplotlib.pyplot as plt import pandas as pd import numpy as np sns.set_theme(style="whitegrid") tips = sns.load_dataset("tips") penguins = sns.load_dataset("penguins") flights = sns.load_dataset("flights") titanic = sns.load_dataset("titanic") # 1. ODDIY SCATTER # tip ni total_bill ga qarshi chizing. Sarlavhani "Tips vs bill" qilib qo'ying va # qaytarilgan Axes yordamida ikkala axis ni dollar birligi bilan label lang. # So'ng bir jumlada javob bering: bog'liqlik musbatmi yoki manfiy? # 2. hue BILAN UCHINCHI O'ZGARUVCHI QO'SHISH # O'sha plot, "time" (Lunch / Dinner) bo'yicha ranglangan. Qaysi ovqat # eng katta hisoblarni beradi? Legend ni axes tashqarisiga chiqaring: # plt.legend(bbox_to_anchor=(1.02, 1), loc="upper left"). # 3. size VA style BIRGALIKDA # sizes=(20, 200) bilan size="size" (stol atrofidagilar soni) va style="smoker" qo'shing. # Nechta legend bo'limi paydo bo'lishiga va figure nega tiqilib qolishiga e'tibor bering. # 4. OVERPLOTTING NI TUZATISH # big = tips.sample(30_000, replace=True, random_state=0) quring. # Uni uch xil chizing: (a) default, (b) s=8 bilan alpha=0.02, # (c) sns.histplot(..., bins=40, cbar=True). Qaysi biri taqsimotning # zich markazini eng aniq ko'rsatadi? # 5. LINEPLOT VA SASSIZ AGGREGATION # sns.lineplot(data=flights, x="year", y="passengers") ni chizing. # So'ng flights.groupby("year")["passengers"].mean() ni print qiling va # chiziq o'sha mean larga tengligini tasdiqlang. estimator=None bilan qayta chizing # va farqni bir jumlada ta'riflang. # 6. errorbar VARIANTLARI # flights chizig'ini sharey=True bilan 1x3 grid da uch marta chizing: # errorbar=("ci", 95), errorbar="sd", errorbar=None. # Comment da "sd" band i nega eng keng ekanini tushuntiring. # 7. FIGURE-LEVEL FACETING # penguins dan flipper_length_mm ni body_mass_g ga qarshi chizish uchun relplot dan # foydalaning, hue="sex", col="species", height=3.5, aspect=1.1. # g.figure.suptitle() bilan butun figure ga sarlavha bering, g.set_axis_labels() # bilan axis larni qayta nomlang va har bir facet sarlavhasini faqat species # nomiga qo'ying. g.savefig("penguins.png", dpi=150) bilan saqlang. # 8. HAQIQIY TIME SERIES, OFFLINE UCHUN XAVFSIZ # flights uchun year + "-" + month ustida pd.to_datetime (format="%Y-%b") # yordamida to'g'ri date column quring, passengers ni date bo'ylab chizing # va hech qanday confidence band paydo bo'lmaganini tasdiqlang. So'ng DataFrame ni # data/flights.csv ga yozing, pd.read_csv bilan qayta yuklang, tartiblangan # month categorical ni tiklang va plot ni internetsiz qayta hosil qiling.
15.8 Intervyu savollari
S: Seaborn da axes-level va figure-level function o'rtasidagi farq nima?
scatterplot yoki lineplot kabi axes-level function bitta matplotlib Axes ga chizadi, ax= argumentini qabul qiladi va o'sha Axes ni qaytaradi, shuning uchun u boshqa matplotlib kontenti bilan erkin birikadi. relplot kabi figure-level function esa butun figure ni yaratadi va egallaydi, col= va row= faceting ni qo'llab-quvvatlaydi, figsize emas height va aspect bilan o'lchamlanadi, grid tashqarisiga bitta umumiy legend qo'yadi va FacetGrid qaytaradi. Amaliy oqibati shuki, plt.title() axes-level plot da ishlaydi, figure-level da esa faqat oxirgi facet ga sarlavha qo'yadi — u yerda g.figure.suptitle() kerak bo'ladi.
S: Siz sns.lineplot(data=flights, x="year", y="passengers") ni chaqirdingiz va soyalangan band oldingiz. Bu nima va u nega bor?
flights da har yilga o'nikkita row to'g'ri keladi, ya'ni har bir x uchun o'nikkita y qiymati bor. Chiziq esa har bir x da faqat bitta y dan o'ta oladi, shuning uchun seaborn aggregate qiladi: u estimator="mean" ni chizadi va 1000 ta resample dan foydalanib o'sha mean ning bootstrap 95% confidence interval i bo'lgan errorbar=("ci", 95) ni hosil qiladi. Band — yillik mean dagi noaniqlik haqidagi bayonot, kuzatilgan qiymatlar diapazoni emas. Buning o'rniga xom data ni ko'rish uchun estimator=None ishlating, hue="month" qo'shing yoki to'g'ri date column bilan x ni unikal qiling.
S: errorbar=("ci", 95), errorbar="sd" va errorbar=None o'rtasidagi farqni tushuntiring.
("ci", 95) — estimator ning bootstrap qilingan 95% confidence interval i, shuning uchun sample hajmi o'sgani sari torayadi va mean ni qanchalik aniq bilishingizni ta'riflaydi. "sd" — observation larning o'zining plyus-minus bitta standart chetlanishi; u data ning tarqoqligini ta'riflaydi va data ko'paygani bilan toraymaydi. None band ni butunlay o'chiradi, bu ayni paytda bootstrap ni ham o'tkazib yuboradi va katta data uchun yoki x allaqachon unikal bo'lgan series uchun to'g'ri tanlovdir. Bunga yaqin variant ("se", 1) analitik hisoblangan bitta standart xatolikni beradi — talqini CI bilan bir xil, lekin bootstrap dan ancha arzon.
S: 200 000 nuqtali scatterplot ingiz qattiq qora to'rtburchakka aylandi. Buni qanday tuzatasiz?
Har bir nuqtaga sarflanadigan siyohni kamaytiring va zichlik ko'rinishiga yo'l bering: alpha ni taxminan 0.01 dan 0.05 gacha, kichik s va edgecolor=None. Tasodifiy kichik namuna chizing — 2000 dan 5000 gacha nuqta odatda shaklni saqlab qoladi. Yoki tasvirlash usulini butunlay o'zgartiring: 2 o'lchamli histogram uchun sns.histplot(x=..., y=..., bins=50, cbar=True), zichlik konturlari uchun esa sns.kdeplot(x=..., y=..., fill=True). Diskret x da muammo boshqacha — nuqtalar bir necha vertikal chiziqda to'planadi — va yechim sns.stripplot(..., jitter=0.25) orqali jitter qo'shish.
S: hue qachon ishlatilishi kerak va u qachon ishlamay qoladi?
hue — uchta semantic kanalning eng kuchlisi; unga eng muhim guruhlovchi o'zgaruvchingizni bering va taxminan oltita categorical level dan oshirmang. U ko'p xil qiymatli numeric column larda ishlamaydi: seaborn ko'z deshifrlay olmaydigan uzluksiz ramp quradi va avtomatik colorbar qo'shilmaydi. Buni pd.qcut bilan bin lash, category ga cast qilish yoki legend=False qo'yib plt.cm.ScalarMappable orqali haqiqiy colorbar qo'shish bilan tuzating. Shuningdek, style= bilan ortiqcha kodlamasangiz, rangni ajrata olmaydigan o'quvchilar uchun ham ishlamaydi.
S: lineplot da sort=True nima qiladi va uni qachon o'chirasiz?
Default holatda lineplot chizishdan oldin row larni x o'zgaruvchisi bo'yicha saralaydi, shuning uchun chiziq chapdan o'ngga monoton harakatlanadi. Time series va dose-response egri chiziqlari uchun bu to'g'ri. Row lar tartibi ma'no anglatgan har qanday holatda esa bu noto'g'ri — fazoviy trayektoriya, gisterezis sirtmog'i, optimizer ning parametr fazosidagi yo'li — chunki saralash yo'lni buzib yuboradi. sort=False ni estimator=None bilan birga ishlating yoki plt.plot() ga o'ting.
S: numpy array uzatganingizda axis label lari nega yo'qoladi va yechimi nima?
Seaborn axis label larini o'ziga berilgan data ning nomlaridan oladi. Numpy array ning nomi yo'q, shuning uchun label qo'yish uchun hech narsa qolmaydi. Yo vektorlarni nomlangan pd.Series obyektlariga o'rang, yo yaxshirog'i, ularni DataFrame ga joylang va data=df, x="col_a", y="col_b" uzating. DataFrame yo'li sizga hue uchun to'g'ri dtype aniqlash, avtomatik legend sarlavhalari va yetishmayotgan qiymatlar bilan to'g'ri ishlashni ham beradi.
S: Sinf kompyuterlarida sns.load_dataset("tips") ishlamayapti. Nima bo'lyapti va nima qilasiz?
load_dataset GitHub dagi seaborn-data repository sidan CSV yuklab oladi, ya'ni unga tarmoq kerak; firewall ortida yoki offline holatda u URLError beradi yoki timeout ga uchraydi. Seaborn yuklab olganlarini ~/seaborn-data ostida cache qiladi, shuning uchun notebook ni har bir kompyuterda bir marta oldindan ishga tushirish yetarli. Sinf uchun ishonchli yechim esa dataset larni CSV ga eksport qilish, ularni material bilan birga tarqatish va pd.read_csv bilan yuklash — load_dataset qo'shadigan tuzatishlarni, ayniqsa flights["month"] uchun tartiblangan categorical ni tiklashni unutmang.
15.9 Xulosa
scatterplothar bir row uchun bitta marker chizadi va hech qachon aggregate qilmaydi;lineplotnuqtalarni saralangan x tartibida bog'laydi va takrorlanuvchi x qiymatlarini mean hamda noaniqlik band iga aggregate qiladi.lineplotdagi soyalangan lenta default holatdaerrorbar=("ci", 95), ya'ni mean ning bootstrap CI si — bu baho haqidagi bayonot, xom data ning diapazoni emas.errorbar="sd"data ning tarqoqligini ta'riflaydi va n bilan toraymaydi;("ci", level)va"se"bahoni ta'riflaydi va torayadi;errorbar=Noneband ni olib tashlaydi va bootstrap ni o'tkazib yuboradi.hue,sizevastyleqo'shimcha column larni rang, marker yuzasi va marker shakliga map qiladi.hueeng oson o'qiladi,sizeeng qiyin; qulay figure lar uchunhuevastyleni ortiqcha kodlang.relplot— figure-level wrapper: ucol=/row=faceting qo'shadi, o'ziniheightvaaspectbilan o'lchamlaydi vaFacetGridqaytaradi — shuning uchunplt.title()emas,g.figure.suptitle(),g.set_axis_labels()vag.set_titles()dan foydalaning.- Axes-level function lar matplotlib
Axesqaytaradi vaax=ni qabul qiladi; ularni katta figure lar ichida birlashtira olish imkonini beradigan narsa shu.relplotax=ni qabul qilmaydi. - Katta data da oddiy scatterplot lar nuqtalarni yashirib yolg'on gapiradi: buni
alpha, kichikroqs, kichik namuna olish, diskret x uchun jitter yoki 2 o'lchamli histogram / KDE bilan tuzating. - Doim nomlangan column li DataFrame uzating — numpy array laringiz sizni axis label lari, legend sarlavhalari va dtype aniqlashdan mahrum qiladi. Avval
isna().sum()ni tekshiring, chunki seaborn yetishmayotgan row larni sassiz tashlab yuboradi. - Zamonaviy parametrlardan foydalaning: seaborn 0.12 da
errorbar=ci=ni almashtirdi,g.figureesag.figni.
Keyingisi: 16-bob distribution plot lar haqida — histplot, kdeplot va ecdfplot.
Bu bobni bepul o'qidingiz.
Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.