5 Class HoursSyllabus
Unit 06 • 5 Class Hours • 10-15 Exam Marks

Data Visualization with Matplotlib

In empirical computing, raw numbers and high-dimensional arrays remain opaque until translated into visual geometry. Matplotlib is Python's foundational 2D visualization library, engineered by John D. Hunter in 2003 to emulate MATLAB's graphics engine while providing deep object-oriented control over every pixel on the canvas.

👨‍🏫 Teacher's Board Note: यो Unit बाट TU परीक्षामा सामान्यतया एउटा १० नम्बरको लामो कोडिङ प्रश्न (जस्तै subplot2grid प्रयोग गरेर dashboard बनाउने वा Grouped Bar/Scatter plot कोर्ने) र एउटा ५ नम्बरको सैद्धान्तिक प्रश्न (जस्तै Boxplot को IQR/Whiskers anatomy वा Pyplot vs OO API) सोधिन्छ। यदि तपाईंले Figure र Axes को Object-Oriented फरक बुझ्नुभयो भने यो युनिटबाट full marks ल्याउन एकदमै सजिलो हुन्छ!
Architecture
3 Layers
Grid Systems
Subplot2grid
Key Plot Types
6 Core Styles
Dual Axis
ax.twinx()
Section 01 • Core Engine Anatomy

The 3-Tier Architecture of Matplotlib

To understand how Matplotlib transforms floating-point numbers into anti-aliased vector curves, one must grasp its internal three-tiered stack:

  1. The Backend Layer (Low-Level Drawing Engine): Contains the concrete rendering machinery that talks to physical output devices. It handles rasterization (converting vectors into pixels) and window events. Key components include FigureCanvas (drawing surface), Renderer (draws objects on canvas), and Event (captures keyboard/mouse events). Output formats include raster (Agg, PNG) and vector (PDF, SVG, PostScript).
  2. The Artist Layer (The Hierarchy of Visual Objects): Represents everything you visually perceive on the screen. The Artist hierarchy consists of Primitive Artists (e.g., Line2D, Rectangle, Circle, Text) and Composite Artists (e.g., Axis, Axes, and Figure). Over 95% of data visualization programming operates within this layer.
  3. The Scripting Layer (`matplotlib.pyplot`): A stateful procedural wrapper designed to mimic MATLAB's global command syntax. It automatically instantiates figures, tracks active axes, and executes plotting commands without requiring users to manually configure artist trees.
FIGURE 6.1: The 3-Tier Architecture of MatplotlibLAYERED STACK
+-------------------------------------------------------------------------+
| SCRIPTING LAYER: matplotlib.pyplot                                      |
| Stateful procedural interface for rapid prototyping (MATLAB style).     |
+-------------------------------------------------------------------------+
                                   |
                                   v
+-------------------------------------------------------------------------+
| ARTIST LAYER (Object Tree):                                              |
|   Figure (Root container)                                               |
|     └── Axes (Plot coordinate system)                                    |
|           ├── Axis (X & Y number lines, Ticks, TickLabels)               |
|           ├── Primitives: Line2D, Rectangle (Bars), Circle, Text        |
|           └── Collections: PathCollection (Scatter), PolyCollection     |
+-------------------------------------------------------------------------+
                                   |
                                   v
+-------------------------------------------------------------------------+
| BACKEND LAYER (Device Rendering):                                       |
|   ├── FigureCanvas: Canvas area (Base / GUI Widget: QtAgg, TkAgg)        |
|   ├── Renderer: Vector/raster rasterizer (Agg, PDF, SVG, PS)            |
|   └── Graphics Context (GC): Color, line width, dash pattern properties |
+-------------------------------------------------------------------------+
👨‍🏫 Teacher's Board Note: परीक्षामा "Explain the architecture of Matplotlib" सोधियो भने यो तीन तह (Backend, Artist, Scripting) को स्पष्ट वर्गीकरण र माथिको Figure 6.1 बनाउनु अनिवार्य छ। Scripting Layer ले user सँग कुरा गर्छ, Artist Layer ले ग्राफका सबै अंगहरू सम्हाल्छ, र Backend Layer ले screen वा printer मा pixel/vector कोर्छ।
Section 02 • Programming Interfaces

Pyplot API vs Object-Oriented (OO) Paradigm

Matplotlib provides two fundamentally distinct operational paradigms. Novices often confuse them, producing fragile scripts with unintended side effects:

1. The Pyplot Stateful Procedural API (MATLAB Style)

Uses functions directly from matplotlib.pyplot (e.g., plt.plot(), plt.title()). It maintains an implicit global state machine tracking the current figure (gcf()) and current axes (gca()). Every function modifies the active axes.

Drawback: Becomes dangerously error-prone when generating multiple subplots, asynchronous threads, or embedded GUI applications.

2. The Object-Oriented Explicit Handle Paradigm (Pythonic Standard)

Instantiates explicit object handles: fig, ax = plt.subplots(). Methods are called directly on the Figure or Axes instances (e.g., ax.plot(), ax.set_title()).

Advantage: Clean, modular, thread-safe, and capable of addressing specific subplots independently across complex dashboard layouts.
FeaturePyplot Procedural APIObject-Oriented (OO) API
Setup Callplt.figure()fig, ax = plt.subplots()
Title Settingplt.title("Title")ax.set_title("Title")
Axis Labelsplt.xlabel(), plt.ylabel()ax.set_xlabel(), ax.set_ylabel()
Axis Limitsplt.xlim(), plt.ylim()ax.set_xlim(), ax.set_ylim()
Subplot AddressingImplicit plt.subplot(2, 2, 1)Explicit index axes[0, 0].plot(...)
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y = np.sin(x)

# RECOMMENDED: Explicit Object-Oriented Approach
fig, ax = plt.subplots(figsize=(8, 4))
ax.plot(x, y, label="sin(x)", color="#2563eb", linewidth=2)
ax.set_title("Harmonic Oscillation (OO Paradigm)", fontsize=12)
ax.set_xlabel("Time (seconds)")
ax.set_ylabel("Amplitude")
ax.grid(True, linestyle="--", alpha=0.5)
ax.legend(loc="upper right")
plt.show()
👨‍🏫 Teacher's Board Note: TU MCA को practical र theory दुवैमा fig, ax = plt.subplots() शैली नै लेख्नुहोस्। plt.plot() लेख्दा पनि चल्छ तर multi-panel dashboards बनाउँदा कुन चाहिँ plot सक्रिय छ भनेर state अल्मलिन्छ। OO style मा set_ उपसर्ग (Prefix) लागेका विधिहरू जस्तै ax.set_title(), ax.set_xlabel() प्रयोग गर्नुपर्छ।
Section 03 • Structural Hierarchy

Anatomy of a Figure: Canvas, Axes, Ticks & Spines

A precise understanding of Matplotlib requires distinguishing between the major structural components of a visualization:

  • Figure (The Window Canvas): The top-level bounding container holding all axes, titles, legends, and colorbars.
  • Axes (The Actual Plot Area): The bounding box where data is plotted. A Figure can contain one or dozens of Axes.
  • Axis (The Number Lines): The individual X and Y scale lines that establish data limits and generate ticks.
  • Ticks and TickLabels: The small tick indicators (major and minor) and their text labels positioned along the Axis.
  • Spines: The four boundary lines delimiting the plot area (top, bottom, left, right).
FIGURE 6.2: Anatomy of a Matplotlib FigureSTRUCTURAL HIERARCHY
+-----------------------------------------------------------------------+
| FIGURE (Canvas Container: fig.suptitle("Dashboard Title"))             |
|                                                                       |
|   +-- TOP SPINE (ax.spines['top']) -------------------------------+   |
|   | AXES TITLE (ax.set_title("Subplot 1"))                        |   |
|   |                                                               |   |
| L | Y-AXIS LABEL                                      LEGEND      | R |
| E | (ax.set_ylabel)                                 [Line A]      | I |
| F |   |                                             [Line B]      | G |
| T |   |                                                           | H |
|   | 10+-------*-----------------------*----------- GRID           | T |
| S |   |        \                     /             (ax.grid)      |   |
| P | 5 +---------*-------------------*                             | S |
| I |   |          \                 /               LINE ARTIST    | P |
| N | 0 +-----------*---------------*-------------- (ax.plot)       | I |
| E |   |            \             /                                | N |
|   |   +--+----+----+----+----+----+----+----+----+----+           | E |
|   |      0    1    2    3    4    5    6    7    8    9           |   |
|   |      ^         ^                                              |   |
|   |      MAJOR     MINOR TICK                                     |   |
|   |      TICK                                                     |   |
|   +-- BOTTOM SPINE (ax.spines['bottom']) -------------------------+   |
|                                                                       |
|       X-AXIS LABEL (ax.set_xlabel("Time (s)"))                        |
+-----------------------------------------------------------------------+
👨‍🏫 Teacher's Board Note: Figure भनेको चित्र कोर्ने सेतो क्यानभास (Drawing Sheet) हो, र Axes भनेको त्यो क्यानभास भित्र कोरिएको वास्तविक ग्राफको बाकस (Plot Box) हो। एउटै Figure मा ४ वटा Subplots (Axes) अटाउन सक्छन्। स्पाइन्स (Spines) भनेको चारैतिरका सिमाना रेखाहरू हुन् जसलाई हटाएर ग्राफलाई modern minimalism दिन सकिन्छ।
Section 04 • Continuous Data

