-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlesson_31.html
More file actions
840 lines (768 loc) · 151 KB
/
Copy pathlesson_31.html
File metadata and controls
840 lines (768 loc) · 151 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Lesson 31: Pandas Correlations, Pandas Plotting & Introduction to Matplotlib — Techbase Python</title>
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"><style>
:root{--acc:#059669;--acd:#047857;--acp:#ecfdf5;--acb:rgba(5,150,105,.22);--acs:rgba(5,150,105,.28);
--bg:#f8fafc;--sf:#fff;--br:#e2e8f0;--tx:#0f172a;--t2:#334155;--mu:#64748b;
--D:'Space Grotesk',sans-serif;--B:'Plus Jakarta Sans',sans-serif;--M:'JetBrains Mono',monospace}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-font-smoothing:antialiased}
body{background:var(--bg);color:var(--tx);font-family:var(--B);font-size:18px;line-height:1.8;overflow-x:hidden}
/* NAV */
.l-nav{position:fixed;top:0;left:0;right:0;z-index:200;background:rgba(255,255,255,.97);
backdrop-filter:blur(14px);border-bottom:1px solid var(--br);height:64px;
display:flex;align-items:center;padding:0 1.5rem;justify-content:space-between;
box-shadow:0 1px 8px rgba(0,0,0,.06)}
.nav-logo-wrap{display:flex;align-items:center;gap:.75rem;text-decoration:none}
.nav-logo-img{height:44px;width:auto;display:block;object-fit:contain}
.nav-logo-text{font-family:var(--D);font-weight:700;font-size:.95rem;color:var(--tx);
display:flex;flex-direction:column;line-height:1.2}
.nav-logo-text span.course-lbl{font-size:.65rem;font-weight:600;color:var(--acc);
text-transform:uppercase;letter-spacing:.1em}
.l-nav-back{font-size:.85rem;color:var(--mu);text-decoration:none;font-weight:600;
display:flex;align-items:center;gap:.3rem;transition:color .2s;padding:.4rem .8rem;
border-radius:8px;border:1.5px solid var(--br)}
.l-nav-back:hover{color:var(--acc);border-color:var(--acb)}
.l-nav-lbl{font-family:var(--M);font-size:.72rem;color:var(--mu)}
/* PROGRESS */
.pw{position:fixed;top:64px;left:0;right:0;z-index:199;height:4px;background:var(--br)}
.pb{height:100%;background:linear-gradient(90deg,var(--acc),var(--acd));
transition:width .5s cubic-bezier(.4,0,.2,1);width:0%;position:relative}
.pb::after{content:'';position:absolute;right:0;top:0;bottom:0;width:24px;
background:inherit;filter:brightness(1.4);animation:pg 1.5s ease-in-out infinite}
@keyframes pg{0%,100%{opacity:1}50%{opacity:.35}}
/* HERO */
.l-hero{padding:88px 1.5rem 2.5rem;background:linear-gradient(160deg,#ecfdf5 0%,#f8fafc 55%,#d1fae5 100%);border-bottom:1px solid var(--br)}
.l-hero-in{max-width:880px;margin:0 auto;display:flex;align-items:flex-start;gap:2rem;flex-wrap:wrap}
.l-hero-logo{flex-shrink:0}
.l-hero-logo img{height:80px;width:auto;opacity:.92}
.l-hero-text{flex:1}
.badge{display:inline-flex;align-items:center;border-radius:100px;padding:.25rem 1rem;
font-family:var(--M);font-size:.68rem;letter-spacing:.08em;text-transform:uppercase;
font-weight:700;color:var(--acc);background:var(--acp);
border:1.5px solid var(--acb);margin-bottom:.9rem}
.l-hero h1{font-family:var(--D);font-weight:700;font-size:clamp(1.6rem,4vw,2.4rem);
letter-spacing:-.02em;line-height:1.15;margin-bottom:.5rem}
.l-hero-sub{font-size:1rem;color:var(--mu)}
/* WELCOME BOX */
.wb{background:#fff;border:1.5px solid var(--acb);border-left:5px solid var(--acc);
border-radius:14px;padding:1.5rem 1.8rem;max-width:880px;margin:1.5rem auto 0;
box-shadow:0 2px 14px var(--acs)}
.wb h2{font-family:var(--D);font-weight:700;font-size:1.1rem;color:var(--acd);
margin-bottom:.65rem;display:flex;align-items:center;gap:.45rem}
.wb p,.wb li{font-size:1rem;line-height:1.85;color:var(--t2)}
.wb ul{margin-left:1.3rem;margin-top:.4rem}
.wm{display:flex;gap:.65rem;margin-top:1rem;flex-wrap:wrap}
.wm span{background:var(--acp);color:var(--acd);border:1px solid var(--acb);
border-radius:7px;padding:.25rem .8rem;font-family:var(--M);font-size:.72rem;font-weight:600}
/* PHASE */
.phase{background:var(--sf);border:1.5px solid var(--br);border-radius:16px;
margin-bottom:1.6rem;overflow:hidden;
transition:opacity .35s,filter .35s,transform .35s;
box-shadow:0 2px 10px rgba(0,0,0,.04)}
.phase.locked{opacity:.28;pointer-events:none;filter:blur(2px);transform:scale(.99)}
.ph{padding:1.1rem 1.5rem;background:#f0fdf6;border-bottom:1px solid var(--br);
display:flex;align-items:center;gap:.9rem}
.pn{font-family:var(--M);font-size:.68rem;font-weight:700;letter-spacing:.1em;
text-transform:uppercase;color:var(--acc);white-space:nowrap}
.pt{font-family:var(--D);font-weight:700;font-size:1rem;color:var(--tx);flex:1}
.pc{width:28px;height:28px;border-radius:50%;background:var(--br);flex-shrink:0;
display:flex;align-items:center;justify-content:center;font-size:.85rem;
transition:background .3s,transform .45s}
.pc.done{background:#10b981;color:#fff;transform:scale(1.15) rotate(360deg)}
.pb2{padding:1.8rem 2rem}
/* RICH CONTENT */
.v2-p{margin-bottom:1.1rem;font-size:1rem;color:var(--t2);line-height:1.88}
.v2-h3{font-family:var(--D);font-weight:700;font-size:1.1rem;color:var(--tx);
margin:1.7rem 0 .6rem;border-top:2px solid var(--acp);padding-top:.45rem}
.v2-h4{font-family:var(--D);font-weight:600;font-size:1rem;color:var(--t2);margin:1.1rem 0 .4rem}
.v2-h5,.v2-h6{font-family:var(--D);font-weight:600;font-size:.95rem;color:var(--mu);margin:.8rem 0 .35rem}
.v2-ul,.v2-ol{margin:.65rem 0 1.1rem 1.5rem;font-size:1rem;color:var(--t2);line-height:1.9}
.v2-ul li,.v2-ol li{margin-bottom:.35rem}
.v2-bq{border-left:4px solid var(--acc);background:var(--acp);border-radius:0 12px 12px 0;
padding:1rem 1.3rem;margin:1.1rem 0;font-size:1rem;color:#064e3b;font-style:italic}
.v2-bq p{margin:0;color:inherit}
.v2-hr{border:none;border-top:1px solid var(--br);margin:1.3rem 0}
.v2-table-wrap{overflow-x:auto;margin:1.1rem 0;border-radius:10px;border:1px solid var(--br)}
.v2-table{width:100%;border-collapse:collapse;font-size:.95rem}
.v2-table th{background:var(--acp);color:#064e3b;font-family:var(--D);font-weight:700;
padding:11px 14px;text-align:left;border-bottom:2px solid var(--acb)}
.v2-table td{padding:9px 14px;border-bottom:1px solid var(--br);color:var(--t2);vertical-align:top}
.v2-table tr:last-child td{border:none}
.v2-table tr:hover td{background:var(--acp)}
.pb2 code{background:var(--acp);color:var(--acd);border-radius:5px;padding:2px 7px;
font-family:var(--M);font-size:.85em}
.pb2 a{color:var(--acc);text-decoration:underline;text-underline-offset:2px}
.pb2 strong{color:var(--tx)}
/* CODE BLOCKS */
.v2-code-wrap{margin:1.3rem 0;border-radius:12px;overflow:hidden;
border:1px solid #1e293b;box-shadow:0 5px 20px rgba(0,0,0,.2)}
.v2-code-bar{background:#1e293b;padding:.6rem 1.1rem;display:flex;align-items:center;gap:.4rem}
.v2-dot{width:11px;height:11px;border-radius:50%}
.v2-dot.r{background:#ff5f57}.v2-dot.y{background:#febc2e}.v2-dot.g{background:#28c840}
.v2-code-lang{margin-left:.5rem;font-family:var(--M);font-size:.65rem;color:#64748b;
text-transform:uppercase;letter-spacing:.08em;flex:1}
.copy-btn{background:rgba(255,255,255,.08);color:#94a3b8;border:none;border-radius:6px;
padding:.28rem .7rem;font-family:var(--M);font-size:.68rem;cursor:pointer;
transition:background .2s,color .2s}
.copy-btn:hover{background:rgba(255,255,255,.2);color:#fff}
.copy-btn.copied{background:#10b981;color:#fff}
.v2-code-body{background:#0f172a;padding:1.4rem 1.6rem;overflow-x:auto}
.v2-code-body pre{margin:0}
.v2-code-body code{font-family:var(--M);font-size:.85rem;line-height:2;
color:#e2e8f0;white-space:pre;background:transparent;padding:0;border-radius:0}
/* TASK BOX */
.task-box{background:#d1fae5;border:2px dashed #059669;border-radius:12px;
padding:1.2rem 1.4rem;margin:1.5rem 0}
.task-lbl{font-family:var(--M);font-size:.68rem;font-weight:700;letter-spacing:.1em;
text-transform:uppercase;color:#064e3b;margin-bottom:.55rem;display:flex;align-items:center;gap:.4rem}
.task-body{font-size:1rem;color:#064e3b;line-height:1.85}
.task-body code{background:rgba(0,0,0,.1);border-radius:4px;padding:2px 7px;
font-family:var(--M);font-size:.85em}
/* EXERCISE / CHALLENGE */
.chal-box{background:linear-gradient(135deg,#ecfdf5 0%,#fff 100%);
border:2px solid var(--acc);border-radius:14px;padding:1.3rem 1.5rem;margin-bottom:1.2rem}
.chal-lbl{font-family:var(--M);font-size:.68rem;font-weight:700;letter-spacing:.1em;
text-transform:uppercase;color:var(--acd);margin-bottom:.65rem}
.chal-body{font-size:1rem;color:var(--tx);line-height:1.85}
.chal-body code{background:var(--acp);color:var(--acd);border-radius:4px;
padding:2px 6px;font-family:var(--M);font-size:.85em}
.reveal-btn{display:inline-flex;align-items:center;gap:.5rem;background:transparent;
color:var(--acd);font-family:var(--D);font-weight:700;font-size:.9rem;
padding:.65rem 1.3rem;border-radius:9px;border:2px solid var(--acc);cursor:pointer;
transition:background .2s,color .2s;margin:.65rem 0}
.reveal-btn:hover{background:var(--acc);color:#fff}
.reveal-content{display:none;margin-top:.65rem;animation:fi .3s ease}
.reveal-content.open{display:block}
@keyframes fi{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
/* BUILD IT */
.build-box{background:#f0fdf4;border:2px solid #16a34a;border-radius:16px;
padding:1.8rem;margin:2rem 0;display:none}
.build-box.visible{display:block;animation:fi .4s ease}
.build-lbl{font-family:var(--M);font-size:.68rem;font-weight:700;letter-spacing:.1em;
text-transform:uppercase;color:#15803d;margin-bottom:.5rem}
.build-name{font-family:var(--D);font-weight:700;font-size:1.2rem;color:#14532d;margin-bottom:.7rem}
.build-req{font-size:1rem;color:#166534;line-height:1.85;margin-bottom:.9rem}
.build-req code{background:rgba(22,163,74,.12);border-radius:4px;
padding:2px 7px;font-family:var(--M);font-size:.85em}
.build-req strong{color:#14532d}
/* GITHUB */
.gh-acc{border:1.5px solid var(--br);border-radius:12px;overflow:hidden;margin:1.5rem 0}
.gh-hd{padding:1.1rem 1.3rem;background:#f8fafc;cursor:pointer;
display:flex;align-items:center;justify-content:space-between;
font-family:var(--D);font-weight:600;font-size:.95rem;user-select:none;transition:background .2s}
.gh-hd:hover{background:#f1f5f9}
.gh-bd{display:none;padding:1.3rem;border-top:1px solid var(--br)}
.gh-bd.open{display:block;animation:fi .25s ease}
.gh-st{display:flex;gap:.9rem;margin-bottom:1.1rem;align-items:flex-start}
.gh-n{width:28px;height:28px;border-radius:50%;background:var(--acc);color:#fff;
font-family:var(--D);font-weight:700;font-size:.78rem;
display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:3px}
.gh-st p{font-size:.95rem;color:var(--t2);line-height:1.75}
.gh-st code{background:var(--acp);color:var(--acd);border-radius:4px;
padding:2px 7px;font-family:var(--M);font-size:.85em}
.gh-nop{background:#fef3c7;border:1.5px solid #fde68a;border-radius:10px;
padding:1.1rem 1.3rem;font-size:.95rem;color:#78350f;line-height:1.8;margin-bottom:1.1rem}
/* SESSION END */
.se{background:linear-gradient(135deg,var(--acc),var(--acd));color:#fff;
border-radius:16px;padding:1.8rem 2rem;margin:2rem 0;display:none}
.se.visible{display:block;animation:fi .4s ease}
.se h2{font-family:var(--D);font-weight:700;font-size:1.15rem;margin-bottom:.85rem}
.se ul{list-style:none;display:flex;flex-direction:column;gap:.45rem}
.se li{font-size:.95rem;opacity:.93;display:flex;align-items:center;gap:.5rem}
.ln-btn{display:inline-flex;align-items:center;gap:.4rem;background:var(--sf);
color:var(--t2);font-family:var(--D);font-weight:600;font-size:.88rem;
padding:.7rem 1.3rem;border-radius:8px;text-decoration:none;
border:1.5px solid var(--br);transition:border-color .2s,color .2s}
.ln-btn:hover{border-color:var(--acc);color:var(--acc)}
.ln-btn.primary{background:var(--acc);color:#fff;border-color:var(--acc)}
.ln-btn.primary:hover{opacity:.9}
.ln{display:flex;align-items:center;justify-content:space-between;
padding-top:1.5rem;border-top:1px solid rgba(255,255,255,.25);
margin-top:1.5rem;flex-wrap:wrap;gap:.75rem}
/* UNLOCK BUTTON */
.ub{display:inline-flex;align-items:center;gap:.5rem;background:var(--acc);
color:#fff;font-family:var(--D);font-weight:700;font-size:.95rem;
padding:.8rem 1.7rem;border-radius:10px;border:none;cursor:pointer;
transition:transform .2s,box-shadow .2s;box-shadow:0 4px 14px var(--acs);margin-top:1.3rem}
.ub:hover{transform:translateY(-2px);box-shadow:0 8px 22px var(--acs)}
.ub:active{transform:scale(.97)}
/* TOAST */
#toast{position:fixed;bottom:95px;right:1.5rem;z-index:999;background:#1e293b;color:#fff;
border-radius:10px;padding:.8rem 1.3rem;font-family:var(--D);font-size:.9rem;
font-weight:600;box-shadow:0 8px 26px rgba(0,0,0,.25);
transform:translateY(20px);opacity:0;transition:all .3s;pointer-events:none}
#toast.show{transform:translateY(0);opacity:1}
/* GO TO TOP */
#go-top{position:fixed;bottom:1.5rem;right:1.5rem;z-index:300;
width:48px;height:48px;border-radius:50%;background:var(--acc);color:#fff;
border:none;cursor:pointer;font-size:1.2rem;box-shadow:0 4px 16px var(--acs);
display:flex;align-items:center;justify-content:center;
opacity:0;transform:translateY(10px);transition:opacity .3s,transform .3s,box-shadow .2s;
pointer-events:none}
#go-top.visible{opacity:1;transform:translateY(0);pointer-events:auto}
#go-top:hover{box-shadow:0 8px 26px var(--acs);transform:translateY(-2px)}
/* CONFETTI */
#cc{position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:998;display:none}
/* FOOTER */
.lf{display:flex;align-items:center;justify-content:center;gap:1rem;
padding:1.6rem 1.5rem;border-top:1px solid var(--br);background:var(--sf)}
.lf img{height:32px;width:auto;opacity:.7}
.lf-text{font-family:var(--M);font-size:.75rem;color:var(--mu)}
</style>
</head>
<body>
<nav class="l-nav">
<a href="../index.html" class="nav-logo-wrap">
<img src="data:image/png;base64,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" alt="Techbase" class="nav-logo-img">
<div class="nav-logo-text">
Techbase<span class="course-lbl">Python Course</span>
</div>
</a>
<span class="l-nav-lbl">Lesson 31 of 45</span>
<a href="../index.html" class="l-nav-back">← All Lessons</a>
</nav>
<div class="pw"><div class="pb" id="pbar"></div></div>
<div class="l-hero">
<div class="l-hero-in">
<div class="l-hero-logo">
<img src="data:image/png;base64,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Q99LnXr+/Plv4+LipggEgtxvvvlmiKH3+PXXX89pwnzV5eb+iUOHEDLz588f5+DgkNkgRCySJAXbtm07eezYsT8lEom/uo63gKIo25KSkjb379+faiqtjUQicfvll19iY2JivlCpVC40TQspirIpLy9vdeXKlfX//e9/YxQKhbUZ3MtBKpX6l5aWdjp06NAO3d/lcnlzhULRypysheHh4esiIyOXq8FBIYS4JSUl3rdv355t7H0QQphCoXBTKivm26IoSiSXy1tqCmga60Mul3vI5fKWAJgfvUmSpK1KpbJTqVR2SqXSRaVSOZAkaUNRlDVJkjbmVnt69OhRqFwubyWXyz1iYmI+o2maY+5GqVAoXOVyefM7d+4sycvL89XhxnyVSuWkUqkcTbyHWKVSOapUKnulUtlMoVA0VyqVzVQqlTNJkmJQidRKRB1xDrhjx47DOTk5Xbhc7ls7O7v0vn377nZycsqQyWR2ycnJA9q1a3cZGImyoyiKt3Xr1nMKhcKBy+XmDRgwYGO7du0uIITw2NjYqTExMbMLCws7bN26NWLJkiV9jS1OCCGN43g5wzDctLS0IUlJSYPatGlzVZs1mxPaqlAobOLj4z/CcVzau3fvP/v27fuXUqm0Sk5ODnFxcXlu7H00VWPVAU3vXYdhmIogiBIzc8oyloThYhhGz58/fwoAACsoKPA8dOjQRgAACAkJ2di+ffvLAAAgEonemrPIb968OReAd2l4GIbhpqSk9GrTps0Nc8ahngM5wzC8/fv37/v66697abitOsJPauy9MAyjFy9ePErzHmFhYTtomuYNGTLklw4dOpwDwHByuXoHkKdPnw7Pzs4OxnFc2rZt27MTJkxYrr2Azal6FBsbO6WsrKwFQRBlY8eO/SooKChc89vo0aOXcTic8qioqC/y8vI6paSk9DOWz0l7h6RpWnT06NHty5Yt66DO4IfUNSW4wERYrFKptGIYRgghVPn7+0fy+fwyPp9f1r1794Pm7RuIYBi9EhiyYPOxOO7fxsamAAAACIJQqsVUzNXVNcXGxsbsEnVZWVntVCqVDY7j5TY2NvklJSVukZGR880FCEII14S6SiQSz9u3b8/s06fPTg341CG4HHPfg6IoK4QQ19XV9Zmtre2bBmXFioyM/AIAwOA4Lh89evSaymQIvH379mwMw0gulysJDAw8rft7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" alt="Techbase Consultant Services">
</div>
<div class="l-hero-text">
<div class="badge">Python · Lesson 31</div>
<h1>Pandas Correlations, Pandas Plotting & Introduction to Matplotlib</h1>
<div class="l-hero-sub">9 phases · Build: Project Goal</div>
</div>
</div>
</div>
<section style="background:linear-gradient(160deg,#ecfdf5 0%,#f8fafc 55%,#d1fae5 100%);padding-bottom:1.5rem;border-bottom:1px solid var(--br)">
<div style="max-width:880px;margin:0 auto;padding:0 1.5rem"><div class="wb"><h2>👋 Welcome to Lesson 31</h2><div style="font-size:1rem;line-height:1.85;color:var(--t2)"><p class="v2-p">Welcome to Lesson 31! In this lesson, you will learn three powerful skills that work beautifully together:</p>
<ol class="v2-ol"><li><strong>How to find correlations in data using Pandas</strong> · discovering hidden relationships between numbers</li><li><strong>How to create charts and graphs directly from a Pandas DataFrame</strong></li><li><strong>What Matplotlib is, how to install it, and how to draw your first plot</strong></li></ol>
<p class="v2-p">By the end of this lesson, you will be able to look at a table of numbers, automatically measure how strongly different columns are related to each other, and then draw visual charts to <em>see</em> those relationships.</p>
<p class="v2-p"><strong>Real-world relevance:</strong> These skills are used every day by data scientists, business analysts, finance professionals, health researchers, sports statisticians, and engineers. Whenever someone says "does more sleep lead to better grades?" or "does workout duration affect calories burned?" · correlation and charts are the tools they use to answer those questions.</p>
<hr class="v2-hr"></div><div class="wm"><span>📚 9 phases</span><span>🏗️ Project Goal</span><span>🐍 GitHub Repo</span></div></div></div>
</section>
<main style="max-width:880px;margin:0 auto;padding:2rem 1.5rem 5rem">
<div class="phase" id="phase1"><div class="ph"><div class="pn">Phase 1 of 9</div><div class="pt">Lesson Introduction</div><div class="pc" id="chk1"></div></div><div class="pb2"><p class="v2-p">Welcome to Lesson 31! In this lesson, you will learn three powerful skills that work beautifully together:</p>
<ol class="v2-ol"><li><strong>How to find correlations in data using Pandas</strong> · discovering hidden relationships between numbers</li><li><strong>How to create charts and graphs directly from a Pandas DataFrame</strong></li><li><strong>What Matplotlib is, how to install it, and how to draw your first plot</strong></li></ol>
<p class="v2-p">By the end of this lesson, you will be able to look at a table of numbers, automatically measure how strongly different columns are related to each other, and then draw visual charts to <em>see</em> those relationships.</p>
<p class="v2-p"><strong>Real-world relevance:</strong> These skills are used every day by data scientists, business analysts, finance professionals, health researchers, sports statisticians, and engineers. Whenever someone says "does more sleep lead to better grades?" or "does workout duration affect calories burned?" · correlation and charts are the tools they use to answer those questions.</p>
<hr class="v2-hr"><div class="task-box"><div class="task-lbl">✏️ Your Task</div><div class="task-body">Practise what you just learned about <strong>Lesson Introduction</strong>. Open your editor, type the examples above by hand, modify them, and observe what changes.</div></div><button class="ub" onclick="unlockNext(1)">Start Lesson ✓</button></div></div>
<div class="phase locked" id="phase2"><div class="ph"><div class="pn">Phase 2 of 9</div><div class="pt">Prerequisite Concepts</div><div class="pc" id="chk2"></div></div><div class="pb2"><p class="v2-p">Before we start, let us make sure you understand a few foundational ideas. We will explain each one simply.</p>
<h3 class="v2-h3">What is a Library (or Module) in Python?</h3>
<p class="v2-p">A <strong>library</strong> (also called a <strong>module</strong> or <strong>package</strong>) is a collection of code that someone else already wrote for you. Instead of writing all the code yourself from scratch, you simply "import" (load) the library and use its ready-made tools.</p>
<p class="v2-p">Think of it like a toolbox: rather than building a hammer yourself, you just open the toolbox and pick up the hammer.</p>
<p class="v2-p">The two libraries we will use in this lesson are:</p>
<ul class="v2-ul"><li><strong>Pandas</strong> · for working with tables of data (like a spreadsheet in Python)</li><li><strong>Matplotlib</strong> · for drawing charts and graphs</li></ul>
<h3 class="v2-h3">What is a DataFrame?</h3>
<p class="v2-p">A <strong>DataFrame</strong> is like a table · it has rows and columns. Think of it like an Excel spreadsheet inside Python. For example:</p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">code</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>| Duration | Pulse | Maxpulse | Calories |
|----------|-------|----------|----------|
| 60 | 110 | 130 | 409 |
| 45 | 117 | 141 | 282 |
| 45 | 103 | 132 | 270 |</code></pre></div></div>
<p class="v2-p">Each <strong>column</strong> holds one type of information (like Duration or Calories). Each <strong>row</strong> holds one record (like one workout session).</p>
<h3 class="v2-h3">What is a CSV file?</h3>
<p class="v2-p">A <strong>CSV</strong> file (Comma-Separated Values) is a simple text file that stores table data. Each line is one row, and columns are separated by commas. Pandas can read CSV files directly into a DataFrame.</p>
<h3 class="v2-h3">What is NumPy?</h3>
<p class="v2-p"><strong>NumPy</strong> is another Python library used for working with numbers and arrays (lists of numbers). Matplotlib often works alongside NumPy. We will use <code>np.array()</code> to create lists of numbers for plotting.</p>
<hr class="v2-hr"><div class="task-box"><div class="task-lbl">✏️ Your Task</div><div class="task-body">Practise what you just learned about <strong>Prerequisite Concepts</strong>. Open your editor, type the examples above by hand, modify them, and observe what changes.</div></div><button class="ub" onclick="unlockNext(2)">Phase Complete — Unlock Next ✓</button></div></div>
<div class="phase locked" id="phase3"><div class="ph"><div class="pn">Phase 3 of 9</div><div class="pt">Part 1: Pandas · Data Correlations</div><div class="pc" id="chk3"></div></div><div class="pb2"><h3 class="v2-h3">What is a Correlation?</h3>
<p class="v2-p"><strong>Correlation</strong> means "how much do two things change together?"</p>
<p class="v2-p">Imagine you're tracking students in a class. You record their study hours per week and their exam scores. You notice: students who study more tend to score higher. That is a <strong>positive correlation</strong> · when one goes up, the other goes up too.</p>
<p class="v2-p">Now imagine tracking how many times students skip classes and their exam scores. Students who skip more tend to score <em>lower</em>. That is a <strong>negative correlation</strong> · when one goes up, the other goes down.</p>
<p class="v2-p">And sometimes two things have no relationship at all · like a student's shoe size and their exam score. That is <strong>no correlation</strong>.</p>
<h3 class="v2-h3">The Correlation Scale: From -1 to 1</h3>
<p class="v2-p">Pandas measures correlation as a <strong>number between -1 and 1</strong>. Here is how to read that number:</p>
<div class="v2-table-wrap"><table class="v2-table"><thead><tr><th>Correlation Value</th><th>What It Means</th></tr></thead><tbody><tr><td><code>1.0</code></td><td>Perfect positive relationship</td></tr><tr><td><code>0.9</code></td><td>Very strong positive relationship</td></tr><tr><td><code>0.6</code></td><td>Good positive relationship</td></tr><tr><td><code>0.2</code></td><td>Weak relationship (almost no link)</td></tr><tr><td><code>0.0</code></td><td>No relationship at all</td></tr><tr><td><code>-0.2</code></td><td>Weak negative relationship</td></tr><tr><td><code>-0.6</code></td><td>Good negative relationship</td></tr><tr><td><code>-0.9</code></td><td>Very strong negative relationship</td></tr><tr><td><code>-1.0</code></td><td>Perfect negative relationship</td></tr></tbody></table></div>
<blockquote class="v2-bq"><p class="v2-p"><strong>Rule of thumb:</strong> A correlation of <code>0.6</code> or higher (or <code>-0.6</code> or lower) is generally considered a <strong>good</strong> (meaningful) correlation.</p></blockquote>
<blockquote class="v2-bq"><p class="v2-p"><strong>Analogy:</strong> Think of correlation like a tug-of-war rope. If both sides pull in the same direction → positive correlation. If they pull in opposite directions → negative. If they both just stand still → no correlation.</p></blockquote>
<hr class="v2-hr">
<h3 class="v2-h3">The <code>corr()</code> Method in Pandas</h3>
<p class="v2-p">Pandas has a built-in method called <code>corr()</code> that automatically calculates the correlation between <strong>every pair of numeric columns</strong> in your DataFrame.</p>
<p class="v2-p"><strong>What it does:</strong> Takes all your numeric columns and measures how strongly each pair is related. It ignores non-numeric (text) columns automatically.</p>
<p class="v2-p"><strong>Why is this useful?</strong> In a dataset with 10 columns, there are 45 possible pairs to compare. Instead of checking each pair manually, <code>corr()</code> calculates all of them in one line.</p>
<hr class="v2-hr">
<h3 class="v2-h3">Simple Example: Understanding What <code>corr()</code> Returns</h3>
<p class="v2-p">Let's start with a tiny, easy example to understand the output before we use real data.</p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import pandas as pd
# Create a very simple DataFrame with 3 columns
data = {
'Hours_Studied': [1, 2, 3, 4, 5],
'Exam_Score': [40, 55, 65, 80, 95],
'Shoe_Size': [7, 9, 6, 8, 7]
}
df = pd.DataFrame(data)
# Calculate correlations
result = df.corr()
print(result)</code></pre></div></div>
<p class="v2-p"><strong>Expected Output:</strong></p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">code</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code> Hours_Studied Exam_Score Shoe_Size
Hours_Studied 1.000000 0.993399 0.000000
Exam_Score 0.993399 1.000000 -0.019608
Shoe_Size 0.000000 -0.019608 1.000000</code></pre></div></div>
<p class="v2-p"><strong>Reading this output · line by line:</strong></p>
<ul class="v2-ul"><li>Every column is shown as both a <strong>row</strong> and a <strong>column</strong> in the result.</li><li>The diagonal (top-left to bottom-right) is always <code>1.000000</code> · because every column is perfectly correlated with <em>itself</em>. Of course!</li><li><code>Hours_Studied</code> vs <code>Exam_Score</code> = <code>0.993399</code> → <strong>very strong positive correlation</strong>! Students who study more hours get much higher scores. Makes sense!</li><li><code>Hours_Studied</code> vs <code>Shoe_Size</code> = <code>0.000000</code> → <strong>no correlation</strong>. Of course · shoe size has nothing to do with study hours.</li><li>The table is <strong>symmetric</strong>: the value for (row A, column B) is the same as (row B, column A).</li></ul>
<blockquote class="v2-bq"><p class="v2-p"><strong>Thinking prompt:</strong> What would happen if we added a "Skipped_Classes" column? Would you expect a positive or negative correlation with Exam_Score? Why?</p></blockquote>
<hr class="v2-hr">
<h3 class="v2-h3">Real Data Example: The Workout Dataset</h3>
<p class="v2-p">Now let's use a real dataset. This is a workout tracking CSV file called <code>data.csv</code> that contains these columns: <code>Duration</code>, <code>Pulse</code>, <code>Maxpulse</code>, <code>Calories</code>.</p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import pandas as pd
# Read the CSV file into a DataFrame
df = pd.read_csv('data.csv')
# Calculate correlations between all numeric columns
print(df.corr())</code></pre></div></div>
<p class="v2-p"><strong>Expected Output:</strong></p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">code</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code> Duration Pulse Maxpulse Calories
Duration 1.000000 -0.155408 0.009403 0.922721
Pulse -0.155408 1.000000 0.786535 0.025120
Maxpulse 0.009403 0.786535 1.000000 0.203814
Calories 0.922721 0.025120 0.203814 1.000000</code></pre></div></div>
<p class="v2-p"><strong>Let's analyse every relationship:</strong></p>
<p class="v2-p"><strong>1. Duration vs Duration = <code>1.000000</code> (Perfect Correlation)</strong> Every column is perfectly correlated with itself. This is always the case. It simply confirms the math is working correctly.</p>
<p class="v2-p"><strong>2. Duration vs Calories = <code>0.922721</code> (Very Good Correlation)</strong> This is close to 1.0, which means there is a very strong positive relationship. The longer you work out, the more calories you burn. And conversely, if you burned a lot of calories, you probably worked out for a long time. This makes complete physical sense!</p>
<p class="v2-p"><strong>3. Pulse vs Maxpulse = <code>0.786535</code> (Good Correlation)</strong> Your average pulse during a workout is strongly related to your maximum pulse. Higher average pulse → higher max pulse. Makes sense: if your heart is beating fast on average, it probably peaked even higher.</p>
<p class="v2-p"><strong>4. Duration vs Maxpulse = <code>0.009403</code> (Very Bad Correlation)</strong> This is almost zero. The length of your workout has almost no relationship to how high your maximum heart rate goes. You could work out for 2 hours at a calm pace or 20 minutes at an intense pace · both could reach the same max pulse.</p>
<p class="v2-p"><strong>5. Duration vs Pulse = <code>-0.155408</code> (Weak Negative Correlation)</strong> Slightly negative, but very weak. Not enough to draw conclusions from.</p>
<p class="v2-p"><strong>6. Pulse vs Calories = <code>0.025120</code> (Basically No Correlation)</strong> Your average heart rate doesn't really predict how many calories you burn. Duration does, but not pulse alone.</p>
<blockquote class="v2-bq"><p class="v2-p"><strong>Key insight:</strong> A number close to <code>0</code> (like <code>0.009</code> or <code>0.025</code>) means the two things are <strong>not related</strong>. Don't try to predict one from the other · you'll just be guessing.</p></blockquote>
<hr class="v2-hr">
<h3 class="v2-h3">What "Good Correlation" Means for Predictions</h3>
<p class="v2-p">This is where correlation becomes practically useful:</p>
<ul class="v2-ul"><li>If Duration and Calories have a correlation of <code>0.92</code>, you can say: <em>"Given how long someone worked out, I can make a reasonable prediction of how many calories they burned."</em></li><li>If Duration and Maxpulse have a correlation of <code>0.009</code>, you <strong>cannot</strong> say: <em>"Given how long someone worked out, I can predict their max heart rate."</em> The data shows no meaningful link.</li></ul>
<p class="v2-p">This is the foundation of <strong>machine learning</strong> and <strong>data science</strong>: you find which inputs (features) are correlated with the output (target) before building a predictive model.</p>
<hr class="v2-hr">
<h3 class="v2-h3">Second Example: Student Performance Correlations</h3>
<p class="v2-p">Let's look at another scenario to reinforce the concept:</p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import pandas as pd
# Student performance data
data = {
'Study_Hours': [2, 4, 6, 8, 3, 5, 7, 1, 9, 4],
'Sleep_Hours': [5, 7, 8, 8, 6, 7, 8, 4, 7, 6],
'Score': [45, 65, 78, 90, 55, 72, 88, 30, 95, 60],
'Absences': [8, 3, 2, 1, 6, 2, 1, 10, 0, 3]
}
df = pd.DataFrame(data)
print(df.corr())</code></pre></div></div>
<p class="v2-p"><strong>Expected Output (approximate):</strong></p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">code</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code> Study_Hours Sleep_Hours Score Absences
Study_Hours 1.000000 0.674957 0.985290 -0.947674
Sleep_Hours 0.674957 1.000000 0.718050 -0.678490
Score 0.985290 0.718050 1.000000 -0.962330
Absences -0.947674 -0.678490 -0.962330 1.000000</code></pre></div></div>
<p class="v2-p"><strong>Analysis:</strong></p>
<ul class="v2-ul"><li>Study_Hours vs Score = <code>0.985</code> → Extremely strong! More study hours → higher scores.</li><li>Absences vs Score = <code>-0.962</code> → Extremely strong <em>negative</em>! More absences → much lower scores.</li><li>Sleep_Hours vs Score = <code>0.718</code> → Good correlation. More sleep helps performance.</li><li>Study_Hours vs Absences = <code>-0.948</code> → Students who study more miss fewer classes.</li></ul>
<blockquote class="v2-bq"><p class="v2-p"><strong>Thinking prompt:</strong> What would happen if you added a "TV_Hours" column? Would you expect it to be positively or negatively correlated with Score?</p></blockquote>
<hr class="v2-hr">
<h3 class="v2-h3">Common Beginner Mistake: Confusing Correlation with Causation</h3>
<p class="v2-p"><strong>Mistake:</strong> Assuming that because two things are correlated, one <em>causes</em> the other.</p>
<p class="v2-p"><strong>Example:</strong> Ice cream sales and drowning accidents are both high in summer. They are correlated · but ice cream does not <em>cause</em> drowning! Both are caused by hot weather leading people to swim more and eat more ice cream.</p>
<p class="v2-p"><strong>Corrected thinking:</strong> Correlation tells you that two things <em>tend to move together</em>. It does <strong>not</strong> tell you <em>why</em>. Always think critically about whether there is a logical explanation before drawing conclusions.</p>
<hr class="v2-hr"><div class="task-box"><div class="task-lbl">✏️ Your Task</div><div class="task-body">Practise what you just learned about <strong>: Pandas · Data Correlations</strong>. Open your editor, type the examples above by hand, modify them, and observe what changes.</div></div><button class="ub" onclick="unlockNext(3)">Phase Complete — Unlock Next ✓</button></div></div>
<div class="phase locked" id="phase4"><div class="ph"><div class="pn">Phase 4 of 9</div><div class="pt">Part 2: Pandas · Plotting</div><div class="pc" id="chk4"></div></div><div class="pb2"><h3 class="v2-h3">What is Plotting?</h3>
<p class="v2-p"><strong>Plotting</strong> means drawing a visual chart (a diagram, a graph) from your data. Instead of staring at rows and rows of numbers, you create a picture that shows the pattern at a glance.</p>
<p class="v2-p">Think of it like this: if I show you 200 workout records in a table, you might not immediately see any pattern. But if I draw a scatter plot showing Duration vs Calories · you'll immediately see the upward trend with your eyes.</p>
<h3 class="v2-h3">How Pandas Plotting Works</h3>
<p class="v2-p">Pandas has a built-in <code>plot()</code> method that lets you draw charts directly from a DataFrame. It uses Matplotlib (which we'll learn about in Parts 3 · 5) behind the scenes to actually display the chart. You call <code>plt.show()</code> to make the chart appear on screen.</p>
<p class="v2-p"><strong>The basic structure is:</strong></p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import pandas as pd
import matplotlib.pyplot as plt # needed to show the chart
df = pd.read_csv('data.csv') # load the data
df.plot() # draw the plot
plt.show() # display the plot</code></pre></div></div>
<hr class="v2-hr">
<h3 class="v2-h3">Simple Default Plot</h3>
<p class="v2-p">When you call <code>df.plot()</code> with no arguments, Pandas draws a <strong>line chart</strong> of all numeric columns against the row index (0, 1, 2, 3...).</p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('data.csv')
df.plot()
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>What this does:</strong></p>
<ul class="v2-ul"><li><code>import pandas as pd</code> → loads the Pandas library, called <code>pd</code> for short</li><li><code>import matplotlib.pyplot as plt</code> → loads the Matplotlib plotting submodule, called <code>plt</code> for short</li><li><code>df = pd.read_csv('data.csv')</code> → reads the CSV file and creates a DataFrame</li><li><code>df.plot()</code> → tells Pandas to draw a default line plot of all numeric columns</li><li><code>plt.show()</code> → displays the chart on your screen (without this line, nothing appears!)</li></ul>
<p class="v2-p"><strong>Expected result:</strong> A line chart showing Duration, Pulse, Maxpulse, and Calories all drawn as separate lines. This gives a general overview.</p>
<hr class="v2-hr">
<h3 class="v2-h3">Scatter Plot: Visualising Correlation</h3>
<p class="v2-p">A <strong>scatter plot</strong> is one of the most powerful charts for visualising correlation. It places a dot for every data row, with the x-position determined by one column and the y-position determined by another.</p>
<p class="v2-p">If the dots form a diagonal upward line → positive correlation. If the dots form a diagonal downward line → negative correlation. If the dots are scattered randomly → no correlation.</p>
<p class="v2-p"><strong>Syntax for a scatter plot with Pandas:</strong></p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>df.plot(kind = 'scatter', x = 'ColumnName', y = 'OtherColumnName')</code></pre></div></div>
<ul class="v2-ul"><li><code>kind = 'scatter'</code> → tells Pandas to make a scatter plot (not a line chart)</li><li><code>x = 'Duration'</code> → use the Duration column as the horizontal axis</li><li><code>y = 'Calories'</code> → use the Calories column as the vertical axis</li></ul>
<hr class="v2-hr">
<h4 class="v2-h4">Scatter Plot Example 1: Good Correlation (Duration vs Calories)</h4>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('data.csv')
# Scatter plot showing a GOOD correlation
df.plot(kind = 'scatter', x = 'Duration', y = 'Calories')
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected result:</strong> The dots will form a clear upward diagonal pattern · the longer the workout duration, the more calories burned. You can visually see the strong correlation of <code>0.922721</code> that we calculated earlier.</p>
<blockquote class="v2-bq"><p class="v2-p"><strong>Connecting the dots (literally):</strong> When you see the dots trending upward from left to right, that is the <em>visual proof</em> of the high positive correlation number.</p></blockquote>
<hr class="v2-hr">
<h4 class="v2-h4">Scatter Plot Example 2: Bad Correlation (Duration vs Maxpulse)</h4>
<p class="v2-p">Now let's plot the pair that had a very low correlation (<code>0.009403</code>):</p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('data.csv')
# Scatter plot showing a BAD (no) correlation
df.plot(kind = 'scatter', x = 'Duration', y = 'Maxpulse')
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected result:</strong> The dots will be <strong>scattered randomly</strong> all over the chart with no clear pattern or direction. There is no diagonal trend. This is the visual confirmation that Duration and Maxpulse have no meaningful relationship · just like the near-zero correlation value showed us numerically.</p>
<blockquote class="v2-bq"><p class="v2-p"><strong>Thinking prompt:</strong> Compare the two scatter plots side by side. Can you see immediately which pair has a strong relationship and which doesn't? This is the power of visualisation.</p></blockquote>
<hr class="v2-hr">
<h3 class="v2-h3">Histogram: Seeing How Data Is Distributed</h3>
<p class="v2-p">A <strong>histogram</strong> shows you how often values fall into different ranges (called "bins" or "intervals"). It answers the question: "How spread out is my data? What's the most common range?"</p>
<p class="v2-p"><strong>Analogy:</strong> Imagine asking 200 students how many hours they studied. Instead of listing all 200 numbers, a histogram groups them: "40 students studied 1 · 2 hours, 80 students studied 3 · 4 hours," etc. You immediately see the most common study amount.</p>
<p class="v2-p"><strong>Key difference from scatter plot:</strong> A scatter plot needs two columns (x and y). A histogram only needs <strong>one column</strong>.</p>
<p class="v2-p"><strong>Syntax for a histogram:</strong></p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>df["ColumnName"].plot(kind = 'hist')</code></pre></div></div>
<ul class="v2-ul"><li><code>df["Duration"]</code> → select just the Duration column from the DataFrame</li><li><code>.plot(kind = 'hist')</code> → draw a histogram of that column's values</li></ul>
<hr class="v2-hr">
<h4 class="v2-h4">Histogram Example: Distribution of Workout Durations</h4>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('data.csv')
# Histogram of the Duration column
df["Duration"].plot(kind = 'hist')
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected result:</strong> A bar chart where the x-axis shows ranges of Duration (like 50 · 60 minutes, 60 · 70 minutes, etc.) and the y-axis shows how many workouts fell in each range.</p>
<p class="v2-p">According to the dataset, <strong>over 100 workouts lasted between 50 and 60 minutes</strong> · this would show as the tallest bar in the histogram, making it very easy to see the most common workout length at a glance.</p>
<blockquote class="v2-bq"><p class="v2-p"><strong>Real-world use:</strong> Histograms are used everywhere · doctors look at histograms of patient ages, engineers look at histograms of measurement errors, teachers look at histograms of exam scores to see how grades are distributed.</p></blockquote>
<hr class="v2-hr">
<h3 class="v2-h3">Summary of Pandas Plot Types</h3>
<div class="v2-table-wrap"><table class="v2-table"><thead><tr><th>Plot Type</th><th><code>kind =</code> value</th><th>What it shows</th><th>Columns needed</th></tr></thead><tbody><tr><td>Line chart</td><td>(default, no <code>kind</code>)</td><td>Trends over rows</td><td>All numeric</td></tr><tr><td>Scatter plot</td><td><code>'scatter'</code></td><td>Relationship between 2 columns</td><td>2 (x and y)</td></tr><tr><td>Histogram</td><td><code>'hist'</code></td><td>Distribution/frequency of values</td><td>1</td></tr></tbody></table></div>
<hr class="v2-hr"><div class="task-box"><div class="task-lbl">✏️ Your Task</div><div class="task-body">Practise what you just learned about <strong>: Pandas · Plotting</strong>. Open your editor, type the examples above by hand, modify them, and observe what changes.</div></div><button class="ub" onclick="unlockNext(4)">Phase Complete — Unlock Next ✓</button></div></div>
<div class="phase locked" id="phase5"><div class="ph"><div class="pn">Phase 5 of 9</div><div class="pt">Part 3: Introduction to Matplotlib</div><div class="pc" id="chk5"></div></div><div class="pb2"><h3 class="v2-h3">What is Matplotlib?</h3>
<p class="v2-p"><strong>Matplotlib</strong> is a Python library specifically designed for creating charts, graphs, diagrams, and all kinds of visualisations.</p>
<ul class="v2-ul"><li>It was created by <strong>John D. Hunter</strong></li><li>It is <strong>open source</strong> · free for anyone to use</li><li>It is mostly written in Python, with some parts in C, Objective-C, and JavaScript</li><li>It is the most popular charting library in the Python data science world</li></ul>
<p class="v2-p"><strong>Why do we need it?</strong> Pandas' <code>plot()</code> method we used above actually <em>uses</em> Matplotlib internally. But when you use Matplotlib directly, you get much more control: custom colours, labels, titles, grid lines, multiple charts in one figure, and much more.</p>
<p class="v2-p"><strong>Where is the code?</strong> The source code is on GitHub at: <code>https://github.com/matplotlib/matplotlib</code></p>
<hr class="v2-hr">
<h3 class="v2-h3">Installing Matplotlib</h3>
<p class="v2-p">Before you can use any external library, you must install it. Here's how:</p>
<p class="v2-p"><strong>Step 1:</strong> Open your command prompt (Windows) or terminal (Mac/Linux).</p>
<p class="v2-p"><strong>Step 2:</strong> Type this command and press Enter:</p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">code</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>pip install matplotlib</code></pre></div></div>
<p class="v2-p"><code>pip</code> is Python's <strong>package manager</strong> · the tool that downloads and installs libraries from the internet.</p>
<p class="v2-p">If this command doesn't work, you might be using a Python distribution like <strong>Anaconda</strong> or <strong>Spyder</strong>, which often have Matplotlib already pre-installed.</p>
<hr class="v2-hr">
<h3 class="v2-h3">Checking Your Matplotlib Version</h3>
<p class="v2-p">Once installed, you can verify the installation and see which version you have:</p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import matplotlib
print(matplotlib.__version__)</code></pre></div></div>
<p class="v2-p"><strong>Expected Output (your version may differ):</strong></p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">code</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>3.9.2</code></pre></div></div>
<p class="v2-p"><strong>Line-by-line explanation:</strong></p>
<ul class="v2-ul"><li><code>import matplotlib</code> → loads the entire Matplotlib library</li><li><code>print(matplotlib.__version__)</code> → prints the version number stored in the <code>__version__</code> attribute</li><li>Note: there are <strong>two underscore characters</strong> on each side of <code>version</code> (that's four underscores total: <code>__version__</code>)</li></ul>
<blockquote class="v2-bq"><p class="v2-p"><strong>Common mistake:</strong> Typing <code>_version_</code> (one underscore each side) instead of <code>__version__</code> (two underscores each side). Python won't recognise it.</p></blockquote>
<hr class="v2-hr"><div class="task-box"><div class="task-lbl">✏️ Your Task</div><div class="task-body">Practise what you just learned about <strong>: Introduction to Matplotlib</strong>. Open your editor, type the examples above by hand, modify them, and observe what changes.</div></div><button class="ub" onclick="unlockNext(5)">Phase Complete — Unlock Next ✓</button></div></div>
<div class="phase locked" id="phase6"><div class="ph"><div class="pn">Phase 6 of 9</div><div class="pt">Part 4: Matplotlib · The Pyplot Submodule</div><div class="pc" id="chk6"></div></div><div class="pb2"><h3 class="v2-h3">What is Pyplot?</h3>
<p class="v2-p">Matplotlib is a large library with many parts. The part we almost always use is called <strong>Pyplot</strong> · a submodule (a smaller package inside the bigger one) that contains all the functions for drawing plots.</p>
<p class="v2-p"><strong>Think of it this way:</strong> Matplotlib is the whole art studio. Pyplot is the particular drawing table where you actually sit down and draw.</p>
<h3 class="v2-h3">Importing Pyplot</h3>
<p class="v2-p">The standard way to import Pyplot is:</p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import matplotlib.pyplot as plt</code></pre></div></div>
<p class="v2-p"><strong>Breaking this down:</strong></p>
<ul class="v2-ul"><li><code>import matplotlib.pyplot</code> → loads the pyplot submodule</li><li><code>as plt</code> → gives it a short nickname <code>plt</code> so you don't have to type <code>matplotlib.pyplot</code> every time</li><li>Now whenever you want to use Pyplot, you just write <code>plt.something()</code></li></ul>
<blockquote class="v2-bq"><p class="v2-p"><strong>Convention:</strong> <code>import matplotlib.pyplot as plt</code> is the universally agreed way to import it. You'll see this exact line in virtually every data science script in the world.</p></blockquote>
<hr class="v2-hr">
<h3 class="v2-h3">Your First Plot with Pyplot</h3>
<p class="v2-p">Now let's draw something! This is the simplest possible Matplotlib example · a straight line:</p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import matplotlib.pyplot as plt
import numpy as np
# Define the x-coordinates of our two points
xpoints = np.array([0, 6])
# Define the y-coordinates of our two points
ypoints = np.array([0, 250])
# Draw a line connecting those points
plt.plot(xpoints, ypoints)
# Display the chart
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected Output:</strong> A chart window opens showing a straight line going from (0, 0) at the bottom-left to (6, 250) at the top-right.</p>
<p class="v2-p"><strong>Line-by-line explanation:</strong></p>
<ul class="v2-ul"><li><code>import matplotlib.pyplot as plt</code> → loads Pyplot with the nickname <code>plt</code></li><li><code>import numpy as np</code> → loads NumPy with the nickname <code>np</code></li><li><code>xpoints = np.array([0, 6])</code> → creates an array with two x-values: 0 and 6</li><li><code>ypoints = np.array([0, 250])</code> → creates an array with two y-values: 0 and 250</li><li><code>plt.plot(xpoints, ypoints)</code> → draws a line chart. Python will plot the point (0, 0) and (6, 250) and draw a line between them</li><li><code>plt.show()</code> → opens a window on your screen to display the chart. <strong>This is required!</strong> Without it, nothing appears.</li></ul>
<blockquote class="v2-bq"><p class="v2-p"><strong>What is <code>np.array()</code>?</strong> It creates a NumPy array · an ordered collection of numbers. Think of it as a smarter version of a Python list. Matplotlib works best with NumPy arrays.</p></blockquote>
<hr class="v2-hr"><div class="task-box"><div class="task-lbl">✏️ Your Task</div><div class="task-body">Practise what you just learned about <strong>: Matplotlib · The Pyplot Submodule</strong>. Open your editor, type the examples above by hand, modify them, and observe what changes.</div></div><button class="ub" onclick="unlockNext(6)">Phase Complete — Unlock Next ✓</button></div></div>
<div class="phase locked" id="phase7"><div class="ph"><div class="pn">Phase 7 of 9</div><div class="pt">Part 5: Matplotlib Plotting · Drawing Points and Lines</div><div class="pc" id="chk7"></div></div><div class="pb2"><h3 class="v2-h3">The <code>plot()</code> Function</h3>
<p class="v2-p">The <code>plt.plot()</code> function is the core of Matplotlib. It draws markers (dots) or lines in a diagram.</p>
<p class="v2-p"><strong>How it works:</strong></p>
<ul class="v2-ul"><li><strong>Parameter 1:</strong> An array of x-coordinates (horizontal positions)</li><li><strong>Parameter 2:</strong> An array of y-coordinates (vertical positions)</li><li>Each pair (x[i], y[i]) defines one point</li><li>By default, Matplotlib connects the points with a line</li></ul>
<blockquote class="v2-bq"><p class="v2-p"><strong>Think of it like plotting points on graph paper.</strong> The x-axis is horizontal. The y-axis is vertical. You mark each point and Matplotlib connects them.</p></blockquote>
<hr class="v2-hr">
<h3 class="v2-h3">Example 1: Simple Line Between Two Points</h3>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import matplotlib.pyplot as plt
import numpy as np
# Point 1: (1, 3) Point 2: (8, 10)
xpoints = np.array([1, 8])
ypoints = np.array([3, 10])
plt.plot(xpoints, ypoints)
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected Output:</strong> A straight line going from point (1, 3) to point (8, 10).</p>
<p class="v2-p"><strong>How does Python know which x goes with which y?</strong></p>
<ul class="v2-ul"><li><code>xpoints[0]</code> = 1 pairs with <code>ypoints[0]</code> = 3 → Point (1, 3)</li><li><code>xpoints[1]</code> = 8 pairs with <code>ypoints[1]</code> = 10 → Point (8, 10)</li><li>Matplotlib draws a line connecting them in order.</li></ul>
<hr class="v2-hr">
<h3 class="v2-h3">Example 2: Plotting Without a Line (Just Dots)</h3>
<p class="v2-p">Sometimes you just want dots, not a line connecting them. Use the shortcut <code>'o'</code> as the third argument · <code>'o'</code> stands for "circles" (ring markers):</p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import matplotlib.pyplot as plt
import numpy as np
xpoints = np.array([1, 8])
ypoints = np.array([3, 10])
plt.plot(xpoints, ypoints, 'o') # 'o' means: show dots only, no line
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected Output:</strong> Two small circle dots on the chart at positions (1, 3) and (8, 10), but <strong>no line</strong> connecting them.</p>
<p class="v2-p"><strong>Why would you want this?</strong> This is similar to a scatter plot · when you just want to see the positions of data points without implying they are connected in sequence.</p>
<hr class="v2-hr">
<h3 class="v2-h3">Example 3: Multiple Points · Connecting a Path</h3>
<p class="v2-p">You can provide as many points as you want, as long as both arrays have the same number of elements:</p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import matplotlib.pyplot as plt
import numpy as np
# Four x-points and four y-points
xpoints = np.array([1, 2, 6, 8])
ypoints = np.array([3, 8, 1, 10])
plt.plot(xpoints, ypoints)
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected Output:</strong> A line chart that:</p>
<ul class="v2-ul"><li>Starts at (1, 3)</li><li>Goes up to (2, 8)</li><li>Drops down to (6, 1)</li><li>Goes back up to (8, 10)</li></ul>
<p class="v2-p"><strong>Line-by-line:</strong></p>
<ul class="v2-ul"><li><code>xpoints = np.array([1, 2, 6, 8])</code> → four x-positions</li><li><code>ypoints = np.array([3, 8, 1, 10])</code> → four corresponding y-positions</li><li>Matplotlib connects them in order: (1,3) → (2,8) → (6,1) → (8,10)</li></ul>
<blockquote class="v2-bq"><p class="v2-p"><strong>Critical rule:</strong> Both arrays must have the <strong>same number of values</strong>. If <code>xpoints</code> has 4 values, <code>ypoints</code> must also have exactly 4 values. Otherwise you get an error.</p></blockquote>
<hr class="v2-hr">
<h3 class="v2-h3">Example 4: Plotting with Default X-Points</h3>
<p class="v2-p">If you only provide y-values and leave out the x-values, Matplotlib automatically assigns x-values starting from 0:</p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import matplotlib.pyplot as plt
import numpy as np
# Only y-values provided
ypoints = np.array([3, 8, 1, 10, 5, 7])
plt.plot(ypoints)
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected Output:</strong> A line chart where:</p>
<ul class="v2-ul"><li>x-axis goes 0, 1, 2, 3, 4, 5 (automatically assigned)</li><li>y-axis shows the values: 3, 8, 1, 10, 5, 7</li></ul>
<p class="v2-p"><strong>So the plotted points are:</strong> (0,3), (1,8), (2,1), (3,10), (4,5), (5,7)</p>
<p class="v2-p"><strong>When is this useful?</strong> When your data is in sequence and the index (position number) is the natural x-axis · for example, daily temperatures for a week, where day 0 = Monday, day 1 = Tuesday, etc.</p>
<blockquote class="v2-bq"><p class="v2-p"><strong>Thinking prompt:</strong> What would happen if you provided 10 y-values? What would the x-axis go up to?</p></blockquote>
<hr class="v2-hr"><div class="task-box"><div class="task-lbl">✏️ Your Task</div><div class="task-body">Practise what you just learned about <strong>: Matplotlib Plotting · Drawing Points and Lines</strong>. Open your editor, type the examples above by hand, modify them, and observe what changes.</div></div><button class="ub" onclick="unlockNext(7)">Phase Complete — Unlock Next ✓</button></div></div>
<div class="phase locked" id="phase8"><div class="ph"><div class="pn">Phase 8 of 9</div><div class="pt">Guided Practice Exercises</div><div class="pc" id="chk8"></div></div><div class="pb2"><div class="chal-box"><div class="chal-lbl">🎯 Your Challenge</div><div class="chal-body"><h3 class="v2-h3">Exercise 1: Simple Correlation Finder</h3>
<p class="v2-p"><strong>Objective:</strong> Use <code>corr()</code> to discover relationships in student data.</p>
<p class="v2-p"><strong>Scenario:</strong> You have data from 8 students tracking study time, sleep, and test scores.</p>
<p class="v2-p"><strong>Steps:</strong></p>
<ol class="v2-ol"><li>Copy and run this code:</li></ol></div></div><div class="task-box"><div class="task-lbl">✏️ Task</div><div class="task-body">Practise what you just learned about <strong>Guided Practice Exercises</strong>. Open your editor, type the examples above by hand, modify them, and observe what changes.</div></div><button class="reveal-btn" onclick="toggleReveal(this)">Reveal Answer 👁️</button><div class="reveal-content"><div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import pandas as pd
data = {
'Study_Hours': [2, 5, 3, 8, 1, 6, 4, 7],
'Sleep_Hours': [6, 7, 5, 8, 4, 8, 6, 7],
'Test_Score': [55, 78, 60, 95, 40, 88, 70, 90],
'Phone_Hours': [5, 2, 4, 1, 7, 1, 3, 2]
}
df = pd.DataFrame(data)
print(df.corr())</code></pre></div></div>
<ol class="v2-ol"><li>Look at each pair and answer:</li></ol>
<p class="v2-p"><strong>Self-check Questions:</strong></p>
<ul class="v2-ul"><li>What is the correlation between Study_Hours and Test_Score? Is it strong?</li><li>What is the correlation between Phone_Hours and Test_Score? Positive or negative?</li><li>What does the diagonal always equal?</li><li>Would you expect more phone use to lead to lower or higher scores?</li></ul>
<p class="v2-p"><strong>Expected Output (approximate):</strong></p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">code</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code> Study_Hours Sleep_Hours Test_Score Phone_Hours
Study_Hours 1.000000 0.697539 0.993180 -0.996386
Sleep_Hours 0.697539 1.000000 0.746671 -0.707764
Test_Score 0.993180 0.746671 1.000000 -0.991474
Phone_Hours -0.996386 -0.707764 -0.991474 1.000000</code></pre></div></div>
<p class="v2-p"><strong>What to notice:</strong></p>
<ul class="v2-ul"><li>Study_Hours vs Test_Score ≈ <code>0.993</code> · incredibly strong positive correlation!</li><li>Phone_Hours vs Test_Score ≈ <code>-0.991</code> · incredibly strong <em>negative</em> correlation. More phone time → much lower scores.</li></ul>
<hr class="v2-hr">
<h3 class="v2-h3">Exercise 2: Scatter Plot to Confirm Correlations</h3>
<p class="v2-p"><strong>Objective:</strong> Visualise two pairs of data · one with strong correlation, one without.</p>
<p class="v2-p"><strong>Scenario:</strong> You have production data from a factory.</p>
<p class="v2-p"><strong>Steps:</strong></p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import pandas as pd
import matplotlib.pyplot as plt
# Factory data
data = {
'Machine_Hours': [2, 4, 6, 8, 10, 12, 14, 16],
'Units_Made': [18, 38, 55, 80, 99, 120, 142, 160],
'Coffee_Breaks': [3, 1, 4, 2, 5, 2, 3, 1]
}
df = pd.DataFrame(data)
# First: check correlations
print(df.corr())
# Second: scatter plot Machine_Hours vs Units_Made (should show strong correlation)
df.plot(kind='scatter', x='Machine_Hours', y='Units_Made')
plt.title('Machine Hours vs Units Made')
plt.show()
# Third: scatter plot Machine_Hours vs Coffee_Breaks (should show no correlation)
df.plot(kind='scatter', x='Machine_Hours', y='Coffee_Breaks')
plt.title('Machine Hours vs Coffee Breaks')
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected result:</strong> The first scatter plot shows an upward diagonal (strong positive correlation). The second shows dots scattered randomly (no correlation).</p>
<p class="v2-p"><strong>Optional challenge:</strong> Can you add a histogram showing the distribution of Units_Made?</p>
<hr class="v2-hr">
<h3 class="v2-h3">Exercise 3: Plotting a Custom Line with Matplotlib</h3>
<p class="v2-p"><strong>Objective:</strong> Draw a Matplotlib line chart from scratch.</p>
<p class="v2-p"><strong>Scenario:</strong> Track the temperature in a city over 6 days.</p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import matplotlib.pyplot as plt
import numpy as np
# Days of the week (x-axis)
days = np.array([1, 2, 3, 4, 5, 6])
# Temperature in Celsius (y-axis)
temperature = np.array([22, 25, 28, 24, 19, 23])
# Draw the line
plt.plot(days, temperature)
# Show the chart
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected Output:</strong> A line chart showing temperature going up from day 1 to 3, then dropping on day 5, then slightly recovering on day 6.</p>
<p class="v2-p"><strong>What-if challenge:</strong> What happens if you change <code>plt.plot(days, temperature)</code> to <code>plt.plot(days, temperature, 'o')</code>? Try it!</p>
<hr class="v2-hr"></div><button class="ub" onclick="unlockNext(8)">Mark Complete and Unlock Next ✓</button></div></div>
<div class="phase locked" id="phase9"><div class="ph"><div class="pn">Phase 9 of 9</div><div class="pt">Common Beginner Mistakes</div><div class="pc" id="chk9"></div></div><div class="pb2"><h3 class="v2-h3">Mistake 1: Forgetting <code>plt.show()</code></h3>
<p class="v2-p"><strong>Wrong:</strong></p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>plt.plot(x, y)
# Nothing appears on screen!</code></pre></div></div>
<p class="v2-p"><strong>Correct:</strong></p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>plt.plot(x, y)
plt.show() # This is what actually displays the chart</code></pre></div></div>
<p class="v2-p"><strong>Why it happens:</strong> Beginners think drawing the chart and displaying it are the same step. They're not. <code>plt.plot()</code> prepares the chart in memory; <code>plt.show()</code> opens the window.</p>
<hr class="v2-hr">
<h3 class="v2-h3">Mistake 2: Different Array Lengths</h3>
<p class="v2-p"><strong>Wrong:</strong></p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>x = np.array([1, 2, 3, 4]) # 4 values
y = np.array([10, 20, 30]) # only 3 values!
plt.plot(x, y) # ERROR!</code></pre></div></div>
<p class="v2-p"><strong>Correct:</strong></p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>x = np.array([1, 2, 3, 4]) # 4 values
y = np.array([10, 20, 30, 40]) # also 4 values
plt.plot(x, y) # Works!</code></pre></div></div>
<p class="v2-p"><strong>Rule:</strong> x and y arrays must always have the <strong>exact same number of elements</strong>.</p>
<hr class="v2-hr">
<h3 class="v2-h3">Mistake 3: Using <code>.corr()</code> on Non-Numeric Data</h3>
<p class="v2-p"><strong>Wrong:</strong></p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>data = {'Name': ['Alice', 'Bob', 'Charlie'], 'Score': [85, 90, 78]}
df = pd.DataFrame(data)
print(df.corr()) # Only 'Score' will appear — Name is text, not a number</code></pre></div></div>
<p class="v2-p"><strong>Correct understanding:</strong> <code>.corr()</code> <strong>automatically ignores</strong> text columns. Only numeric columns participate in the correlation calculation. This is not an error · it is by design.</p>
<hr class="v2-hr">
<h3 class="v2-h3">Mistake 4: Misreading the Correlation Table</h3>
<p class="v2-p"><strong>Wrong thinking:</strong> "The number in row Duration, column Calories is different from row Calories, column Duration."</p>
<p class="v2-p"><strong>Correct:</strong> The table is <strong>symmetric</strong>. The value at (Duration, Calories) = the value at (Calories, Duration). They are always the same.</p>
<hr class="v2-hr">
<h3 class="v2-h3">Mistake 5: Importing Without Aliases</h3>
<p class="v2-p"><strong>Wrong:</strong></p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import matplotlib.pyplot
matplotlib.pyplot.plot(x, y) # Very tedious to type!</code></pre></div></div>
<p class="v2-p"><strong>Correct:</strong></p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import matplotlib.pyplot as plt
plt.plot(x, y) # Much cleaner!</code></pre></div></div>
<p class="v2-p">The <code>as plt</code> shortcut is not required, but it is standard practice and makes your code much easier to read and write.</p>
<hr class="v2-hr">
<h3 class="v2-h3">Mistake 6: Using One Underscore in <code>__version__</code></h3>
<p class="v2-p"><strong>Wrong:</strong></p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>print(matplotlib._version_) # One underscore each side — Error!</code></pre></div></div>
<p class="v2-p"><strong>Correct:</strong></p>
<div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">python</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>print(matplotlib.__version__) # Two underscores each side — Correct!</code></pre></div></div>
<hr class="v2-hr"><div class="task-box"><div class="task-lbl">✏️ Your Task</div><div class="task-body"> · ### Mistake 6: Using One Underscore in __version__
Wrong:
`python
print(matplotlib._version_) # One underscore each side · Error!
`
Correct:
`python
print(matplotlib.__version__) # Two underscores each side · Correct!
` · </div></div><button class="ub" onclick="unlockNext(9)">Phase Complete — Unlock Next ✓</button></div></div>
<div class="build-box" id="build-it"><div class="build-lbl">🏗️ Build It — Mini Project</div><div class="build-name">Project Goal</div><div class="build-req"><p class="v2-p">Let's combine everything from this lesson into a realistic mini-project that a fitness coach might actually use.</p>
<h3 class="v2-h3">Project Goal</h3>
<p class="v2-p">Analyse workout data to:</p>
<ol class="v2-ol"><li>Find which factors are most strongly correlated with calories burned</li><li>Draw visual charts to present the findings</li><li>Summarise your conclusions</li></ol>
<hr class="v2-hr">
<h3 class="v2-h3">Stage 1: Setup · Create the Data</h3></div><button class="reveal-btn" onclick="toggleCode(this)">Reveal Starter Code 💻</button><div class="reveal-content"><div class="v2-code-wrap"><div class="v2-code-bar"><span class="v2-dot r"></span><span class="v2-dot y"></span><span class="v2-dot g"></span><span class="v2-code-lang">starter.py</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# Simulate workout data for 10 sessions
workout_data = {
'Duration_min': [30, 45, 60, 75, 90, 30, 45, 60, 75, 90],
'Avg_Pulse': [110, 120, 115, 125, 130, 105, 118, 122, 128, 135],
'Max_Pulse': [135, 145, 142, 155, 160, 130, 143, 150, 158, 165],
'Intensity_1to10': [4, 6, 5, 7, 8, 3, 5, 6, 7, 9],
'Calories': [240, 380, 450, 560, 680, 200, 350, 460, 570, 710]
}
df = pd.DataFrame(workout_data)
print("=== Workout Data ===")
print(df)</code></pre></div></div><div style="display:flex;gap:.8rem;flex-wrap:wrap;margin-top:1.1rem"><button class="ub" onclick="downloadStarter(`import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# Simulate workout data for 10 sessions
workout_data = {
'Duration_min': [30, 45, 60, 75, 90, 30, 45, 60, 75, 90],
'Avg_Pulse': [110, 120, 115, 125, 130, 105, 118, 122, 128, 135],
'Max_Pulse': [135, 145, 142, 155, 160, 130, 143, 150, 158, 165],
'Intensity_1to10': [4, 6, 5, 7, 8, 3, 5, 6, 7, 9],
'Calories': [240, 380, 450, 560, 680, 200, 350, 460, 570, 710]
}
df = pd.DataFrame(workout_data)
print("=== Workout Data ===")
print(df)`)" style="background:#10b981;box-shadow:0 4px 14px rgba(16,185,129,.3)">Download starter.py ↓</button><button class="ub" onclick="showGithub()" style="background:#0f172a;box-shadow:none">🐙 Save to GitHub →</button></div></div></div>
<div class="gh-acc" id="gh-steps" style="display:none">
<div class="gh-hd" onclick="toggleGh(this)">🐙 Save Python Project to GitHub <span>▼</span></div>
<div class="gh-bd">
<div class="gh-nop"><strong>Why Python cannot use GitHub Pages:</strong> GitHub Pages only serves static HTML, CSS, and JavaScript files. Python scripts need a runtime environment (a server or computer) to execute — the browser alone cannot run them. You will learn cloud deployment (Replit, PythonAnywhere, Heroku) later in this course. For now, save your code to GitHub as a growing portfolio of Python work.</div>
<div class="gh-st"><div class="gh-n">1</div><p>Go to <strong>github.com</strong>, click <strong>New repository</strong>, name it <code>python-lesson-31-project-goal</code>. Set to <strong>Public</strong>, tick <strong>Add a README</strong>, click <strong>Create repository</strong>.</p></div>
<div class="gh-st"><div class="gh-n">2</div><p>Click <strong>Add file > Upload files</strong> and upload your <code>.py</code> script.</p></div>
<div class="gh-st"><div class="gh-n">3</div><p>Write commit message: <em>"Add Python lesson 31 project"</em> and click <strong>Commit changes</strong>. Your code is now publicly visible on your GitHub profile. 🐍</p></div>
<button class="ub" onclick="showEnd()" style="background:#059669;margin-top:.5rem">Done — Finish Session ✅</button>
</div></div>
<div class="se" id="session-end"><h2>Lesson 31 complete! 🎉</h2><p style="margin-bottom:.85rem;font-size:.95rem;opacity:.9">You covered:</p><ul><li>✅ Lesson Introduction</li><li>✅ Prerequisite Concepts</li><li>✅ Part 1: Pandas · Data Correlations</li><li>✅ Part 2: Pandas · Plotting</li><li>✅ Part 3: Introduction to Matplotlib</li><li>✅ Part 4: Matplotlib · The Pyplot Submodule</li><li>✅ Part 5: Matplotlib Plotting · Drawing Points and Lines</li><li>✅ Guided Practice Exercises</li></ul><div class="ln"><a href="lesson_30.html" class="ln-btn">← Lesson 30</a><a href="lesson_32.html" class="ln-btn primary">Lesson 32 →</a></div></div>
</main>
<footer class="lf">
<img src="data:image/png;base64,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" alt="Techbase">
<span class="lf-text">Techbase Code Coach · Python Course · Lesson 31 · © 2025 Techbase Consultant Services, Ibadan</span>
</footer>
<div id="toast"></div>
<button id="go-top" title="Back to top">↑</button>
<canvas id="cc"></canvas>
<script>
const TOTAL=9,KEY='techbase_python_l31';
let cur=parseInt(localStorage.getItem(KEY)||'1');
function init(){for(let i=2;i<=cur;i++)unlock(i,false);bar();}
function unlockNext(n){
const c=document.getElementById('chk'+n);
if(c){c.classList.add('done');c.textContent='✓';}
localStorage.setItem(KEY,n+1);cur=n+1;
if(n===TOTAL){
document.getElementById('build-it').classList.add('visible');
bar(100);toast('Building time! 🏗️');
setTimeout(()=>document.getElementById('build-it').scrollIntoView({behavior:'smooth'}),200);
setTimeout(confetti,600);
}else{unlock(n+1,true);bar();
toast(['Phase complete! ✅','Keep going! 🎯','Nice work! 💡','Nailed it! 🚀'][n%4]);}
}
function unlock(n,scroll){
const el=document.getElementById('phase'+n);if(!el)return;
el.classList.remove('locked');
if(scroll)setTimeout(()=>el.scrollIntoView({behavior:'smooth',block:'start'}),180);
}
function bar(p){document.getElementById('pbar').style.width=(p!==undefined?p:Math.round((cur-1)/TOTAL*95))+'%';}
function toggleReveal(btn){const w=btn.nextElementSibling;const o=w.classList.toggle('open');btn.textContent=o?'Hide Answer 🙈':'Reveal Answer 👁️';}
function toggleCode(btn){const w=btn.nextElementSibling;const o=w.classList.toggle('open');btn.textContent=o?'Hide Starter Code 🙈':'Reveal Starter Code 💻';}
function copyCode(btn){
const code=btn.closest('.v2-code-wrap').querySelector('code').innerText;
navigator.clipboard.writeText(code).then(()=>{
btn.textContent='Copied! ✓';btn.classList.add('copied');
setTimeout(()=>{btn.innerHTML='❐ Copy';btn.classList.remove('copied');},1800);
}).catch(()=>{});
}
const tEl=document.getElementById('toast');let tT;
function toast(msg){tEl.innerHTML=msg;tEl.classList.add('show');clearTimeout(tT);tT=setTimeout(()=>tEl.classList.remove('show'),2400);}
const gEl=document.getElementById('go-top');
window.addEventListener('scroll',()=>gEl.classList.toggle('visible',scrollY>320),{passive:true});
gEl.addEventListener('click',()=>window.scrollTo({top:0,behavior:'smooth'}));
function toggleGh(el){el.nextElementSibling.classList.toggle('open');}
function showGithub(){const g=document.getElementById('gh-steps');if(g){g.style.display='block';setTimeout(()=>g.scrollIntoView({behavior:'smooth'}),150);}}
function showEnd(){const e=document.getElementById('session-end');if(e){e.classList.add('visible');setTimeout(()=>e.scrollIntoView({behavior:'smooth'}),150);}}
function downloadStarter(code){const ext='python'==='python'?'py':'html';const a=document.createElement('a');a.href='data:text/'+(ext==='py'?'x-python':'html')+';charset=utf-8,'+encodeURIComponent(code);a.download='starter.'+ext;a.click();}
function confetti(){
const cv=document.getElementById('cc');cv.style.display='block';const ctx=cv.getContext('2d');
cv.width=innerWidth;cv.height=innerHeight;
const ps=Array.from({length:140},()=>{return{x:Math.random()*cv.width,y:-10-Math.random()*120,r:4+Math.random()*6,d:2+Math.random()*3,c:['#e34c26','#0284c7','#d97706','#059669','#7c3aed','#ec4899'][Math.floor(Math.random()*6)],ta:0};});
let f=0;function draw(){ctx.clearRect(0,0,cv.width,cv.height);
ps.forEach(p=>{p.ta+=.1;p.y+=p.d;p.x+=Math.sin(f/20);ctx.beginPath();ctx.arc(p.x,p.y,p.r,0,Math.PI*2);ctx.fillStyle=p.c;ctx.fill();});
f++;if(f<210)requestAnimationFrame(draw);else{ctx.clearRect(0,0,cv.width,cv.height);cv.style.display='none';}}
draw();toast('All phases done! 🎉');
}
init();
</script>
</body></html>