-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlesson_32.html
More file actions
1143 lines (1014 loc) · 170 KB
/
Copy pathlesson_32.html
File metadata and controls
1143 lines (1014 loc) · 170 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
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Lesson 32: Matplotlib Visualisation: Markers, Lines, Labels, Grids, Subplots, Scatter Charts, and Bar Charts — 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 32 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 32</div>
<h1>Matplotlib Visualisation: Markers, Lines, Labels, Grids, Subplots, Scatter Charts, and Bar Charts</h1>
<div class="l-hero-sub">11 phases · Build: Project Overview</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 32</h2><div style="font-size:1rem;line-height:1.85;color:var(--t2)"><p class="v2-p">Have you ever looked at a news article and seen a line graph showing how temperatures changed over a year, or a bar chart comparing sales across different months? Those visuals are <strong>charts</strong> · and in Python, one of the most popular tools for creating them is a library called <strong>Matplotlib</strong>.</p>
<p class="v2-p">In this lesson you will learn how to:</p>
<ul class="v2-ul"><li>Add <strong>markers</strong> to highlight data points on a line chart</li><li>Control how the <strong>line</strong> looks · its style, colour, and thickness</li><li>Add <strong>labels</strong> (titles, axis names) so your chart tells a story</li><li>Add a <strong>grid</strong> to make values easier to read</li><li>Place multiple charts side-by-side using <strong>subplots</strong></li><li>Draw <strong>scatter charts</strong> to spot patterns between two variables</li><li>Draw <strong>bar charts</strong> to compare categories</li></ul>
<p class="v2-p">This lesson is designed for <strong>absolute beginners</strong>. You do not need any prior knowledge of Matplotlib or charting. Every concept is explained from the ground up, with simple examples before more complex ones.</p>
<blockquote class="v2-bq"><p class="v2-p"><strong>Real-world relevance:</strong> Data scientists, engineers, teachers, healthcare analysts, and business managers use charts daily to understand and present information. Learning to create charts in Python is one of the most practical and in-demand skills you can build.</p></blockquote>
<hr class="v2-hr"></div><div class="wm"><span>📚 11 phases</span><span>🏗️ Project Overview</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 11</div><div class="pt">Lesson Introduction</div><div class="pc" id="chk1"></div></div><div class="pb2"><p class="v2-p">Have you ever looked at a news article and seen a line graph showing how temperatures changed over a year, or a bar chart comparing sales across different months? Those visuals are <strong>charts</strong> · and in Python, one of the most popular tools for creating them is a library called <strong>Matplotlib</strong>.</p>
<p class="v2-p">In this lesson you will learn how to:</p>
<ul class="v2-ul"><li>Add <strong>markers</strong> to highlight data points on a line chart</li><li>Control how the <strong>line</strong> looks · its style, colour, and thickness</li><li>Add <strong>labels</strong> (titles, axis names) so your chart tells a story</li><li>Add a <strong>grid</strong> to make values easier to read</li><li>Place multiple charts side-by-side using <strong>subplots</strong></li><li>Draw <strong>scatter charts</strong> to spot patterns between two variables</li><li>Draw <strong>bar charts</strong> to compare categories</li></ul>
<p class="v2-p">This lesson is designed for <strong>absolute beginners</strong>. You do not need any prior knowledge of Matplotlib or charting. Every concept is explained from the ground up, with simple examples before more complex ones.</p>
<blockquote class="v2-bq"><p class="v2-p"><strong>Real-world relevance:</strong> Data scientists, engineers, teachers, healthcare analysts, and business managers use charts daily to understand and present information. Learning to create charts in Python is one of the most practical and in-demand skills you can build.</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>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 11</div><div class="pt">Prerequisite Concepts</div><div class="pc" id="chk2"></div></div><div class="pb2"><p class="v2-p">Before diving in, here is everything you need to know to follow this lesson comfortably.</p>
<h3 class="v2-h3">What Is a Library?</h3>
<p class="v2-p">Python comes with many built-in tools. A <strong>library</strong> is a collection of extra tools someone has already written that you can add to your project. Think of it like a toolbox: Python gives you a basic set of tools, and you can borrow extra specialised tools from a library when you need them.</p>
<h3 class="v2-h3">Installing and Importing Matplotlib</h3>
<p class="v2-p">Matplotlib is not built into Python. You install it once from your terminal:</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">bash</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">Then, at the top of every Python file where you want to use it, you <strong>import</strong> it:</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>
<ul class="v2-ul"><li><code>matplotlib</code> · the full library name</li><li><code>pyplot</code> · the specific module inside the library that handles plotting</li><li><code>plt</code> · a short nickname (alias) we choose so we don't have to type <code>matplotlib.pyplot</code> every time</li></ul>
<h3 class="v2-h3">What Is <code>plt.show()</code>?</h3>
<p class="v2-p">After you write code to build a chart, you call <code>plt.show()</code> to actually <strong>display</strong> it in a window. Think of it like writing a letter and then pressing "send" · <code>plt.show()</code> is the "send" step.</p>
<h3 class="v2-h3">What Are Lists?</h3>
<p class="v2-p">Charts need data. In Python, data is often stored in a <strong>list</strong> · a collection of values in square brackets:</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 = [1, 2, 3, 4, 5]
y = [10, 20, 15, 30, 25]</code></pre></div></div>
<p class="v2-p">Here <code>x</code> might represent days and <code>y</code> might represent temperatures recorded on those days.</p>
<h3 class="v2-h3">What Is a Plot?</h3>
<p class="v2-p">A <strong>plot</strong> is just another word for a chart or graph. When we say "plot the data", we mean "draw a chart using this data".</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 11</div><div class="pt">Part 1 · Matplotlib Markers</div><div class="pc" id="chk3"></div></div><div class="pb2"><h3 class="v2-h3">What Are Markers?</h3>
<p class="v2-p">When you draw a line chart, the line is drawn <strong>between</strong> your data points. A <strong>marker</strong> is a small symbol placed exactly <strong>at each data point</strong> so you can clearly see where actual values were recorded.</p>
<blockquote class="v2-bq"><p class="v2-p"><strong>Analogy:</strong> Imagine walking along a path and placing a small flag at every location you stopped to take a note. Those flags are markers.</p></blockquote>
<p class="v2-p">Without markers, you just see a smooth line. With markers, you can see exactly where each measurement was taken.</p>
<h3 class="v2-h3">Your First Marker Example</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
x = [1, 2, 3, 4, 5]
y = [3, 7, 2, 9, 5]
plt.plot(x, y, marker='o')
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> A line chart with a small filled circle (<code>o</code>) drawn at each of the five data points.</p>
<p class="v2-p"><strong>Line-by-line explanation:</strong></p>
<div class="v2-table-wrap"><table class="v2-table"><thead><tr><th>Line</th><th>What it does</th></tr></thead><tbody><tr><td><code>import matplotlib.pyplot as plt</code></td><td>Loads the plotting tools and gives them the nickname <code>plt</code></td></tr><tr><td><code>x = [1, 2, 3, 4, 5]</code></td><td>The horizontal (x-axis) values · positions along the bottom</td></tr><tr><td><code>y = [3, 7, 2, 9, 5]</code></td><td>The vertical (y-axis) values · the heights of each point</td></tr><tr><td><code>plt.plot(x, y, marker='o')</code></td><td>Draws a line through all points AND places a circle at each point</td></tr><tr><td><code>plt.show()</code></td><td>Displays the chart</td></tr></tbody></table></div>
<h3 class="v2-h3">All Available Marker Styles</h3>
<p class="v2-p">Matplotlib gives you many marker shapes. Here is a complete reference table:</p>
<div class="v2-table-wrap"><table class="v2-table"><thead><tr><th>Marker code</th><th>Shape description</th></tr></thead><tbody><tr><td><code>'o'</code></td><td>Circle</td></tr><tr><td><code>'*'</code></td><td>Star</td></tr><tr><td><code>'.'</code></td><td>Small dot</td></tr><tr><td><code>','</code></td><td>Pixel (tiny single pixel)</td></tr><tr><td><code>'x'</code></td><td>Cross (×)</td></tr><tr><td><code>'X'</code></td><td>Filled cross (×)</td></tr><tr><td><code>'+'</code></td><td>Plus sign (+)</td></tr><tr><td><code>'P'</code></td><td>Filled plus sign</td></tr><tr><td><code>'s'</code></td><td>Square</td></tr><tr><td><code>'D'</code></td><td>Diamond</td></tr><tr><td><code>'d'</code></td><td>Thin diamond</td></tr><tr><td><code>'p'</code></td><td>Pentagon</td></tr><tr><td><code>'H'</code></td><td>Hexagon (flat top)</td></tr><tr><td><code>'h'</code></td><td>Hexagon (pointy top)</td></tr><tr><td><code>'v'</code></td><td>Triangle pointing down</td></tr><tr><td><code>'^'</code></td><td>Triangle pointing up</td></tr><tr><td><code>'<'</code></td><td>Triangle pointing left</td></tr><tr><td><code>'>'</code></td><td>Triangle pointing right</td></tr><tr><td><code>'1'</code></td><td>Tri-down</td></tr><tr><td><code>'2'</code></td><td>Tri-up</td></tr><tr><td><code>'3'</code></td><td>Tri-left</td></tr><tr><td><code>'4'</code></td><td>Tri-right</td></tr><tr><td>`'</td><td>'`</td><td>Vertical line</td></tr><tr><td><code>'_'</code></td><td>Horizontal line</td></tr></tbody></table></div>
<h3 class="v2-h3">Trying Different Markers</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
x = [1, 2, 3, 4, 5]
y = [3, 7, 2, 9, 5]
plt.plot(x, y, marker='*')
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> Same line chart, but now a star symbol sits at each data point.</p>
<blockquote class="v2-bq"><p class="v2-p"><strong>Thinking prompt:</strong> What would happen if you changed <code>'*'</code> to <code>'s'</code>? Try it · you should see squares at each point instead of stars.</p></blockquote>
<h3 class="v2-h3">Controlling Marker Size</h3>
<p class="v2-p">You can change how large the markers are using the <code>markersize</code> parameter (shortened as <code>ms</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 matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [3, 7, 2, 9, 5]
plt.plot(x, y, marker='o', ms=15)
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> The same chart but with noticeably larger circles at each data point.</p>
<ul class="v2-ul"><li><code>ms=15</code> means the marker diameter is 15 points (the default is around 6)</li></ul>
<h3 class="v2-h3">Controlling Marker Colour</h3>
<p class="v2-p">Use <code>mec</code> (marker edge colour) to change the <strong>outline</strong> colour of the marker, and <code>mfc</code> (marker face colour) to change the <strong>fill</strong> colour:</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
x = [1, 2, 3, 4, 5]
y = [3, 7, 2, 9, 5]
plt.plot(x, y, marker='o', ms=15, mec='red', mfc='blue')
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> Large circles · filled blue with a red outline · at each data point.</p>
<p class="v2-p"><strong>Parameter reference:</strong></p>
<div class="v2-table-wrap"><table class="v2-table"><thead><tr><th>Parameter</th><th>Full name</th><th>What it controls</th></tr></thead><tbody><tr><td><code>mec</code></td><td>marker edge color</td><td>The colour of the border/outline of the marker</td></tr><tr><td><code>mfc</code></td><td>marker face color</td><td>The colour of the inside/fill of the marker</td></tr><tr><td><code>ms</code></td><td>markersize</td><td>How large the marker is</td></tr></tbody></table></div>
<h3 class="v2-h3">Accepted Colour Values</h3>
<p class="v2-p">You can specify colours in several ways:</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>mec='red' # by name
mec='#FF0000' # by hex code (same as red)
mec=(1.0, 0, 0) # by RGB tuple (red, green, blue each 0–1)</code></pre></div></div>
<blockquote class="v2-bq"><p class="v2-p"><strong>Common mistake:</strong> Spelling <code>colour</code> the British way · Python only accepts <code>color</code> (American spelling) in Matplotlib.</p></blockquote>
<h3 class="v2-h3">Shorthand Format String for Marker + Line + Colour</h3>
<p class="v2-p">Matplotlib allows a very compact "format string" that sets the <strong>colour</strong>, <strong>marker</strong>, and <strong>line style</strong> all at once using a short 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">code</span><button class="copy-btn" onclick="copyCode(this)">❐ Copy</button></div><div class="v2-code-body"><pre><code>plt.plot(x, y, 'r*--')</code></pre></div></div>
<p class="v2-p">This means:</p>
<ul class="v2-ul"><li><code>r</code> = red colour</li><li><code>*</code> = star marker</li><li><code> · </code> = dashed line</li></ul>
<p class="v2-p"><strong>Full shorthand example:</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
x = [1, 2, 3, 4, 5]
y = [3, 7, 2, 9, 5]
plt.plot(x, y, 'g^-.')
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> A green line with triangles at each point, drawn in a dot-dash pattern.</p>
<p class="v2-p"><strong>Format string quick reference:</strong></p>
<div class="v2-table-wrap"><table class="v2-table"><thead><tr><th>Character</th><th>Meaning</th></tr></thead><tbody><tr><td><code>r</code></td><td>Red</td></tr><tr><td><code>g</code></td><td>Green</td></tr><tr><td><code>b</code></td><td>Blue</td></tr><tr><td><code>k</code></td><td>Black</td></tr><tr><td><code>y</code></td><td>Yellow</td></tr><tr><td><code>m</code></td><td>Magenta</td></tr><tr><td><code>c</code></td><td>Cyan</td></tr><tr><td><code>w</code></td><td>White</td></tr><tr><td><code>o</code></td><td>Circle marker</td></tr><tr><td><code>*</code></td><td>Star marker</td></tr><tr><td><code>s</code></td><td>Square marker</td></tr><tr><td><code>-</code></td><td>Solid line</td></tr><tr><td><code> · </code></td><td>Dashed line</td></tr><tr><td><code>-.</code></td><td>Dash-dot line</td></tr><tr><td><code>:</code></td><td>Dotted line</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>Matplotlib Markers</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 11</div><div class="pt">Part 2 · Matplotlib Line Styling</div><div class="pc" id="chk4"></div></div><div class="pb2"><h3 class="v2-h3">What Is Line Styling?</h3>
<p class="v2-p">A chart line can be customised in three main ways:</p>
<ol class="v2-ol"><li>Its <strong>style</strong> · solid, dashed, dotted, etc.</li><li>Its <strong>colour</strong> · any named colour or hex code</li><li>Its <strong>width</strong> · how thick or thin the line is</li></ol>
<p class="v2-p">These are all controlled by parameters inside <code>plt.plot()</code>.</p>
<h3 class="v2-h3">Line Style</h3>
<p class="v2-p">Use <code>linestyle</code> (or shortened <code>ls</code>) to change the style of the 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
x = [1, 2, 3, 4, 5]
y = [3, 7, 2, 9, 5]
plt.plot(x, y, linestyle='dashed')
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> A dashed line connecting the five data points (no markers).</p>
<p class="v2-p"><strong>All linestyle options:</strong></p>
<div class="v2-table-wrap"><table class="v2-table"><thead><tr><th>Value</th><th>What it looks like</th></tr></thead><tbody><tr><td><code>'solid'</code> or <code>'-'</code></td><td> · · · · · · · </td></tr><tr><td><code>'dashed'</code> or <code>' · '</code></td><td> · · · · · </td></tr><tr><td><code>'dotted'</code> or <code>':'</code></td><td>· · · · ·</td></tr><tr><td><code>'dashdot'</code> or <code>'-.'</code></td><td> · · · · · · · </td></tr></tbody></table></div>
<h3 class="v2-h3">Line Colour</h3>
<p class="v2-p">Use <code>color</code> (or <code>c</code>) to set the line's colour:</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
x = [1, 2, 3, 4, 5]
y = [3, 7, 2, 9, 5]
plt.plot(x, y, color='hotpink')
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> A solid hot-pink line connecting the data points.</p>
<blockquote class="v2-bq"><p class="v2-p">Matplotlib recognises over 140 named colours including <code>'tomato'</code>, <code>'steelblue'</code>, <code>'goldenrod'</code>, <code>'orchid'</code>, and many more.</p></blockquote>
<h3 class="v2-h3">Line Width</h3>
<p class="v2-p">Use <code>linewidth</code> (or <code>lw</code>) to control thickness:</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
x = [1, 2, 3, 4, 5]
y = [3, 7, 2, 9, 5]
plt.plot(x, y, linewidth=8)
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> A very thick solid line. The default line width is around 1.5.</p>
<h3 class="v2-h3">Combining All Line Style Options</h3>
<p class="v2-p">You can combine marker, line style, colour, and width all in one <code>plt.plot()</code> call:</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
x = [1, 2, 3, 4, 5]
y = [3, 7, 2, 9, 5]
plt.plot(
x, y,
marker='o',
ms=10,
mec='darkblue',
mfc='skyblue',
linestyle='dashed',
color='steelblue',
linewidth=2
)
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> A dashed steel-blue line with sky-blue circles (dark-blue outline) at each data point.</p>
<blockquote class="v2-bq"><p class="v2-p"><strong>Thinking prompt:</strong> What would change if you set <code>linewidth=0</code>? Try it · the connecting line disappears and you only see the markers!</p></blockquote>
<h3 class="v2-h3">Multiple Lines on One Chart</h3>
<p class="v2-p">You can draw more than one line simply by calling <code>plt.plot()</code> multiple times before <code>plt.show()</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 matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [3, 7, 2, 9, 5]
y2 = [1, 4, 6, 3, 8]
plt.plot(x, y1, marker='o', color='blue', label='Dataset A')
plt.plot(x, y2, marker='s', color='red', label='Dataset B')
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> Two lines on the same chart · one blue with circles, one red with squares.</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>Matplotlib Line Styling</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 11</div><div class="pt">Part 3 · Matplotlib Labels and Titles</div><div class="pc" id="chk5"></div></div><div class="pb2"><h3 class="v2-h3">Why Do Labels Matter?</h3>
<p class="v2-p">A chart without labels is like a map without place names · you can see the shapes but you don't know what they mean.</p>
<p class="v2-p">Labels include:</p>
<ul class="v2-ul"><li>A <strong>title</strong> at the top of the chart</li><li>An <strong>x-axis label</strong> along the bottom</li><li>A <strong>y-axis label</strong> along the left side</li><li>A <strong>legend</strong> (when multiple lines are present) explaining what each line represents</li></ul>
<blockquote class="v2-bq"><p class="v2-p"><strong>Real-world relevance:</strong> In a scientific paper, a business report, or a school project, an unlabelled chart will always be questioned. Labels are what transform raw data into a meaningful story.</p></blockquote>
<h3 class="v2-h3">Adding a Title</h3>
<p class="v2-p">Use <code>plt.title()</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 matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [3, 7, 2, 9, 5]
plt.plot(x, y)
plt.title("My Daily Measurements")
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> The same line chart, but now "My Daily Measurements" appears above it as a title.</p>
<h3 class="v2-h3">Adding Axis Labels</h3>
<p class="v2-p">Use <code>plt.xlabel()</code> and <code>plt.ylabel()</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 matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [3, 7, 2, 9, 5]
plt.plot(x, y, marker='o')
plt.title("Temperature Over 5 Days")
plt.xlabel("Day")
plt.ylabel("Temperature (°C)")
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> The chart now has:</p>
<ul class="v2-ul"><li>"Temperature Over 5 Days" as the title</li><li>"Day" written below the x-axis</li><li>"Temperature (°C)" written vertically along the y-axis</li></ul>
<h3 class="v2-h3">Customising Label Font Properties</h3>
<p class="v2-p">You can control the font size, colour, and style of any label using the <code>fontdict</code> parameter:</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
x = [1, 2, 3, 4, 5]
y = [3, 7, 2, 9, 5]
title_font = {
'family': 'serif',
'color': 'darkred',
'size': 18,
'weight': 'bold'
}
axis_font = {
'family': 'serif',
'color': 'steelblue',
'size': 12
}
plt.plot(x, y, marker='o')
plt.title("Temperature Over 5 Days", fontdict=title_font)
plt.xlabel("Day", fontdict=axis_font)
plt.ylabel("Temperature (°C)", fontdict=axis_font)
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> A styled chart with a large, bold, dark-red title and smaller steel-blue axis labels.</p>
<p class="v2-p"><strong><code>fontdict</code> key reference:</strong></p>
<div class="v2-table-wrap"><table class="v2-table"><thead><tr><th>Key</th><th>What it controls</th><th>Example values</th></tr></thead><tbody><tr><td><code>'family'</code></td><td>Font family</td><td><code>'serif'</code>, <code>'sans-serif'</code>, <code>'monospace'</code></td></tr><tr><td><code>'color'</code></td><td>Text colour</td><td><code>'red'</code>, <code>'#333333'</code></td></tr><tr><td><code>'size'</code></td><td>Font size in points</td><td><code>10</code>, <code>14</code>, <code>20</code></td></tr><tr><td><code>'weight'</code></td><td>Bold or normal</td><td><code>'bold'</code>, <code>'normal'</code></td></tr><tr><td><code>'style'</code></td><td>Italic or normal</td><td><code>'italic'</code>, <code>'normal'</code></td></tr></tbody></table></div>
<h3 class="v2-h3">Title Positioning</h3>
<p class="v2-p">Use the <code>loc</code> parameter to align the title:</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.title("Left-aligned title", loc='left')
plt.title("Right-aligned title", loc='right')
plt.title("Centred title", loc='center') # This is the default</code></pre></div></div>
<h3 class="v2-h3">Adding a Legend</h3>
<p class="v2-p">When you have multiple lines, a <strong>legend</strong> is a small box that tells the viewer which line is which. Use <code>label</code> in each <code>plt.plot()</code> call, then call <code>plt.legend()</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 matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y1 = [3, 7, 2, 9, 5]
y2 = [1, 4, 6, 3, 8]
plt.plot(x, y1, label='City A Temperature')
plt.plot(x, y2, label='City B Temperature')
plt.title("Temperature Comparison")
plt.xlabel("Day")
plt.ylabel("Temperature (°C)")
plt.legend()
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> A chart with two lines, a legend box showing which colour belongs to "City A Temperature" and "City B Temperature", plus a title and axis labels.</p>
<blockquote class="v2-bq"><p class="v2-p"><strong>Common mistake:</strong> Forgetting to call <code>plt.legend()</code>. If you add <code>label=</code> to your plots but never call <code>plt.legend()</code>, the legend will not appear.</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 Labels and Titles</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 11</div><div class="pt">Part 4 · Matplotlib Grid</div><div class="pc" id="chk6"></div></div><div class="pb2"><h3 class="v2-h3">What Is a Grid?</h3>
<p class="v2-p">A <strong>grid</strong> is a set of light horizontal and/or vertical lines drawn behind the chart data to make it easier to read the value of each data point.</p>
<blockquote class="v2-bq"><p class="v2-p"><strong>Analogy:</strong> Think of graph paper. The faint squares in the background make it much easier to estimate values precisely. Matplotlib's grid does exactly the same thing for your digital charts.</p></blockquote>
<h3 class="v2-h3">Adding a Basic Grid</h3>
<p class="v2-p">Use <code>plt.grid()</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 matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [3, 7, 2, 9, 5]
plt.plot(x, y, marker='o')
plt.title("Temperature Over 5 Days")
plt.xlabel("Day")
plt.ylabel("Temperature (°C)")
plt.grid()
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> The same chart as before, but now faint grey gridlines appear horizontally and vertically across the chart area.</p>
<h3 class="v2-h3">Controlling Which Axis Shows Grid Lines</h3>
<p class="v2-p">The <code>axis</code> parameter lets you show gridlines only on one axis:</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.grid(axis='x') # vertical lines only (one per x value)
plt.grid(axis='y') # horizontal lines only (one per y value)
plt.grid(axis='both') # both (this is the default)</code></pre></div></div>
<p class="v2-p"><strong>Example · horizontal gridlines only:</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
x = [1, 2, 3, 4, 5]
y = [3, 7, 2, 9, 5]
plt.plot(x, y, marker='o')
plt.grid(axis='y')
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> Only horizontal gridlines appear across the chart (making it easy to read y-values).</p>
<h3 class="v2-h3">Styling the Grid</h3>
<p class="v2-p">You can customise the grid's appearance using standard line parameters:</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
x = [1, 2, 3, 4, 5]
y = [3, 7, 2, 9, 5]
plt.plot(x, y, marker='o', color='steelblue', linewidth=2)
plt.title("Temperature Over 5 Days")
plt.xlabel("Day")
plt.ylabel("Temperature (°C)")
plt.grid(
color='grey',
linestyle='--',
linewidth=0.5
)
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> A chart with thin dashed grey gridlines behind the data line.</p>
<p class="v2-p"><strong>Grid styling parameters:</strong></p>
<div class="v2-table-wrap"><table class="v2-table"><thead><tr><th>Parameter</th><th>What it does</th><th>Example</th></tr></thead><tbody><tr><td><code>color</code></td><td>Grid line colour</td><td><code>'grey'</code>, <code>'#cccccc'</code></td></tr><tr><td><code>linestyle</code></td><td>Grid line style</td><td><code>' · '</code>, <code>':'</code>, <code>'-'</code></td></tr><tr><td><code>linewidth</code></td><td>Grid line thickness</td><td><code>0.5</code>, <code>1</code>, <code>2</code></td></tr></tbody></table></div>
<blockquote class="v2-bq"><p class="v2-p"><strong>Thinking prompt:</strong> What happens if you set <code>linewidth=3</code> for the grid? It will overpower the data lines · always keep grid lines subtle (0.3 · 0.8) so they don't compete with your data.</p></blockquote>
<blockquote class="v2-bq"><p class="v2-p"><strong>Common mistake:</strong> Placing <code>plt.grid()</code> after <code>plt.show()</code> · always call <code>plt.grid()</code> before <code>plt.show()</code>.</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 Grid</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 11</div><div class="pt">Part 5 · Matplotlib Subplots</div><div class="pc" id="chk7"></div></div><div class="pb2"><h3 class="v2-h3">What Are Subplots?</h3>
<p class="v2-p">So far every example has shown <strong>one chart per figure</strong>. A <strong>subplot</strong> lets you place <strong>multiple charts inside the same figure window</strong>, arranged in rows and columns.</p>
<blockquote class="v2-bq"><p class="v2-p"><strong>Real-world relevance:</strong> A scientist comparing rainfall, temperature, and humidity in one report might display all three charts side-by-side so the reader can see relationships at a glance.</p></blockquote>
<h3 class="v2-h3">The <code>plt.subplot()</code> Function</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>plt.subplot(rows, columns, position)</code></pre></div></div>
<ul class="v2-ul"><li><code>rows</code> · how many rows of charts you want</li><li><code>columns</code> · how many columns of charts you want</li><li><code>position</code> · which slot to place the <strong>current</strong> chart in (counted left to right, top to bottom, starting at 1)</li></ul>
<h3 class="v2-h3">Your First Subplot Example</h3>
<p class="v2-p">Two charts side-by-side (1 row, 2 columns):</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
x = [1, 2, 3, 4, 5]
y1 = [3, 7, 2, 9, 5]
y2 = [1, 4, 6, 3, 8]
# First chart: position 1 (left slot)
plt.subplot(1, 2, 1)
plt.plot(x, y1, marker='o', color='steelblue')
plt.title("Dataset A")
# Second chart: position 2 (right slot)
plt.subplot(1, 2, 2)
plt.plot(x, y2, marker='s', color='tomato')
plt.title("Dataset B")
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> Two charts displayed side by side in one figure window.</p>
<ul class="v2-ul"><li>Left chart: blue circles, titled "Dataset A"</li><li>Right chart: red squares, titled "Dataset B"</li></ul>
<p class="v2-p"><strong>Step-by-step explanation:</strong></p>
<ol class="v2-ol"><li><code>plt.subplot(1, 2, 1)</code> · create a layout of 1 row and 2 columns, and activate position 1</li><li><code>plt.plot(...)</code> · draw the first chart into the active position</li><li><code>plt.subplot(1, 2, 2)</code> · activate position 2 (right slot)</li><li><code>plt.plot(...)</code> · draw the second chart into position 2</li><li><code>plt.show()</code> · display the entire figure with both charts</li></ol>
<h3 class="v2-h3">Two Charts Stacked Vertically</h3>
<p class="v2-p">Two charts stacked (2 rows, 1 column):</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
x = [1, 2, 3, 4, 5]
y1 = [3, 7, 2, 9, 5]
y2 = [1, 4, 6, 3, 8]
# Top chart
plt.subplot(2, 1, 1)
plt.plot(x, y1, marker='o', color='green')
plt.title("Top Chart")
# Bottom chart
plt.subplot(2, 1, 2)
plt.plot(x, y2, marker='^', color='purple')
plt.title("Bottom Chart")
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> Two charts stacked vertically · green circles on top, purple triangles below.</p>
<h3 class="v2-h3">A 2×2 Grid of Four Charts</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
x = [1, 2, 3, 4, 5]
plt.subplot(2, 2, 1)
plt.plot(x, [1, 4, 9, 16, 25], color='blue')
plt.title("Squares")
plt.subplot(2, 2, 2)
plt.plot(x, [1, 8, 27, 64, 125], color='orange')
plt.title("Cubes")
plt.subplot(2, 2, 3)
plt.plot(x, [2, 4, 8, 16, 32], color='green')
plt.title("Powers of 2")
plt.subplot(2, 2, 4)
plt.plot(x, [1, 3, 6, 10, 15], color='red')
plt.title("Triangular Numbers")
plt.suptitle("Number Sequences")
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> Four charts in a 2×2 grid, each showing a different mathematical sequence. A super-title "Number Sequences" appears above all four.</p>
<p class="v2-p"><strong><code>plt.suptitle()</code></strong> adds a title to the <strong>whole figure</strong>, sitting above all individual chart titles.</p>
<h3 class="v2-h3">Subplot Position Numbering Explained</h3>
<p class="v2-p">For a 2×2 grid:</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>┌──────────┬──────────┐
│ pos 1 │ pos 2 │
├──────────┼──────────┤
│ pos 3 │ pos 4 │
└──────────┴──────────┘</code></pre></div></div>
<p class="v2-p">Positions are numbered <strong>left to right, then top to bottom</strong>.</p>
<blockquote class="v2-bq"><p class="v2-p"><strong>Common mistake:</strong> Using <code>plt.subplot(2, 2, 0)</code> · positions start at <strong>1</strong>, not 0. Using 0 raises an error.</p></blockquote>
<blockquote class="v2-bq"><p class="v2-p"><strong>Thinking prompt:</strong> If you call <code>plt.subplot(3, 2, 5)</code>, which slot does that activate? Answer: Row 3, Column 1 (bottom-left).</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 Subplots</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 11</div><div class="pt">Part 6 · Matplotlib Scatter Charts</div><div class="pc" id="chk8"></div></div><div class="pb2"><h3 class="v2-h3">What Is a Scatter Chart?</h3>
<p class="v2-p">A <strong>scatter chart</strong> (also called a scatter plot) places individual dots on a chart · one dot per data point. There are <strong>no connecting lines</strong> between the dots.</p>
<p class="v2-p">Scatter charts are used to:</p>
<ul class="v2-ul"><li>Reveal whether two variables are <strong>related</strong> (correlated)</li><li>Spot <strong>clusters</strong> · groups of similar data points</li><li>Identify <strong>outliers</strong> · unusual values far from the rest</li></ul>
<blockquote class="v2-bq"><p class="v2-p"><strong>Real-world example:</strong> A biologist measuring the relationship between rainfall (x) and plant height (y) would use a scatter chart to see if taller plants grow where there is more rain.</p></blockquote>
<blockquote class="v2-bq"><p class="v2-p"><strong>Line chart vs scatter chart:</strong> Use a <strong>line chart</strong> when data is ordered over time (days, months, steps). Use a <strong>scatter chart</strong> when two independent measurements are compared with no time ordering.</p></blockquote>
<h3 class="v2-h3">Your First Scatter Chart</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
x = [5, 7, 8, 7, 2, 17, 2, 9, 4, 11, 12, 9, 6]
y = [99, 86, 87, 88, 111, 86, 103, 87, 94, 78, 77, 85, 86]
plt.scatter(x, y)
plt.title("Car Age vs Average Speed")
plt.xlabel("Age of Car (years)")
plt.ylabel("Average Speed (km/h)")
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> A scatter chart with 13 individual dots, showing the age of cars on the x-axis and their average speed on the y-axis.</p>
<p class="v2-p"><strong>Line-by-line explanation:</strong></p>
<div class="v2-table-wrap"><table class="v2-table"><thead><tr><th>Line</th><th>What it does</th></tr></thead><tbody><tr><td><code>x = [...]</code></td><td>Car ages in years</td></tr><tr><td><code>y = [...]</code></td><td>Average speeds in km/h</td></tr><tr><td><code>plt.scatter(x, y)</code></td><td>Draws one dot for each (x, y) pair</td></tr><tr><td><code>plt.title(...)</code></td><td>Adds a title</td></tr><tr><td><code>plt.xlabel(...)</code></td><td>Labels the x-axis</td></tr><tr><td><code>plt.ylabel(...)</code></td><td>Labels the y-axis</td></tr></tbody></table></div>
<h3 class="v2-h3">Customising Scatter Chart Colour and Size</h3>
<p class="v2-p">Use <code>color</code> to change dot colour and <code>s</code> to change dot <strong>size</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
x = [5, 7, 8, 7, 2, 17, 2, 9, 4, 11, 12, 9, 6]
y = [99, 86, 87, 88, 111, 86, 103, 87, 94, 78, 77, 85, 86]
plt.scatter(x, y, color='hotpink', s=100)
plt.title("Car Age vs Average Speed")
plt.xlabel("Age of Car (years)")
plt.ylabel("Average Speed (km/h)")
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> Same scatter chart but with larger pink dots.</p>
<h3 class="v2-h3">Using Different Colours Per Dot</h3>
<p class="v2-p">Pass a <strong>list of colours</strong> (one per data point) to colour each dot differently:</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
x = [5, 7, 8, 7, 2, 17]
y = [99, 86, 87, 88, 111, 86]
colours = ['red', 'green', 'blue', 'orange', 'purple', 'brown']
plt.scatter(x, y, c=colours, s=100)
plt.title("Individual Car Speeds")
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> Six differently coloured dots · one red, one green, one blue, etc.</p>
<blockquote class="v2-bq"><p class="v2-p">Notice that for scatter charts, the colour parameter shorthand is <code>c=</code> rather than <code>color=</code> when passing a list.</p></blockquote>
<h3 class="v2-h3">Using a Colour Map</h3>
<p class="v2-p">A <strong>colour map</strong> (or cmap) automatically assigns colours from a gradient based on the value of another variable. This is useful for encoding a third dimension of data visually:</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
x = [5, 7, 8, 7, 2, 17, 2, 9, 4, 11, 12, 9, 6]
y = [99, 86, 87, 88, 111, 86, 103, 87, 94, 78, 77, 85, 86]
# Use the y-values to colour the dots
colors = y
plt.scatter(x, y, c=colors, cmap='viridis', s=100)
plt.colorbar()
plt.title("Car Age vs Speed (colour = speed)")
plt.xlabel("Age (years)")
plt.ylabel("Speed (km/h)")
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> Dots coloured along a purple-yellow gradient · lower speeds in purple, higher speeds in yellow · plus a colour bar on the right showing the scale.</p>
<p class="v2-p"><strong>Popular colour maps:</strong></p>
<div class="v2-table-wrap"><table class="v2-table"><thead><tr><th>Name</th><th>Gradient description</th></tr></thead><tbody><tr><td><code>'viridis'</code></td><td>Purple → blue → green → yellow</td></tr><tr><td><code>'plasma'</code></td><td>Purple → pink → yellow</td></tr><tr><td><code>'inferno'</code></td><td>Black → red → yellow</td></tr><tr><td><code>'coolwarm'</code></td><td>Blue → white → red</td></tr><tr><td><code>'Greens'</code></td><td>Light green → dark green</td></tr></tbody></table></div>
<h3 class="v2-h3">Controlling Dot Transparency with Alpha</h3>
<p class="v2-p">Use <code>alpha</code> (a value between 0.0 and 1.0) to make dots semi-transparent. This is very useful when many dots overlap:</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
x = [5, 7, 8, 7, 2, 17, 2, 9, 4, 11, 12, 9, 6]
y = [99, 86, 87, 88, 111, 86, 103, 87, 94, 78, 77, 85, 86]
plt.scatter(x, y, color='steelblue', s=200, alpha=0.5)
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> Large semi-transparent dots where overlapping areas appear darker.</p>
<ul class="v2-ul"><li><code>alpha=1.0</code> · fully opaque (default)</li><li><code>alpha=0.5</code> · 50% transparent</li><li><code>alpha=0.0</code> · fully invisible</li></ul>
<h3 class="v2-h3">Two Datasets on One Scatter Chart</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
# Dataset 1: Cars from 2010–2015
x1 = [5, 7, 8, 7, 2, 17, 2, 9, 4]
y1 = [99, 86, 87, 88, 111, 86, 103, 87, 94]
# Dataset 2: Cars from 2016–2021
x2 = [2, 3, 6, 12, 8, 5]
y2 = [105, 100, 98, 90, 103, 110]
plt.scatter(x1, y1, color='blue', label='2010–2015', alpha=0.7)
plt.scatter(x2, y2, color='red', label='2016–2021', alpha=0.7)
plt.title("Car Age vs Speed by Era")
plt.xlabel("Age (years)")
plt.ylabel("Speed (km/h)")
plt.legend()
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> A scatter chart with blue dots for older cars and red dots for newer cars, with a legend identifying each group.</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>Matplotlib Scatter Charts</strong>. Open your editor, type the examples above by hand, modify them, and observe what changes.</div></div><button class="ub" onclick="unlockNext(8)">Phase Complete — Unlock Next ✓</button></div></div>
<div class="phase locked" id="phase9"><div class="ph"><div class="pn">Phase 9 of 11</div><div class="pt">Part 7 · Matplotlib Bar Charts</div><div class="pc" id="chk9"></div></div><div class="pb2"><h3 class="v2-h3">What Is a Bar Chart?</h3>
<p class="v2-p">A <strong>bar chart</strong> uses rectangular bars to compare values across different <strong>categories</strong>. The length (or height) of each bar represents the value for that category.</p>
<blockquote class="v2-bq"><p class="v2-p"><strong>Real-world examples:</strong></p>
<ul class="v2-ul"><li>Comparing monthly sales figures across 12 months</li><li>Comparing the number of students enrolled in different university courses</li><li>Comparing rainfall amounts in different cities</li></ul></blockquote>
<blockquote class="v2-bq"><p class="v2-p"><strong>Bar chart vs line chart:</strong> Use a <strong>line chart</strong> when showing change <strong>over time</strong> with a continuous connection. Use a <strong>bar chart</strong> when comparing <strong>discrete categories</strong> that don't have a natural connection.</p></blockquote>
<h3 class="v2-h3">Your First Bar Chart</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
categories = ["Apples", "Bananas", "Cherries", "Dates"]
values = [450, 380, 210, 310]
plt.bar(categories, values)
plt.title("Fruit Sales This Month")
plt.xlabel("Fruit")
plt.ylabel("Units Sold")
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> Four vertical bars · one for each fruit · with heights proportional to the sales values.</p>
<p class="v2-p"><strong>Line-by-line explanation:</strong></p>
<div class="v2-table-wrap"><table class="v2-table"><thead><tr><th>Line</th><th>What it does</th></tr></thead><tbody><tr><td><code>categories</code></td><td>The x-axis labels for each bar</td></tr><tr><td><code>values</code></td><td>The height of each bar</td></tr><tr><td><code>plt.bar(categories, values)</code></td><td>Draws the bar chart</td></tr><tr><td><code>plt.title(...)</code></td><td>Adds a title</td></tr><tr><td><code>plt.xlabel(...)</code></td><td>Labels the x-axis (category axis)</td></tr><tr><td><code>plt.ylabel(...)</code></td><td>Labels the y-axis (value axis)</td></tr></tbody></table></div>
<h3 class="v2-h3">Customising Bar Colour</h3>
<p class="v2-p">Pass a single colour for all bars, or a list of colours:</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
categories = ["Apples", "Bananas", "Cherries", "Dates"]
values = [450, 380, 210, 310]
# All bars the same colour
plt.bar(categories, values, color='steelblue')
plt.title("Fruit Sales")
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> All four bars in steel blue.</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
categories = ["Apples", "Bananas", "Cherries", "Dates"]
values = [450, 380, 210, 310]
# Each bar a different colour
colours = ['red', 'yellow', 'crimson', 'saddlebrown']
plt.bar(categories, values, color=colours)
plt.title("Fruit Sales")
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> Red bar for Apples, yellow for Bananas, crimson for Cherries, brown for Dates.</p>
<h3 class="v2-h3">Controlling Bar Width</h3>
<p class="v2-p">The default bar width is <code>0.8</code>. Use <code>width</code> to change it:</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
categories = ["Apples", "Bananas", "Cherries", "Dates"]
values = [450, 380, 210, 310]
plt.bar(categories, values, width=0.4)
plt.title("Narrower Bars")
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> Narrower bars with more space between them.</p>
<ul class="v2-ul"><li><code>width=1.0</code> · bars touch each other</li><li><code>width=0.8</code> · default (small gap between bars)</li><li><code>width=0.4</code> · narrow bars with larger gaps</li></ul>
<h3 class="v2-h3">Horizontal Bar Charts</h3>
<p class="v2-p">Swap <code>plt.bar()</code> for <code>plt.barh()</code> to draw horizontal bars:</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
categories = ["Apples", "Bananas", "Cherries", "Dates"]
values = [450, 380, 210, 310]
plt.barh(categories, values, color='darkorange')
plt.title("Fruit Sales — Horizontal")
plt.xlabel("Units Sold")
plt.ylabel("Fruit")
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> Four horizontal bars extending from left to right, one per fruit.</p>
<blockquote class="v2-bq"><p class="v2-p"><strong>When to use horizontal bars:</strong> Horizontal bars are especially useful when you have many categories or long category names · they fit much better along the y-axis without overlapping.</p></blockquote>
<h3 class="v2-h3">Adding a Grid to a Bar Chart</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
categories = ["Apples", "Bananas", "Cherries", "Dates"]
values = [450, 380, 210, 310]
plt.bar(categories, values, color='steelblue')
plt.title("Fruit Sales")
plt.xlabel("Fruit")
plt.ylabel("Units Sold")
plt.grid(axis='y', linestyle='--', linewidth=0.7, color='grey')
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> A bar chart with horizontal dashed grey gridlines, making it easy to read the exact height of each bar.</p>
<blockquote class="v2-bq"><p class="v2-p"><strong>Best practice:</strong> For bar charts, add <code>axis='y'</code> to the grid so only horizontal lines appear. Vertical gridlines on a bar chart are usually distracting.</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 Bar Charts</strong>. Open your editor, type the examples above by hand, modify them, and observe what changes.</div></div><button class="ub" onclick="unlockNext(9)">Phase Complete — Unlock Next ✓</button></div></div>
<div class="phase locked" id="phase10"><div class="ph"><div class="pn">Phase 10 of 11</div><div class="pt">Guided Practice Exercises</div><div class="pc" id="chk10"></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 · Weather Line Chart with Markers and Labels</h3>
<p class="v2-p"><strong>Scenario:</strong> You are a meteorologist tracking the daily maximum temperature (°C) in a city for one week.</p>
<p class="v2-p"><strong>Data:</strong></p>
<div class="v2-table-wrap"><table class="v2-table"><thead><tr><th>Day</th><th>Temperature (°C)</th></tr></thead><tbody><tr><td>Mon</td><td>18</td></tr><tr><td>Tue</td><td>21</td></tr><tr><td>Wed</td><td>19</td></tr><tr><td>Thu</td><td>25</td></tr><tr><td>Fri</td><td>27</td></tr><tr><td>Sat</td><td>24</td></tr><tr><td>Sun</td><td>22</td></tr></tbody></table></div>
<p class="v2-p"><strong>Objective:</strong> Create a fully labelled line chart with markers, a styled line, a grid, and appropriate labels.</p>
<p class="v2-p"><strong>Steps:</strong></p>
<ol class="v2-ol"><li>Create a list for days and a list for temperatures</li><li>Call <code>plt.plot()</code> with circle markers and a blue dashed line</li><li>Add a title: <code>"Weekly Maximum Temperatures"</code></li><li>Add x-axis label: <code>"Day of Week"</code></li><li>Add y-axis label: <code>"Temperature (°C)"</code></li><li>Add a grid with only horizontal lines</li><li>Display the chart</li></ol>
<p class="v2-p"><strong>Expected solution:</strong></p></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 matplotlib.pyplot as plt
days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
temps = [18, 21, 19, 25, 27, 24, 22]
plt.plot(days, temps, marker='o', linestyle='dashed', color='steelblue', linewidth=2)
plt.title("Weekly Maximum Temperatures", fontsize=14)
plt.xlabel("Day of Week")
plt.ylabel("Temperature (°C)")
plt.grid(axis='y', linestyle='--', linewidth=0.6, color='grey')
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> A styled blue dashed line with circles at each day's temperature, horizontal gridlines, and full labels.</p>
<p class="v2-p"><strong>Self-check questions:</strong></p>
<ul class="v2-ul"><li>Can you identify the hottest day from the chart?</li><li>What would the chart look like if you added <code>mfc='red'</code> to highlight the data points?</li><li>What if you changed <code>axis='y'</code> to <code>axis='both'</code>?</li></ul>
<p class="v2-p"><strong>What-if challenge:</strong> Add a second line showing the minimum temperatures for the same week: <code>[10, 12, 11, 15, 16, 14, 13]</code></p>
<hr class="v2-hr">
<h3 class="v2-h3">Exercise 2 · Student Score Scatter Chart</h3>
<p class="v2-p"><strong>Scenario:</strong> A teacher wants to see if the number of hours studied relates to exam scores.</p>
<p class="v2-p"><strong>Data:</strong></p>
<div class="v2-table-wrap"><table class="v2-table"><thead><tr><th>Hours studied</th><th>Score (%)</th></tr></thead><tbody><tr><td>1</td><td>55</td></tr><tr><td>2</td><td>60</td></tr><tr><td>3</td><td>65</td></tr><tr><td>2.5</td><td>58</td></tr><tr><td>5</td><td>80</td></tr><tr><td>4</td><td>75</td></tr><tr><td>6</td><td>85</td></tr><tr><td>7</td><td>90</td></tr><tr><td>5.5</td><td>82</td></tr><tr><td>3.5</td><td>70</td></tr></tbody></table></div>
<p class="v2-p"><strong>Objective:</strong> Create a scatter chart with colour-mapped dots showing the score, and a colour bar.</p>
<p class="v2-p"><strong>Steps:</strong></p>
<ol class="v2-ol"><li>Create <code>hours</code> and <code>scores</code> lists</li><li>Use <code>plt.scatter()</code> with <code>c=scores</code>, <code>cmap='YlOrRd'</code>, <code>s=150</code>, <code>alpha=0.8</code></li><li>Add a colour bar</li><li>Add title, x-label, y-label</li><li>Add a horizontal grid</li></ol>
<p class="v2-p"><strong>Expected solution:</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
hours = [1, 2, 3, 2.5, 5, 4, 6, 7, 5.5, 3.5]
scores = [55, 60, 65, 58, 80, 75, 85, 90, 82, 70]
plt.scatter(hours, scores, c=scores, cmap='YlOrRd', s=150, alpha=0.8)
plt.colorbar(label='Score (%)')
plt.title("Study Hours vs Exam Score")
plt.xlabel("Hours Studied")
plt.ylabel("Exam Score (%)")
plt.grid(axis='y', linestyle='--', linewidth=0.5, color='grey')
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> A scatter chart where dots go from yellow (lower scores) to dark red (higher scores), with a colour bar on the right.</p>
<p class="v2-p"><strong>Self-check questions:</strong></p>
<ul class="v2-ul"><li>Does the chart suggest a positive relationship (more hours → higher score)?</li><li>What would <code>cmap='Blues'</code> look like compared to <code>'YlOrRd'</code>?</li></ul>
<hr class="v2-hr">
<h3 class="v2-h3">Exercise 3 · Department Budget Bar Chart</h3>
<p class="v2-p"><strong>Scenario:</strong> A company wants to compare its annual budget allocation across five departments.</p>
<p class="v2-p"><strong>Data:</strong></p>
<div class="v2-table-wrap"><table class="v2-table"><thead><tr><th>Department</th><th>Budget (£ thousands)</th></tr></thead><tbody><tr><td>Engineering</td><td>850</td></tr><tr><td>Marketing</td><td>420</td></tr><tr><td>Operations</td><td>630</td></tr><tr><td>HR</td><td>200</td></tr><tr><td>R&D</td><td>710</td></tr></tbody></table></div>
<p class="v2-p"><strong>Objective:</strong> Create a horizontal bar chart with distinct colours for each department, a grid on the value axis, and full labels.</p>
<p class="v2-p"><strong>Expected solution:</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
departments = ["Engineering", "Marketing", "Operations", "HR", "R&D"]
budgets = [850, 420, 630, 200, 710]
colours = ['steelblue', 'tomato', 'mediumseagreen', 'gold', 'mediumpurple']
plt.barh(departments, budgets, color=colours)
plt.title("Annual Budget by Department", fontsize=14)
plt.xlabel("Budget (£ thousands)")
plt.ylabel("Department")
plt.grid(axis='x', linestyle='--', linewidth=0.6, color='grey')
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> Five horizontal bars of different colours, with dashed vertical gridlines behind them, making budget values easy to read.</p>
<hr class="v2-hr">
<h3 class="v2-h3">Exercise 4 · Subplot Comparison Dashboard</h3>
<p class="v2-p"><strong>Scenario:</strong> You want a single figure showing three related charts · daily sales as a line chart, product category sales as a bar chart, and customer age vs purchase value as a scatter chart.</p>
<p class="v2-p"><strong>Objective:</strong> Build a 1×3 subplot layout with three different chart types.</p>
<p class="v2-p"><strong>Expected solution:</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
# Data
days = [1, 2, 3, 4, 5, 6, 7]
sales = [120, 145, 132, 178, 155, 190, 168]
categories = ["Electronics", "Clothing", "Food", "Books"]
cat_sales = [450, 320, 210, 140]
ages = [22, 35, 41, 28, 55, 48, 33, 29, 62, 44]
amounts = [150, 320, 280, 190, 450, 370, 220, 175, 500, 310]
# Create figure
plt.figure(figsize=(15, 4))
# Chart 1: Line chart
plt.subplot(1, 3, 1)
plt.plot(days, sales, marker='o', color='steelblue', linewidth=2)
plt.title("Daily Sales")
plt.xlabel("Day")
plt.ylabel("Sales (£)")
plt.grid(axis='y', linestyle='--', linewidth=0.5)
# Chart 2: Bar chart
plt.subplot(1, 3, 2)
plt.bar(categories, cat_sales, color=['steelblue', 'tomato', 'mediumseagreen', 'gold'])
plt.title("Sales by Category")
plt.xlabel("Category")
plt.ylabel("Sales (£)")
plt.grid(axis='y', linestyle='--', linewidth=0.5)
# Chart 3: Scatter chart
plt.subplot(1, 3, 3)
plt.scatter(ages, amounts, c=amounts, cmap='viridis', s=80, alpha=0.8)
plt.title("Age vs Purchase Value")
plt.xlabel("Customer Age")
plt.ylabel("Purchase (£)")
plt.grid(linestyle='--', linewidth=0.4)
plt.suptitle("Sales Dashboard — Week 1", fontsize=16, fontweight='bold')
plt.tight_layout()
plt.show()</code></pre></div></div>
<p class="v2-p"><strong>Expected output:</strong> A single figure containing three charts side-by-side forming a mini dashboard, with an overall title.</p>
<blockquote class="v2-bq"><p class="v2-p"><code>plt.tight_layout()</code> · automatically adjusts spacing between subplots so labels and titles don't overlap. Always use it when building subplots.</p></blockquote>
<hr class="v2-hr"></div><button class="ub" onclick="unlockNext(10)">Mark Complete and Unlock Next ✓</button></div></div>
<div class="phase locked" id="phase11"><div class="ph"><div class="pn">Phase 11 of 11</div><div class="pt">Common Beginner Mistakes</div><div class="pc" id="chk11"></div></div><div class="pb2"><h3 class="v2-h3">Mistake 1 · Calling <code>plt.show()</code> Too Early</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># WRONG
plt.plot(x, y)
plt.show() # Chart displays here with nothing else
plt.title("My Chart") # This line has no effect — chart already shown
# CORRECT
plt.plot(x, y)
plt.title("My Chart") # Add everything first
plt.show() # Then display</code></pre></div></div>
<h3 class="v2-h3">Mistake 2 · Mismatched List Lengths</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># WRONG — x has 5 values, y has 4 values
x = [1, 2, 3, 4, 5]
y = [10, 20, 30, 40]
plt.plot(x, y) # Raises ValueError
# CORRECT
x = [1, 2, 3, 4, 5]
y = [10, 20, 30, 40, 50]
plt.plot(x, y)</code></pre></div></div>
<p class="v2-p"><strong>Rule:</strong> <code>x</code> and <code>y</code> lists must always have exactly the same number of values.</p>
<h3 class="v2-h3">Mistake 3 · Subplot Position Starting at 0</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># WRONG — positions start at 1, not 0
plt.subplot(1, 2, 0) # Raises ValueError
# CORRECT
plt.subplot(1, 2, 1)</code></pre></div></div>
<h3 class="v2-h3">Mistake 4 · Forgetting <code>plt.legend()</code> After Adding Labels</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># WRONG — labels added but legend never shown
plt.plot(x, y1, label='Dataset A')
plt.plot(x, y2, label='Dataset B')
plt.show() # No legend visible
# CORRECT
plt.plot(x, y1, label='Dataset A')
plt.plot(x, y2, label='Dataset B')
plt.legend() # This line makes the legend appear
plt.show()</code></pre></div></div>
<h3 class="v2-h3">Mistake 5 · Using <code>color</code> Instead of <code>c</code> in Scatter for Lists</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># WRONG — passing a list to color= in scatter
plt.scatter(x, y, color=['red', 'blue', 'green']) # May raise an error
# CORRECT — use c= when passing a list
plt.scatter(x, y, c=['red', 'blue', 'green'])</code></pre></div></div>
<h3 class="v2-h3">Mistake 6 · Grid Lines Obscuring Data</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># Poor practice — thick dark grid lines overpower the data
plt.grid(color='black', linewidth=3)