Simple Plot, Line Styles, Markers & Customization

The line plot is the fundamental tool for continuous data. The ax.plot() method accepts parameters controlling color, geometry, and marker points:

  • Linestyles (`linestyle` or `ls`): '-' (solid), '--' (dashed), '-.' (dash-dot), ':' (dotted).
  • Markers (`marker`): 'o' (circle), 's' (square), '^' (triangle), '*' (star), 'D' (diamond).
  • Color Formats (`color` or `c`): Named colors ('red'), Hex codes ('#2563eb'), or RGBA tuples.
  • Shorthand String Syntax: ax.plot(x, y, 'r--o') combines red color, dashed line, and circle marker in one compact token.
import matplotlib.pyplot as plt
import numpy as np

months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
mca_attendance = [78, 82, 85, 80, 92, 88]
csit_attendance = [70, 75, 74, 82, 85, 81]

fig, ax = plt.subplots(figsize=(8, 4.5))

# Plot series with explicit styling
ax.plot(months, mca_attendance, color="#d8b979", linestyle="-", 
        linewidth=2.5, marker="o", markersize=7, label="MCA Cohort")

ax.plot(months, csit_attendance, color="#38bdf8", linestyle="--", 
        linewidth=2.0, marker="s", markersize=6, label="B.Sc. CSIT Cohort")

ax.set_title("Student Attendance Trend Comparison", fontsize=13, pad=12)
ax.set_xlabel("Academic Month", fontsize=10)
ax.set_ylabel("Average Attendance (%)", fontsize=10)
ax.set_ylim(60, 100)

ax.grid(True, linestyle=":", alpha=0.6)
ax.legend(loc="lower right", frameon=True)

plt.tight_layout()
plt.show()
👨‍🏫 Teacher's Board Note: परीक्षामा marker, linestyle, र color का फरक देखाउन दुईवटा curves भएको multi-line ग्राफ बनाउनुहोस्। साथै plt.tight_layout() अन्तिममा लेख्दा axis labels र title आपसमा खप्टिने (Overlap) समस्या हट्छ।
Section 05 • Multi-Scale Visualization

Multi-Plots on a Single Canvas & Dual Y-Axes (`twinx`)

When plotting two related variables that share an identical X-axis domain but occupy vastly different numeric magnitudes (e.g., Monthly Temperature in °C vs Rainfall in mm), overlaying them on a single Y-axis distorts the smaller series into an unreadable flat line.

Matplotlib resolves this with `ax.twinx()`: creating an overlay twin Axes that shares the original X-axis while establishing a secondary Y-axis on the right spine.

FIGURE 6.3: Dual Y-Axes Mechanism via `twinx()`DIVERGENT SCALES
PRIMARY Y-AXIS: ax1 (Temperature °C)          SECONDARY Y-AXIS: ax2 (Rainfall mm)
Scale: 0 to 40 °C                             Scale: 0 to 500 mm
                +---------------------------------------+
   40 °C -------|                                       |------- 500 mm
                |          ax1.plot() (Line)            |
   30 °C -------|          [Temperature Curve]          |------- 375 mm
                |                                       |
   20 °C -------|          ax2.bar() (Bars)             |------- 250 mm
                |          [Rainfall Volume]            |
   10 °C -------|                                       |------- 125 mm
                |                                       |
    0 °C -------+---------------------------------------+------- 0 mm
                   Jan   Feb   Mar   Apr   May   Jun
                   SHARED X-AXIS: ax1 and ax2 share domain
import matplotlib.pyplot as plt

months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"]
temperature = [12, 15, 20, 26, 29, 28, 27]       # °C (Scale 0-35)
rainfall = [20, 35, 45, 90, 180, 360, 420]         # mm (Scale 0-500)

fig, ax1 = plt.subplots(figsize=(8, 4.5))

# Primary Axis: Temperature Line
color1 = "#f87171" # Warm Red
ax1.set_xlabel("Month")
ax1.set_ylabel("Temperature (°C)", color=color1)
line1 = ax1.plot(months, temperature, color=color1, marker="o", linewidth=2.5, label="Avg Temp")
ax1.tick_params(axis="y", labelcolor=color1)
ax1.set_ylim(0, 35)

# Secondary Axis: Rainfall Bars
ax2 = ax1.twinx()
color2 = "#38bdf8" # Sky Blue
ax2.set_ylabel("Precipitation (mm)", color=color2)
bars = ax2.bar(months, rainfall, color=color2, alpha=0.35, width=0.4, label="Rainfall")
ax2.tick_params(axis="y", labelcolor=color2)
ax2.set_ylim(0, 500)

ax1.set_title("Kathmandu Climate: Temperature vs Monsoon Precipitation", pad=12)
fig.tight_layout()
plt.show()
👨‍🏫 Teacher's Board Note: ax.twinx() भनेको एउटै X-axis (Months) मा दुईवटा फरक नाप (Scale) भएका डाटा देखाउने विधि हो। तापक्रम १० देखि ३० डिग्री हुन्छ तर पानी ३०० मिलिमिटर पर्छ। एउटै Y-axis मा राख्दा १० डिग्रीको रेखा भुइँमै टाँसिन्छ। त्यसैले ax2 = ax1.twinx() गरेर दायाँतर्फ नयाँ Y-axis थपिन्छ।
Section 06 • Multi-Panel Grids

`subplots()` Function & Axis Sharing

The plt.subplots(nrows, ncols) function serves as the workhorse for creating uniform grid arrays of subplots in a single invocation. It returns a tuple containing the Figure and a NumPy array of Axes objects:

  • 2D Array Indexing: For a 2x2 grid, subplots are addressed as axes[0, 0] (top-left), axes[0, 1] (top-right), axes[1, 0] (bottom-left), and axes[1, 1] (bottom-right).
  • Flattening with `axes.flatten()`: When iterating over subplots programmatically, flattening the 2D array into a 1D sequence simplifies the loop structure.
  • Axis Sharing (`sharex=True`, `sharey=True`): Synchronizes zooming and eliminates redundant duplicate tick markings on interior plots.
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 2 * np.pi, 200)

fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(9, 6), sharex=True)

# Panel (0, 0): Sine Wave
axes[0, 0].plot(x, np.sin(x), color="#d8b979")
axes[0, 0].set_title("Sine: sin(x)")
axes[0, 0].grid(True, linestyle=":")

# Panel (0, 1): Cosine Wave
axes[0, 1].plot(x, np.cos(x), color="#38bdf8")
axes[0, 1].set_title("Cosine: cos(x)")
axes[0, 1].grid(True, linestyle=":")

# Panel (1, 0): Tangent Wave
axes[1, 0].plot(x, np.tan(x), color="#f87171")
axes[1, 0].set_title("Tangent: tan(x)")
axes[1, 0].set_ylim(-5, 5)
axes[1, 0].grid(True, linestyle=":")

# Panel (1, 1): Damped Sine Wave
axes[1, 1].plot(x, np.exp(-x/3) * np.sin(3*x), color="#4ade80")
axes[1, 1].set_title("Damped Oscillation")
axes[1, 1].grid(True, linestyle=":")

fig.suptitle("Trigonometric Signal Matrix", fontsize=14, y=0.98)
fig.tight_layout()
plt.show()
👨‍🏫 Teacher's Board Note: जब nrows > 1ncols > 1 हुन्छ, axes variable एउटा 2D NumPy array बन्छ। विद्यार्थीहरूले axes[0].plot() लेखेर IndexError निकाल्छन्। सधैं axes[row, col] लेख्नुहोस् वा ax = axes.flatten() गरेर ax[0], ax[1], ax[2] प्रयोग गर्नुहोस्।
Section 07 • Advanced Grid Geometry

`subplot2grid()` for Asymmetrical Executive Dashboards

While plt.subplots() generates rigid, equal-sized grid cells, modern analytical dashboards require asymmetrical layouts: a dominant primary chart spanning multiple rows or columns, accompanied by smaller subordinate diagnostic widgets.

The `plt.subplot2grid(shape, loc, rowspan=1, colspan=1)` function provides this capability:

  • `shape`: A tuple (nrows, ncols) establishing the underlying virtual grid resolution.
  • `loc`: A tuple (row, col) pinpointing the top-left anchor coordinate of the subplot.
  • `rowspan`: Number of vertical rows the subplot expands across.
  • `colspan`: Number of horizontal columns the subplot expands across.
FIGURE 6.4: subplot2grid 3x3 Asymmetric Dashboard MatrixGRID SPANNING
VIRTUAL GRID: (3, 3) -> 3 Rows x 3 Columns
Col 0                     Col 1                     Col 2
+-----------------------------------------------------------------------+
| Row 0: PRIMARY HERO CHART                                              |
| loc=(0, 0), rowspan=2, colspan=3                                      |
| (Spans 2 full rows and all 3 horizontal columns)                      |
|                                                                       |
| Row 1: (Continues hero chart area)                                    |
+-------------------------+-------------------------+-------------------+
| Row 2: WIDGET 1         | Row 2: WIDGET 2         | Row 2: WIDGET 3   |
| loc=(2, 0)              | loc=(2, 1)              | loc=(2, 2)        |
| rowspan=1, colspan=1    | rowspan=1, colspan=1    | rowspan=1, colspan=1|
+-------------------------+-------------------------+-------------------+
import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure(figsize=(10, 7))

# 1. Master Hero Chart: Spans Top 2 Rows across all 3 Columns
ax_master = plt.subplot2grid((3, 3), (0, 0), rowspan=2, colspan=3)
x = np.linspace(0, 10, 100)
ax_master.plot(x, np.sin(x), color="#d8b979", linewidth=2)
ax_master.set_title("Master Performance Timeline (rowspan=2, colspan=3)")
ax_master.grid(True, linestyle=":")

# 2. Bottom-Left Mini Chart
ax_sub1 = plt.subplot2grid((3, 3), (2, 0), rowspan=1, colspan=1)
ax_sub1.bar(["A", "B", "C"], [10, 24, 18], color="#38bdf8")
ax_sub1.set_title("Category Distribution")

# 3. Bottom-Middle Mini Chart
ax_sub2 = plt.subplot2grid((3, 3), (2, 1), rowspan=1, colspan=1)
ax_sub2.hist(np.random.randn(200), bins=15, color="#4ade80", edgecolor="black")
ax_sub2.set_title("Residual Variance")

# 4. Bottom-Right Mini Chart
ax_sub3 = plt.subplot2grid((3, 3), (2, 2), rowspan=1, colspan=1)
ax_sub3.pie([65, 35], labels=["Pass", "Fail"], autopct="%1.0f%%", colors=["#d8b979", "#f87171"])
ax_sub3.set_title("Pass Ratio")

fig.suptitle("TU MCA Executive Analytical Dashboard", fontsize=14, y=0.98)
fig.tight_layout()
plt.show()
👨‍🏫 Teacher's Board Note: TU MCA परीक्षामा १० नम्बरको प्रश्नमा "Explain subplot2grid() with a code layout example" बारम्बार सोधिन्छ। (3, 3) को नक्सा कोरेर माथिल्लो २ लहर (rowspan=2) मा ठूलो मेन ग्राफ र पुछारको लहरमा ३ वटा साना ग्राफ (colspan=1) बनाएको देखाइदिनुभयो भने परीक्षकले पूरा नम्बर दिन्छन्।
Section 08 • Typography & Scales

Formatting Axes, Ticks, Limits & Grids

Visual polish separates amateur sketches from publication-grade scientific graphics:

  • Setting Limits: ax.set_xlim(min, max) and ax.set_ylim(min, max) clamp visible domains to eliminate misleading blank borders.
  • Custom Ticks & Labels: ax.set_xticks([0, 25, 50, 75, 100]) and ax.set_xticklabels(['0%', '25%', ...], rotation=45) prevent label overlaps.
  • Logarithmic Scales: ax.set_yscale('log') transforms power-law or exponential distributions into readable linear slopes.
  • Spine Manipulation: Hiding non-essential spines produces clean, modern graphics:
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)
👨‍🏫 Teacher's Board Note: वैज्ञानिक ग्राफिक्समा दायाँ र माथिको सिमाना (Top & Right Spines) हटाउँदा ग्राफ एकदमै modern र clean देखिन्छ। Exponential growth (जस्तै algorithm को time complexity $O(2^n)$) देखाउँदा सधैं ax.set_yscale('log') प्रयोग गर्नुपर्छ।
Section 09 • Discrete Categories

Bar Plots: Vertical, Horizontal, Grouped & Stacked

Bar plots encode numerical values as rectangular lengths across discrete categorical classes. Matplotlib supports four configurations:

  1. Vertical Bar (`ax.bar`): Standard configuration for comparing quantities across discrete categories.
  2. Horizontal Bar (`ax.barh`): Recommended when categorical labels have long string names, avoiding unreadable vertical tilts.
  3. Grouped Bar Chart: Compares multiple sub-metrics per category side-by-side by computing mathematical offsets along the X-axis (x - width/2 and x + width/2).
  4. Stacked Bar Chart: Uses the bottom parameter to stack one category directly atop another, illustrating both total volume and sub-component contributions.
import matplotlib.pyplot as plt
import numpy as np

departments = ["MCA", "CSIT", "BCA", "BBM"]
theory_pass = [42, 38, 45, 30]
practical_pass = [48, 45, 46, 35]

x = np.arange(len(departments))
bar_width = 0.35

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4.5))

# 1. Grouped Bar Chart (Side-by-Side)
ax1.bar(x - bar_width/2, theory_pass, width=bar_width, label="Theory", color="#d8b979")
ax1.bar(x + bar_width/2, practical_pass, width=bar_width, label="Practical", color="#38bdf8")
ax1.set_title("Grouped Bar Chart: Exam Mode")
ax1.set_xticks(x)
ax1.set_xticklabels(departments)
ax1.set_ylabel("Students Passed")
ax1.legend()
ax1.grid(axis="y", linestyle=":", alpha=0.6)

# 2. Stacked Bar Chart (Cumulative using 'bottom')
ax2.bar(departments, theory_pass, label="Theory Pass", color="#d8b979")
ax2.bar(departments, practical_pass, bottom=theory_pass, label="Practical Pass", color="#4ade80")
ax2.set_title("Stacked Bar Chart: Aggregate Total")
ax2.set_ylabel("Total Clearances")
ax2.legend()
ax2.grid(axis="y", linestyle=":", alpha=0.6)

plt.tight_layout()
plt.show()
👨‍🏫 Teacher's Board Note: Grouped bar chart बनाउँदा विद्यार्थीहरूले बारहरू खप्टिने (Overlap हुने) गल्ती गर्छन्। बार खप्टिन नदिन x - bar_width/2x + bar_width/2 को गणितीय offset दिनुपर्छ। Stacked Bar Chart बनाउँदा दोस्रो बारमा bottom=first_bar_data लेख्न कहिल्यै नबिर्सिनुहोला!
Section 10 • Statistical Distributions

Histograms: Bins, Density & Probability Distributions

A histogram approximates the probability distribution of a continuous variable by dividing the entire range into consecutive, non-overlapping intervals called bins.

  • Continuous vs Discrete: While Bar charts display discrete categorical counts with artificial spacing, Histograms display continuous data where bar widths represent interval ranges and bar touching reflects continuity.
  • `bins` Parameter: Can accept an integer count (e.g., bins=20) or an explicit list of boundary edges.
  • `density=True`: Normalizes bin heights so the total integrated area equals 1.0, representing a valid Probability Density Function (PDF).
import matplotlib.pyplot as plt
import numpy as np

np.random.seed(42)
mca_scores = np.random.normal(loc=72, scale=10, size=500) # Normal dist: mean=72, std=10

fig, ax = plt.subplots(figsize=(8, 4.5))

counts, bins, patches = ax.hist(
    mca_scores,
    bins=15,
    density=False,
    color="#d8b979",
    edgecolor="#0a0a0d",
    alpha=0.85
)

# Mean and standard deviation marker lines
ax.axvline(np.mean(mca_scores), color="#ef4444", linestyle="--", linewidth=2, label="Mean (72)")
ax.axvline(np.median(mca_scores), color="#38bdf8", linestyle="-.", linewidth=2, label="Median")

ax.set_title("Distribution of Student Exam Scores (N=500)", fontsize=13, pad=12)
ax.set_xlabel("Marks Obtained (0-100)")
ax.set_ylabel("Frequency (Student Count)")
ax.legend()
ax.grid(axis="y", linestyle=":", alpha=0.5)

plt.tight_layout()
plt.show()
👨‍🏫 Teacher's Board Note: Bar Chart र Histogram बिचको भिन्नता TU को धेरै पुरानो favourite question हो! Bar Chart मा प्रत्येक स्तम्भको बिचमा खाली ठाउँ (Gap) हुन्छ किनभने तिनीहरू अलग-अलग discrete categories हुन्। तर Histogram मा continuous data भएकोले बारहरू आपसमा जोडिएका (Contiguous) हुन्छन्।
Section 11 • Bivariate & Multivariate

Scatter Plots: Sizing, Colormaps & Multi-Dimensionality

Scatter plots display relationships between two continuous variables. With Matplotlib's ax.scatter(), a 2D sheet of paper can represent up to 4 dimensions of data simultaneously:

  1. Dimension 1 (X position): Variable 1 (e.g., Study Hours per Week).
  2. Dimension 2 (Y position): Variable 2 (e.g., Final Semester GPA).
  3. Dimension 3 (Point Size `s`): Variable 3 (e.g., Lab Project Scores scaled to bubble radii).
  4. Dimension 4 (Color `c` & Colormap `cmap`): Variable 4 (e.g., Attendance percentage mapped to a color spectrum).
import matplotlib.pyplot as plt
import numpy as np

np.random.seed(101)
n_students = 60
study_hours = np.random.uniform(5, 35, n_students)
gpa = 2.0 + (study_hours * 0.055) + np.random.normal(0, 0.25, n_students)
gpa = np.clip(gpa, 2.0, 4.0)

project_score = np.random.uniform(20, 100, n_students)  # Size dimension
attendance = np.random.uniform(60, 100, n_students)     # Color dimension

fig, ax = plt.subplots(figsize=(8.5, 5))

scatter = ax.scatter(
    study_hours,
    gpa,
    s=project_score * 2.5,   # Bubble size
    c=attendance,            # Continuous color
    cmap="viridis",          # Perceptually uniform colormap
    alpha=0.75,
    edgecolors="white",
    linewidth=0.8
)

# Add Colorbar bound to scatter object
cbar = fig.colorbar(scatter, ax=ax)
cbar.set_label("Attendance Percentage (%)")

ax.set_title("Multivariate Student Analytics (X: Hours, Y: GPA, Size: Project, Color: Attendance)")
ax.set_xlabel("Weekly Study Hours")
ax.set_ylabel("Graduation GPA (Scale 4.0)")
ax.grid(True, linestyle=":", alpha=0.5)

plt.tight_layout()
plt.show()
👨‍🏫 Teacher's Board Note: ax.scatter() को मुख्य तागत भनेको एउटै ग्राफमा ४ वटा आयाम (Dimensions) देखाउन पाउनु हो: X-position, Y-position, Bubble Size (s), र Color gradient (c with cmap='viridis')। यसको साथमा fig.colorbar(scatter) जोड्न नबिर्सिनुहोला।
Section 12 • Proportions & Pitfalls

Pie Charts: Autopct, Explode & Shadows

Pie charts illustrate proportional parts-of-a-whole compositions. In Matplotlib, ax.pie() provides parameters for precision formatting:

  • `autopct`: String formatter (e.g., '%1.1f%%') calculating and displaying percentage text automatically.
  • `explode`: Fractional tuple (e.g., (0, 0.1, 0, 0)) physically detaching selected slices for emphasis.
  • `startangle`: Rotates the initial pie slice counter-clockwise from the X-axis (typically 90° for vertical symmetry).
  • Academic Critique: Data science literature cautions against pie charts when slices exceed 5 or have similar percentages, as human perception judges lengths (Bar plots) far more accurately than angles and areas.
import matplotlib.pyplot as plt

grades = ["Distinction", "First Division", "Second Division", "Failed"]
students = [45, 80, 25, 10]
colors = ["#d8b979", "#38bdf8", "#a8a29e", "#ef4444"]
explode = (0.1, 0, 0, 0)  # Emphasize top performers

fig, ax = plt.subplots(figsize=(6.5, 6.5))

wedges, texts, autotexts = ax.pie(
    students,
    labels=grades,
    autopct="%1.1f%%",
    startangle=140,
    explode=explode,
    colors=colors,
    shadow=True,
    textprops={"fontsize": 10}
)

# Enhance visibility of percentage labels inside wedges
for at in autotexts:
    at.set_color("#0b0d13")
    at.set_weight("bold")

ax.set_title("TU MCA Cohort Final Grading Breakdown", pad=20, fontsize=12)
plt.tight_layout()
plt.show()
👨‍🏫 Teacher's Board Note: explode parameter ले कुनै खास slice (जस्तै Distinction पाएका विद्यार्थी) लाई बाहिर तानेर हाइलाइट गर्छ। autopct='%1.1f%%' ले मानहरूलाई प्रतिशत (Percentage) मा स्वतः बदल्छ।
Section 13 • Non-Parametric Summary

Box Plots: Five-Number Summary, IQR & Outliers

The Box-and-Whisker plot (invented by John Tukey) is the gold standard for comparing distributions across groups without assuming normality. It visually encapsulates the Five-Number Summary:

  1. Median ($Q_2$ / 50th Percentile): The central dividing line inside the box.
  2. Lower Quartile ($Q_1$ / 25th Percentile): The bottom hinge of the rectangular box.
  3. Upper Quartile ($Q_3$ / 75th Percentile): The top hinge of the rectangular box.
  4. Interquartile Range ($IQR$): The vertical height of the box ($IQR = Q_3 - Q_1$), containing the middle 50% of observation records.
  5. Whiskers: Extend to the furthest data point within $1.5 \times IQR$ from the hinges ($Q_1 - 1.5 \times IQR$ and $Q_3 + 1.5 \times IQR$).
  6. Outliers (Fliers): Any observation falling strictly outside the $1.5 \times IQR$ fences, rendered as individual circular markers.
FIGURE 6.5: Box-and-Whisker Plot Statistical AnatomyTU EXAM ESSENTIAL
   o   <-- OUTLIER / FLIER (> Q3 + 1.5 * IQR)
   |
+--+--+  <-- UPPER WHISKER: Max value within (Q3 + 1.5 * IQR)
   |
   |
+--+--------------------+  <-- UPPER QUARTILE (Q3 / 75th Percentile)
|                       |
|                       |  <-- INTERQUARTILE RANGE (IQR = Q3 - Q1)
|  ===================  |  <-- MEDIAN (Q2 / 50th Percentile)
|                       |      (Middle 50% of all data)
|                       |
+--+--------------------+  <-- LOWER QUARTILE (Q1 / 25th Percentile)
   |
   |
+--+--+  <-- LOWER WHISKER: Min value within (Q1 - 1.5 * IQR)
   |
   o   <-- OUTLIER / FLIER (< Q1 - 1.5 * IQR)
import matplotlib.pyplot as plt
import numpy as np

np.random.seed(42)
mca_marks = np.random.normal(75, 8, 100)
csit_marks = np.random.normal(70, 12, 100)
# Inject deliberate outliers
csit_marks = np.append(csit_marks, [30, 32, 99])

fig, ax = plt.subplots(figsize=(7, 5))

bp = ax.boxplot(
    [mca_marks, csit_marks],
    labels=["MCA Cohort", "CSIT Cohort"],
    patch_artist=True,   # Fill with color
    notch=False,
    showmeans=True
)

# Custom color styling
colors = ["#d8b979", "#38bdf8"]
for patch, color in zip(bp['boxes'], colors):
    patch.set_facecolor(color)
    patch.set_alpha(0.7)

ax.set_title("Cross-Department Exam Marks Variance & Outlier Detection")
ax.set_ylabel("Marks (0-100)")
ax.grid(axis="y", linestyle=":", alpha=0.5)

plt.tight_layout()
plt.show()
👨‍🏫 Teacher's Board Note: Box Plot को यो $1.5 \times IQR$ को formula परीक्षामा १००% आउने प्रश्न हो! $IQR$ भनेको $Q_3 - Q_1$ हो। यदि कुनै विद्यार्थीको नम्बर $Q_3 + 1.5 \times IQR$ भन्दा माथि वा $Q_1 - 1.5 \times IQR$ भन्दा तल गयो भने त्यसलाई Outlier (असामान्य डेटा) मानिन्छ र थोप्ला (Circle) ले देखाइन्छ।
Section 14 • Production Engineering

Exporting Graphics (`savefig`) & Memory Safety

In production environments (such as web microservices or automated reporting daemons), figures must be saved to disk rather than displayed interactively with plt.show():

# High-Resolution Publication Export
fig.savefig(
    "mca_academic_report.png",
    dpi=300,                  # 300 Dots Per Inch for print quality
    bbox_inches="tight",      # Trims unnecessary blank whitespace padding
    transparent=False,        # Preserves opaque solid background
    format="png"              # Raster (PNG, JPG) or Vector (PDF, SVG, EPS)
)

# CRITICAL: Prevent Memory Leaks in Server Batch Pipelines!
plt.close(fig)
👨‍🏫 Teacher's Board Note: सर्भर वा ब्याच प्रोसेसिङमा हजारौँ ग्राफ बनाउँदा plt.close(fig) लेखिएन भने Matplotlib ले सबै Figure Memory मा राखिराख्छ र RAM Full (Memory Leak) भएर सर्भर क्र्यास हुन्छ। bbox_inches='tight' ले ग्राफ वरिपरिको अनावश्यक सेतो भाग काटेर चिटिक्क पार्छ।
Section 15 • End-to-End Capstone

Full Exam Project: 4-Panel Executive Student Analytics Dashboard

A standard 10-mark long coding problem in TU MCA examinations states: "Write a complete Python script utilizing Matplotlib to construct a multi-panel visual dashboard displaying student performance across four diverse plot types: a grouped bar chart, a scatter correlation, a boxplot outlier detector, and an exploded pie chart."

import matplotlib.pyplot as plt
import numpy as np

def build_student_dashboard():
    # Simulated Examination Data
    semesters = ["Sem 1", "Sem 2", "Sem 3", "Sem 4"]
    theory_avg = [68, 72, 75, 80]
    practical_avg = [78, 82, 85, 89]

    np.random.seed(42)
    study_hours = np.random.uniform(10, 40, 50)
    gpa = 2.2 + (study_hours * 0.045) + np.random.normal(0, 0.2, 50)

    dept_a = np.random.normal(74, 6, 40)
    dept_b = np.random.normal(70, 10, 40)
    dept_c = np.random.normal(82, 5, 40)

    grade_labels = ["Distinction", "1st Div", "2nd Div", "Fail"]
    grade_shares = [35, 45, 15, 5]

    # Initialize Canvas
    fig = plt.figure(figsize=(12, 8))

    # PANEL 1: Grouped Bar Chart (Top-Left)
    ax1 = plt.subplot2grid((2, 2), (0, 0))
    x = np.arange(len(semesters))
    width = 0.35
    ax1.bar(x - width/2, theory_avg, width, label="Theory", color="#d8b979")
    ax1.bar(x + width/2, practical_avg, width, label="Practical", color="#38bdf8")
    ax1.set_title("1. Semester Mean Scores (Grouped Bar)")
    ax1.set_xticks(x)
    ax1.set_xticklabels(semesters)
    ax1.set_ylabel("Marks (%)")
    ax1.legend()
    ax1.grid(axis="y", linestyle=":", alpha=0.5)

    # PANEL 2: Scatter Plot (Top-Right)
    ax2 = plt.subplot2grid((2, 2), (0, 1))
    sc = ax2.scatter(study_hours, gpa, c=gpa, cmap="plasma", alpha=0.85, edgecolors="white")
    ax2.set_title("2. Hours vs GPA Correlation (Scatter)")
    ax2.set_xlabel("Weekly Study Hours")
    ax2.set_ylabel("GPA")
    fig.colorbar(sc, ax=ax2, label="GPA Scale")
    ax2.grid(True, linestyle=":", alpha=0.5)

    # PANEL 3: Box-and-Whisker Plot (Bottom-Left)
    ax3 = plt.subplot2grid((2, 2), (1, 0))
    ax3.boxplot([dept_a, dept_b, dept_c], labels=["Software", "Network", "AI"], patch_artist=True)
    ax3.set_title("3. Department Score Variance (Box Plot)")
    ax3.set_ylabel("Marks Distribution")
    ax3.grid(axis="y", linestyle=":", alpha=0.5)

    # PANEL 4: Exploded Pie Chart (Bottom-Right)
    ax4 = plt.subplot2grid((2, 2), (1, 1))
    ax4.pie(grade_shares, labels=grade_labels, autopct="%1.1f%%", explode=[0.1, 0, 0, 0],
            colors=["#d8b979", "#38bdf8", "#a8a29e", "#ef4444"], startangle=120)
    ax4.set_title("4. Grade Classification (Pie)")

    # Overall Polish
    fig.suptitle("TU MCA504 • Comprehensive Student Performance Dashboard", fontsize=15, y=0.98)
    fig.tight_layout()
    fig.savefig("tu_student_dashboard.png", dpi=300, bbox_inches="tight")
    print("[SUCCESS] Dashboard generated and exported to 'tu_student_dashboard.png'.")
    plt.show()

if __name__ == "__main__":
    build_student_dashboard()
👨‍🏫 Teacher's Board Note: यो ३०-लाइनको script मा Unit 6 का सबै मुख्य स्तम्भहरू — subplot2grid, bar offset math, scatter with colormap, boxplot, pie with explode, र savefig — एकै ठाउँमा समेटिएका छन्। परीक्षाको लामो प्रश्नमा यो blueprint दुरुस्त लेख्नुभयो भने पूरा १० अंक प्राप्त हुन्छ!
Special Focus • Final Preparation Hacks

Master Techniques, Mental Models & Exam Writing Hacks

Data visualization questions in TU MCA are practical and rigorous. Applying these 6 Core Mental Models and adhering to the 5-Layer Long Answer Formula will safeguard your answers from examiners' standard mark-deduction traps.

1. The 5-Layer Long Answer Formula for Visualization Questions

When answering 8-mark or 10-mark Matplotlib questions, deliver your solution through this 5-stage architecture:

Layer 1
Formal Definition & Visual Intent (2-3 Sentences):State the exact theoretical purpose of the chart type (e.g., continuous distribution vs discrete comparison).
Layer 2
Hand-Drawn ASCII Sketch / Visual Layout:Sketch the plot anatomy or grid layout clearly (e.g., Figure vs Axes hierarchy, or Boxplot $1.5 \times IQR$ fences).
Layer 3
Minimal Object-Oriented Code Snippet (12-18 Lines):Write explicit fig, ax = plt.subplots() code with realistic data and full labels.
Layer 4
Key Parameters & Function Signatures:Explain parameters like bins, density, explode, autopct, or rowspan.
Layer 5
Production Edge Case / Memory Trap Callout:Note production considerations like plt.close(fig) or tight_layout() padding prevention.

2. The 6 Core Mental Models (अवधारणा दिमागमा बसाउने मुख्य सूत्रहरू)

1. The Art Canvas vs Picture Frames (Figure vs Axes)

सूत्र: Figure = सेतो बोर्ड वा क्यानभास — जसलाई भित्तामा टाँगिन्छ। Axes = त्यो क्यानभासभित्र राखिएका अलग-अलग तस्बिरका फ्रेमहरू। एउटै Figure मा जतिवटा पनि Axes (Subplots) अटाउन सक्छन्।

fig = Canvas (Window)
ax1, ax2 = Subplot Picture Frames
2. The Rubber Newspaper Grid (subplot2grid Spanning)

सूत्र: subplot2grid = पत्रपत्रिकाको फ्रन्टपेज लेआउट — मुख्य समाचारले माथिका २ वटा लहर (rowspan=2) र सबै कलमहरू (colspan=3) ओगट्छ, र बाँकी साना समाचार तलका कोठाहरूमा बस्छन्।

(3, 3) Grid: Hero spans (0,0) rowspan=2
Mini widgets span row 2 col 0, 1, 2
3. The Five-Number Statistical Vault (Boxplot Anatomy)

सूत्र: Box Plot भनेको डेटाको ५-अंकीय तिजोरी हो। बाकसभित्र ५०% डेटा ($IQR$) बस्छ। बाकसको माथि र तल $1.5 \times IQR$ सम्मका तार (Whiskers) हुन्छन्। तारभन्दा बाहिर उछिट्टिएका थोप्लाहरू Outliers हुन्।

Box: Q1 to Q3 (IQR)
Fences: Q1 - 1.5*IQR and Q3 + 1.5*IQR
4. Twin Scales on One Mountain (twinx Dual Axes)

सूत्र: twinx() = एउटै पहाड चढ्ने दुई फरक मिटर — एउटाले तातोपना (३० °C) नाप्छ, अर्कोले पानीको वजन (४०० mm)। पहाडको भुइँ (X-axis) एउटै हुन्छ, तर देब्रे र दायाँ भित्तामा अलग-अलग Y-scale लेखिन्छ।

ax1.set_ylabel("°C", color='red')
ax2 = ax1.twinx(); ax2.set_ylabel("mm")
5. The 4D Bubble Particle (Scatter Dimensions)

सूत्र: Scatter Plot को प्रत्येक थोप्लो ४-आयामी बेलुन हो — X = कति पढ्यो, Y = कति GPA आयो, Size (s) = प्रोजेक्टको अंक, र Color (c) = कति हाजिर थियो। २D पानामै ४ वटा कथा भन्न सकिन्छ।

(x, y) = Location coordinates
s = Radius area | c = Colormap heat
6. The Memory Leak Ghost (plt.close vs RAM Crash)

सूत्र: Matplotlib ले plt.close(fig) नभनेसम्म बनाएका सबै तस्बिरहरूलाई मेमोरीमा टाँसेर राख्छ। लूपभित्र हजारौँ ग्राफ बनाउँदा close() गरिएन भने सर्भरको RAM भरिएर Out of Memory Crash हुन्छ।

fig.savefig("chart.png")
plt.close(fig) ✅ RAM सुरक्षित

3. The 5 Fatal Examiner Traps in Matplotlib Questions

Candidates often forfeit 30-50% of available marks due to these recurring mistakes:

  • TRAP 1:
    Pyplot vs Axes Method Name Collision: In Pyplot procedural API, you write plt.title(), plt.xlabel(), and plt.xlim(). In the Object-Oriented API, you MUST write ax.set_title(), ax.set_xlabel(), and ax.set_xlim(). Calling ax.title() raises an AttributeError!
  • TRAP 2:
    Grouped Bar Chart Coordinate Overlap: Plotting multiple bars using ax.bar(categories, data1) and ax.bar(categories, data2) places them directly on top of each other, obscuring data1. You must convert categories to numeric indices (np.arange(len(cat))) and apply horizontal shifts (x - width/2).
  • TRAP 3:
    Omitting `tight_layout()` / `bbox_inches='tight'`: In subplots, axis labels and titles frequently collide with adjacent plots unless plt.tight_layout() is invoked. Similarly, saving figures without bbox_inches='tight' crops outer axis titles in exported image files.
  • TRAP 4:
    Misstating Boxplot Whisker Formula: Examiners check the whisker boundary definition strictly. Stating whiskers extend to "minimum and maximum of all data" is incorrect; they extend to the most extreme data points within $1.5 \times IQR$ from quartiles. Points beyond are outliers.
  • TRAP 5:
    Confusing Histogram with Bar Chart: Bar charts plot categorical counts with artificial spacing between bars. Histograms plot continuous binned frequency distributions with contiguous touching bars. Calling plt.hist() on raw categorical strings causes errors.

4. 3-Minute Quick Formula Matrix (Exam Hall Revision Sheet)

Function / MethodSyntax ExampleReturn ObjectExam Keywords
plt.subplots()fig, ax = plt.subplots(2, 2)Figure, ndarray of AxesUniform grid, sharex, sharey
plt.subplot2grid()plt.subplot2grid((3,3),(0,0),rowspan=2)AxesSubplotAsymmetric layouts, rowspan, colspan
ax.twinx()ax2 = ax1.twinx()Secondary AxesShared X, dual independent Y
ax.boxplot()ax.boxplot(data, patch_artist=True)Dict of Artist linesFive-number summary, 1.5*IQR, outliers
ax.scatter()ax.scatter(x, y, s=size, c=val)PathCollectionMultivariate, cmap, bubble radius
fig.savefig()fig.savefig("f.png", dpi=300)None (Disk File)DPI, bbox_inches='tight', plt.close()
Section 16 • Examination Hall Blueprint

TU Exam Q&A Bank: 10 High-Yield Model Answers

Each model answer features 5-Point Quick-Grab Memory Anchors for rapid revision, an authoritative Examination Paragraph Blueprint in English, and an interactive Teacher's Board Note.

Q1TU Model • Matplotlib Architecture & Layers (8 Marks)

Explain the three-layer architecture of Matplotlib in detail. What are the roles of Backend, Artist, and Scripting layers?

5-POINT QUICK-GRAB MEMORY ANCHORS:
  • Tri-Layer Stack: Matplotlib is organized as a three-tier software architecture: Backend Layer, Artist Layer, and Scripting Layer.
  • Backend Layer Role: Handles low-level rendering (Renderer) and event dispatching (Event) onto native GUI canvases (FigureCanvas: Agg, TkAgg, PDF, SVG).
  • Artist Layer Role: The object-oriented tree representing every graphical element; subdivided into Primitive Artists (Line2D, Text) and Composite Artists (Axis, Axes, Figure).
  • Scripting Layer Role: The stateful procedural interface (`matplotlib.pyplot`) designed for interactive data exploration and MATLAB compatibility.
  • Communication Flow: User commands flow from Pyplot down to the Artist tree, which compiles into drawing calls executed by the Backend Renderer.

📝 Examination Paragraph Blueprint: Matplotlib is engineered as a three-tiered layered architecture separating rendering hardware, graphical primitives, and user-facing commands. At the base resides the Backend Layer, composed of three essential classes: FigureCanvas (which encapsulates the native drawing area, such as a Qt/Tk widget or paper boundary), Renderer (which handles pixel rasterization or vector compilation according to output formats like PNG, PDF, or SVG), and Event (which translates OS keyboard and mouse interactions into GUI callbacks).

Above the backend lies the Artist Layer, which comprises all visual objects visible on the canvas. Artists exist in a strict hierarchical tree: the root Figure contains one or more Axes instances, each containing two or three Axis instances. Individual elements are classified as Primitives (e.g., Line2D, Rectangle, Polygon, Text) or Composites (e.g., Axis, Axes, Figure). Finally, the Scripting Layer (exposed via matplotlib.pyplot) wraps the Artist layer in a procedural state machine, automatically managing active figures and axes for rapid scientific plotting.

👨‍🏫 Teacher's Board Note: Exam paper मा सुरुमै Figure 6.1 को three-tier box diagram बनाउनुहोस्। Scripting layer ले user सँग MATLAB style मा सजिलो interface दिन्छ, Artist layer ले Figure, Axes र Line2D का objects व्यवस्थापन गर्छ, र Backend layer ले screen वा printer मा pixel/vector render गर्छ। यो architecture diagram देखाएमा ८ मा ८ मार्क्स secure हुन्छ।
Q2TU Model • Pyplot API vs Object-Oriented Paradigm (6 Marks)

Differentiate between the Pyplot stateful API and the Object-Oriented (OO) plotting paradigm in Matplotlib. Why is the OO approach preferred?

5-POINT QUICK-GRAB MEMORY ANCHORS:
  • State Tracking: Pyplot relies on an implicit global state machine tracking the current figure (`gcf()`) and axes (`gca()`); OO uses explicit variable handles (`fig`, `ax`).
  • Syntax Differences: Pyplot calls methods directly on `plt` (`plt.title()`, `plt.xlabel()`); OO invokes setter methods on the axes object (`ax.set_title()`, `ax.set_xlabel()`).
  • Subplot Scalability: Pyplot becomes error-prone with multi-panel dashboards; OO cleanly addresses each panel via array coordinates (`axes[0, 1].plot()`).
  • Concurrency & Embedding: The OO paradigm is thread-safe and can be embedded cleanly into web services and GUI toolkits (Tkinter, PyQt).
  • Maintainability: OO code is modular, self-contained, and avoids unexpected side-effects caused by hidden state switching.

📝 Examination Paragraph Blueprint: The primary distinction between the two interfaces lies in state management. The Pyplot API provides a MATLAB-style procedural interface that manages an implicit global state machine. Whenever a command like plt.plot() or plt.title() is invoked, Matplotlib automatically identifies or creates the "current" active figure and axes, applying changes globally. While convenient for rapid single-curve exploratory scripts, it introduces ambiguity in complex workflows where figures or subplots are modified out of linear order.

Conversely, the Object-Oriented API explicitly instantiates distinct Figure and Axes instances via fig, ax = plt.subplots(). Customization is applied directly through explicit method calls on the target object (e.g., ax.set_title(), ax.set_xlabel(), ax.grid()). The OO approach is vastly superior for production software, multi-panel analytical dashboards, and multi-threaded server environments because it eliminates hidden global state, allows direct random-access indexing of specific subplots, and integrates natively with GUI event loops.

👨‍🏫 Teacher's Board Note: दुईवटा approach को तुलना तालिका (Comparison Table) बनाउनुहोस्। विशेष रूपमा set_ prefix को भिन्नता खुलाउनुहोस्: Pyplot मा plt.title() हुन्छ भने OO मा ax.set_title() हुन्छ। fig, ax = plt.subplots() को छोटो कोड लेख्न नबिर्सिनुहोला।
Q3TU Model • subplots() vs subplot2grid() Dashboard Layouts (10 Marks)

Compare `plt.subplots()` with `plt.subplot2grid()`. Write a complete Python program to generate a 3x3 asymmetrical dashboard layout where the main chart spans two rows and all three columns.

5-POINT QUICK-GRAB MEMORY ANCHORS:
  • Grid Uniformity: `plt.subplots()` generates uniform, identical-sized grid cells; `subplot2grid()` supports asymmetrical cell spanning across rows and columns.
  • subplot2grid Signature: Takes `shape=(nrows, ncols)`, starting anchor `loc=(row, col)`, and expansion factors `rowspan` and `colspan`.
  • Executive Layouts: Allows dominant primary plots (hero charts) to occupy large areas while subordinate diagnostics occupy smaller surrounding cells.
  • Indexing Mechanism: `subplots()` returns an array of axes; `subplot2grid()` returns individual axes directly on each invocation.
  • Padding Prevention: Both approaches require `fig.tight_layout()` to calculate bounding padding and eliminate label overlaps.

📝 Examination Paragraph Blueprint: While plt.subplots(nrows, ncols) is ideal for generating uniform matrices of identical subplots, it cannot accommodate non-uniform dashboard designs where specific charts require greater visual emphasis. plt.subplot2grid() overcomes this limitation by overlaying an arbitrary virtual grid and allowing individual subplots to span across multiple contiguous rows and columns via rowspan and colspan parameters.

In the examination solution, establish a 3x3 virtual grid resolution: shape=(3, 3). Anchor the hero plot at coordinate (0, 0) with rowspan=2 and colspan=3, enabling it to dominate the top two-thirds of the canvas. The remaining row 2 is partitioned among three auxiliary plots anchored at (2, 0), (2, 1), and (2, 2) with rowspan=1 and colspan=1 each, producing a publication-grade executive dashboard.

👨‍🏫 Teacher's Board Note: यो १० नम्बरको प्रश्नमा Figure 6.4 जस्तै ३x३ को ग्रिड स्केच कोर्नुहोस् र Section 7 को subplot2grid((3, 3), (0, 0), rowspan=2, colspan=3) भएको Python code लेखिदिनुहोस्। tight_layout() किन आवश्यक छ खुलाउँदा full marks पाइन्छ।
Q4TU Model • Anatomy of a Box-and-Whisker Plot (8 Marks)

Explain the statistical anatomy of a Box-and-Whisker Plot. Define Median, Quartiles, Interquartile Range (IQR), Whisker boundaries, and Outlier detection mathematically.

5-POINT QUICK-GRAB MEMORY ANCHORS:
  • Five-Number Summary: Encapsulates Minimum, First Quartile ($Q_1$), Median ($Q_2$), Third Quartile ($Q_3$), and Maximum.
  • IQR Formula: $IQR = Q_3 - Q_1$, measuring the statistical spread of the central 50% of the dataset.
  • Inner Whisker Limits: Lower fence = $Q_1 - 1.5 \times IQR$; Upper fence = $Q_3 + 1.5 \times IQR$.
  • Outlier / Flier Rule: Any data observation lying beyond the $1.5 \times IQR$ fences is classified as an outlier and plotted as an individual marker.
  • Matplotlib Implementation: Executed using `ax.boxplot(data, patch_artist=True)`.

📝 Examination Paragraph Blueprint: The Box-and-Whisker plot is an exploratory data analysis tool designed to visualize the non-parametric distribution, skewness, and outlier presence of continuous numerical datasets without assuming underlying Gaussian normality. The central rectangular box demarcates the Interquartile Range ($IQR$), computed as $IQR = Q_3 - Q_1$, spanning the 25th percentile ($Q_1$) to the 75th percentile ($Q_3$) and capturing the central 50% of observation values. A solid line running through the box marks the second quartile or sample Median ($Q_2$).

Extending outward from the hinges are the Whiskers. Crucially, the whiskers do not necessarily extend to absolute dataset extrema; rather, they extend to the most extreme data points residing within $1.5 \times IQR$ from the respective quartiles (Lower Fence = $Q_1 - 1.5 \times IQR$, Upper Fence = $Q_3 + 1.5 \times IQR$). Any empirical data point lying outside these statistical fences is formally categorized as an Outlier (Flier) and rendered as an individual distinct point, enabling rapid quality diagnosis in machine learning pipelines.

👨‍🏫 Teacher's Board Note: कापीको बीचमा Figure 6.5 को बाकस चित्र कोर्नुहोस् र $Q_1$, $Q_2$ (Median), $Q_3$, $IQR = Q_3 - Q_1$, तथा $1.5 \times IQR$ को Whisker formula स्पष्टसँग लेख्नुहोस्। Outliers लाई बाहिर थोप्लो बनाएर देखाउँदा परीक्षक प्रभावित हुन्छन्।
Q5TU Model • Grouped vs Stacked Bar Charts (8 Marks)

Explain the implementation mechanics of Grouped Bar Charts and Stacked Bar Charts in Matplotlib with Python code examples.

5-POINT QUICK-GRAB MEMORY ANCHORS:
  • Grouped Bar Goal: Places multiple metric bars side-by-side per category for direct sub-category comparisons.
  • Grouped Coordinate Shift: Converts categories to numeric offsets via `x = np.arange(len(cats))` and shifts positions by `x - width/2` and `x + width/2`.
  • Stacked Bar Goal: Stacks bars vertically to illustrate cumulative totals alongside component breakdowns.
  • Stacked Mechanics: Utilizes the `bottom=baseline_series` parameter in subsequent `ax.bar()` invocations.
  • Tick Alignment: Requires resetting category labels via `ax.set_xticks(x)` and `ax.set_xticklabels(categories)`.

📝 Examination Paragraph Blueprint: In categorical analysis, comparing multi-dimensional attributes requires either horizontal segregation or vertical aggregation. A Grouped Bar Chart renders sub-metrics side-by-side within each categorical division. Because Matplotlib's ax.bar() will overlap bars plotted at identical coordinates, the programmer must convert categorical strings into numeric indices using np.arange(len(categories)), defining a fixed bar width (e.g., width = 0.35), and offsetting bar locations mathematically via x - width/2 and x + width/2.

In contrast, a Stacked Bar Chart displays part-to-whole relationships by layering sub-category bars vertically. The initial series is plotted normally, while subsequent series supply the preceding dataset to the bottom parameter (e.g., ax.bar(categories, series2, bottom=series1)). This ensures the second bar anchors directly atop the apex of the first, preserving total cumulative height while visualizing constituent sub-component shares.

👨‍🏫 Teacher's Board Note: Grouped bar chart मा बारहरू नखप्टिउन भनेर x - width/2x + width/2 गरिएको गणितीय offset र Stacked bar chart मा bottom=series1 प्रयोग भएको code snippet लेखेर देखाउनुहोस्।
Q6TU Model • Scatter Plots & Multivariate Mapping (6 Marks)

How does Matplotlib enable 4-dimensional data visualization on a 2D Scatter Plot? Explain the roles of size, color, and colormaps.

5-POINT QUICK-GRAB MEMORY ANCHORS:
  • Spatial Dimensions (X & Y): Position along horizontal and vertical Cartesian coordinates encodes two primary continuous metrics.
  • Size Dimension (`s`): Point area scales proportional to a third numeric variable (e.g., Population or Budget).
  • Color Dimension (`c`): Point color encodes a fourth variable through a continuous gradient spectrum.
  • Colormap (`cmap`): Perceptually uniform color lookup tables (e.g., `viridis`, `plasma`) prevent optical distortion.
  • Colorbar Reference: `fig.colorbar(scatter_obj)` provides the critical quantitative legend for interpreting color values.

📝 Examination Paragraph Blueprint: Standard Cartesian plots are fundamentally constrained to two spatial dimensions (X and Y). Matplotlib expands this visual bandwidth through ax.scatter() by mapping additional data columns to the geometric properties of the plotted marker glyphs. Dimensions 1 and 2 are encoded positionally along the Cartesian X and Y axes, reflecting bivariate relationships such as Study Hours versus GPA.

Dimension 3 is encoded via the s (size) parameter, scaling the circular marker radius proportionally to a third continuous metric (e.g., Lab Project Score). Dimension 4 is mapped via the c (color) parameter, which translates a fourth variable (e.g., Attendance Rate) through a normalized colormap such as cmap='viridis'. To ensure scientific interpretability, fig.colorbar(scatter) must be instantiated to provide an objective scale legend for decoding color values.

👨‍🏫 Teacher's Board Note: एउटै थोप्लोमा ४ वटा data attributes कसरी अटाउँछन् (X, Y, Size s, Color c) भन्ने बुँदागत व्याख्या गर्नुहोस् र fig.colorbar(scatter) को महत्त्व खुलाउनुहोस्।
Q7TU Model • Dual Y-Axes with twinx() (8 Marks)

When and why is `ax.twinx()` used in scientific visualization? Provide a complete code example comparing two variables of differing magnitude.

5-POINT QUICK-GRAB MEMORY ANCHORS:
  • Divergent Scales Problem: When two series share an X domain but differ in magnitude (e.g., 0-30 °C vs 0-500 mm rain), plotting on one axis squashes the smaller series.
  • twinx Mechanism: Creates an overlay Axes that shares the existing X-axis while erecting an independent secondary Y-axis on the right.
  • Independent Spines: The primary axis (`ax1`) manages the left spine; the twin axis (`ax2`) manages the right spine.
  • Color-Coding Best Practice: Y-axis labels and tick marks should match the color of their respective plotted curves to prevent viewer confusion.
  • Layout Safety: Requires `fig.tight_layout()` to accommodate tick labels on both opposing spines.

📝 Examination Paragraph Blueprint: In scientific reporting, investigators frequently correlate two dependent variables against a shared independent domain (e.g., monthly progression), but whose physical units and numeric ranges differ by orders of magnitude. For example, plotting Temperature (ranging from 10 to 30 °C) alongside Rainfall (ranging from 50 to 500 mm) on a single scale compresses the temperature curve into an imperceptible flat line along the X-axis baseline.

Matplotlib resolves this scaling dilemma via ax2 = ax1.twinx(). This constructor instantiates a secondary Axes object perfectly overlaying the original, inheriting the shared horizontal X-axis while constructing an independent vertical scale on the right spine. In the implementation, investigators plot the temperature curve on ax1 (setting left spine labels in red) and precipitation bars on ax2 (setting right spine labels in blue). Matching curve colors to their respective axis labels is mandatory for visual clarity.

👨‍🏫 Teacher's Board Note: Figure 6.3 को रेखाचित्र कोरेर ax2 = ax1.twinx() को भूमिका सम्झाउनुहोस्। एउटै महिना (Months) मा तापक्रम (३० सम्म) र वर्षा (५०० सम्म) देखाउन दायाँतर्फ नयाँ Y-axis कसरी निर्माण हुन्छ, त्यो प्रस्ट्याउनुहोस्।
Q8TU Model • Histogram vs Bar Chart Differences (5 Marks)

Differentiate between a Histogram and a Bar Chart in terms of data type, visual spacing, and statistical interpretation.

5-POINT QUICK-GRAB MEMORY ANCHORS:
  • Data Nature: Bar charts plot discrete categorical entities; Histograms plot continuous quantitative distributions.
  • Bar Spacing: Bar charts feature deliberate gaps between bars; Histograms have contiguous, touching bars reflecting numeric continuity.
  • X-Axis Representation: Bar chart X-axis represents qualitative labels; Histogram X-axis represents continuous numerical bin intervals.
  • Bar Width Significance: In Bar charts, bar width is arbitrary styling; in Histograms, bar width represents quantitative interval range ($\Delta x$).
  • Area Interpretation: In normalized histograms (`density=True`), total integrated area under all bars equals 1.0 (Probability Density).

📝 Examination Paragraph Blueprint: Although superficially similar in appearance, Histograms and Bar charts serve fundamentally different statistical objectives. A Bar Chart evaluates categorical, discrete, or qualitative data (e.g., Department names, Blood types, Countries). Because categories are inherently discrete entities with no quantitative continuum between them, bars are drawn with deliberate whitespace intervals separating them, and bar widths carry zero mathematical significance.

Conversely, a Histogram models continuous, quantitative distributions (e.g., Student Exam Marks, Sensor Voltages, Server Latencies). The continuous variable is segmented into consecutive mathematical intervals called bins. The bars are drawn touching without gaps to symbolize mathematical continuity. Furthermore, while bar chart heights represent discrete item tallies, histogram bar areas represent frequency volume, and when normalized via density=True, the total integrated area equals 1.0, modeling a valid continuous Probability Density Function.

👨‍🏫 Teacher's Board Note: तुलना तालिका बनाएर Data Type (Discrete vs Continuous), Spacing (Gaps vs Contiguous), र Area (Arbitrary vs Probability Density) तीनवटा मुख्य बुँदाहरू प्रस्ट्याउनुहोस्।
Q9TU Model • Pie Chart Customization & Pitfalls (5 Marks)

Explain the key parameters of `ax.pie()`: explode, autopct, and startangle. Why do modern data scientists discourage excessive reliance on pie charts?

5-POINT QUICK-GRAB MEMORY ANCHORS:
  • explode Parameter: Fractional offset tuple detaching specific wedges from the center for visual emphasis.
  • autopct Parameter: Formatting string (e.g., `'%1.1f%%'`) computing and rendering percentage labels automatically.
  • startangle Parameter: Degrees counter-clockwise from horizontal X-axis to orient the first wedge (commonly 90° or 140°).
  • Human Perceptual Flaw: Human cognition evaluates linear lengths (Bar charts) far more accurately than angles, wedge curves, or 2D areas.
  • Best Practice Alternative: Use Bar or Donut charts when categories exceed 5 or slices share similar percentage shares.

📝 Examination Paragraph Blueprint: In Matplotlib, ax.pie() constructs proportional part-of-a-whole visualizations. Three primary parameters govern its appearance: explode accepts a tuple of float values specifying the fractional radial distance each slice is offset from the center pie apex, effectively emphasizing outlier categories like Distinction grades. The autopct parameter accepts a Python string format specifier (such as '%1.1f%%') to calculate and imprint numerical percentage values inside each wedge. The startangle parameter rotates the starting edge counter-clockwise from the X-axis for visual balance.

Despite their ubiquity, modern data science literature heavily discourages pie charts. Cognitive psychology demonstrates that the human visual system struggles to accurately compare angles and curved surface areas compared to aligned linear bar lengths. When categories exceed five or percentages are closely balanced (e.g., 24% vs 26%), distinguishing relative rank becomes nearly impossible without reading the numeric text, rendering the graphic redundant. Horizontal bar charts are consistently preferred for objective visual comparison.

👨‍🏫 Teacher's Board Note: explode, autopct, र startangle का कामहरू लेख्नुहोस्। साथै "मानव आँखाले कोण (Angle) भन्दा लम्बाइ (Length) धेरै सही नाप्न सक्छ, त्यसैले Bar Chart लाई Pie Chart भन्दा बढी वैज्ञानिक मानिन्छ" भन्ने analytical point परीक्षामा लेख्दा राम्रो प्रभाव पर्छ।
Q10TU Model • Figure Exporting & Production Memory Management (6 Marks)

Discuss the role of `fig.savefig()` with attention to DPI, bounding boxes, and vector vs raster formats. Why is `plt.close()` critical in production batch scripts?

5-POINT QUICK-GRAB MEMORY ANCHORS:
  • DPI (Dots Per Inch): Controls output resolution; standard screen is 72-100 DPI, while scientific publication requires 300+ DPI.
  • bbox_inches='tight': Automatically calculates and crops unnecessary white canvas margins, preventing clipped axis labels.
  • Vector vs Raster: Raster (PNG, JPG) stores fixed pixels (degrades upon zooming); Vector (PDF, SVG) stores mathematical primitives (infinitely scalable).
  • Memory Retention Mechanism: Matplotlib maintains global internal references to every created Figure until explicitly cleared.
  • plt.close(fig) Imperative: Failure to call `plt.close(fig)` in batch loops leads to cumulative RAM exhaustion (Memory Leaks).

📝 Examination Paragraph Blueprint: In automated data pipelines and production reporting, graphical output is persisted via fig.savefig() rather than interactive GUI windows. The function provides crucial arguments: dpi=300 establishes resolution at 300 dots per inch, fulfilling print quality standards. Specifying bbox_inches='tight' instructs the rendering engine to compute the exact bounding box of all Artists, trimming excess whitespace padding and preventing external axis labels from being clipped in the file. Format selection is governed by output requirements: raster formats (PNG, JPG) encode pixel matrices, while vector formats (PDF, SVG) preserve mathematical geometries, ensuring infinite zooming scalability without pixelation.

A critical architectural pitfall in server automation is memory management. Because Matplotlib maintains global dictionary references to all created Figure objects to facilitate stateful commands, garbage collection cannot automatically reclaim figure memory even when variables fall out of local scope. In automated loops generating hundreds of analytical reports, this persistent accumulation causes severe memory leaks, resulting in OS kernel termination. Explicitly invoking plt.close(fig) de-registers the figure from the GUI engine and immediately frees the underlying memory buffer.

👨‍🏫 Teacher's Board Note: dpi=300 ले high-resolution प्रिन्ट दिन्छ, bbox_inches='tight' ले बाहिरको अनावश्यक सेतो भाग काट्छ, र लूपभित्र plt.close(fig) नलेखे Memory Leak भएर सर्भर क्र्यास हुन्छ भन्ने व्यवहारिक इन्जिनियरिङ तथ्य खुलाएर उत्तर लेख्नुहोला।