Back to List
Calculating...
UNIT 1 : CH 3
Dec 14, 2025
π Plotting with PyPlot
Have you ever wondered how news apps show **bar charts** of election results, or how weather apps show **line graphs** of temperature? All of that is **Data Visualization** β and in Python, we do it with **Matplotlib's PyPlot**! Let's make data beautiful! π¨π
> [!TIP]
> **How to use these notes:** Run every code example in Python to actually SEE the charts! Board Exam Tips appear throughout. For IP students, the most tested topics are **Line Chart**, **Bar Chart**, **Pie Chart**, **Histogram**, and **DataFrame plotting**. Focus on the code and the customization parameters! π―
---
## 3.1 π What is Data Visualization?
**Data Visualization** means presenting data in a **visual format** (charts, graphs, maps) so that our brain can understand patterns and insights quickly.
```mermaid
graph LR
RAW["π Raw Data\n90, 85, 78, 92, 65\nJust numbers..."]
VIZ["π Visualization\nBar Chart / Line Graph\nInstant understanding!"]
INS["π‘ Insights\nWho scored highest?\nWhat's the trend?\nWhere to improve?"]
RAW --> VIZ --> INS
style VIZ fill:#FF9800,color:#fff
style INS fill:#4CAF50,color:#fff
```
**Why do we need Data Visualization?**
::: grid
::: card π§ | Faster Understanding | Brain processes visuals 60,000x faster than text | A chart of sales is faster than a table of numbers
::: card π | Spot Trends | Easily see if marks are going up or down | Line chart shows improvement over time
::: card π | Find Patterns | Detect seasonal trends, outliers, correlations | Sales always drop in June? Bar chart shows it!
::: card πΌ | Better Decisions | Managers make decisions from dashboards, not Excel sheets | Every app, dashboard, report uses charts
:::
> **Analogy:** Imagine reading 100 students' marks in a table vs. looking at a bar chart β with the chart, you instantly see who topped, who failed, and the overall pattern. That's the magic of data visualization!
---
## 3.2 π Using Pyplot of Matplotlib Library
**Matplotlib** is the main Python library for creating charts. **Pyplot** is the module inside Matplotlib that we use β it provides simple functions to draw plots.
```mermaid
graph TD
MLIB["π¦ Matplotlib Library\n(The whole package)"]
PLOT["π pyplot Module\n(What we actually use)"]
PLT["plt alias\n(Short name for pyplot)"]
MLIB --> PLOT --> PLT
style MLIB fill:#9C27B0,color:#fff
style PLOT fill:#2196F3,color:#fff
style PLT fill:#4CAF50,color:#fff
```
---
### 3.2.1 Installing and Importing Matplotlib π§
**Step 1 β Install (done once in terminal):**
```
pip install matplotlib
```
**Step 2 β Import in your Python file:**
```python
# standard_import.py
import matplotlib.pyplot as plt # plt is the universal alias β always use this!
```
> [!IMPORTANT]
> **Board Exam Tip**
> "Write the command to import Matplotlib's pyplot module." β **1-mark** question every year!
> Answer: `import matplotlib.pyplot as plt`
---
### 3.2.2 Working with PyPlot Methods π οΈ
Every chart follows the same 5-step structure:
```python
# step_structure.py
import matplotlib.pyplot as plt
# Step 1: Define your data
x = [1, 2, 3, 4, 5]
y = [10, 25, 15, 30, 20]
# Step 2: Create the chart
plt.plot(x, y)
# Step 3: Add labels and title
plt.title("My First Chart")
plt.xlabel("X Axis")
plt.ylabel("Y Axis")
# Step 4: Save (BEFORE show!)
plt.savefig("my_chart.png")
# Step 5: Display
plt.show()
```
**The Golden Rule of PyPlot:**
```
Define Data β Plot β Customize β Save β Show
```
> [!WARNING]
> **ALWAYS save BEFORE show()!**
> `plt.show()` clears the chart from memory after displaying it. If you call `savefig()` AFTER `show()`, you'll save a **blank empty image**. Always: `savefig()` first, then `show()`!
---
## 3.3 π Creating Line Charts and Scatter Charts
### 3.3.1 Line Chart using `plot()` Function
A **Line Chart** connects data points with a line β best for showing **trends over time**.
> **Real Example:** Tracking your monthly mobile data usage, temperature across days, or company revenue over years.
```python
# basic_line_chart.py
import matplotlib.pyplot as plt
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
sales = [5000, 7000, 6500, 8000, 7500, 9000]
plt.plot(months, sales) # Basic line chart
plt.title("Monthly Sales 2024")
plt.xlabel("Month")
plt.ylabel("Sales (βΉ)")
plt.show()
```
**With only Y values (X is auto-generated as 0, 1, 2...):**
```python
# auto_x_values.py
import matplotlib.pyplot as plt
marks = [85, 90, 78, 92, 88]
plt.plot(marks) # X = 0, 1, 2, 3, 4 automatically
plt.title("Student Marks")
plt.show()
```
---
### 3.3.2 Specifying Plot Size and Grid π
```python
# plot_size_grid.py
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [10, 25, 15, 35, 28]
# Set figure size (width, height) in inches:
plt.figure(figsize=(10, 5)) # 10 inches wide, 5 inches tall
plt.plot(x, y)
# Add grid lines to make values easier to read:
plt.grid(True) # Add grid
plt.grid(color='gray', linestyle='--', linewidth=0.5) # Custom grid style
plt.title("Sales Trend")
plt.show()
```
| Parameter | What it does |
| :--- | :--- |
| `figsize=(w, h)` | Width and height of chart in inches |
| `plt.grid(True)` | Shows grid lines |
| `plt.grid(color=, linestyle=)` | Customizes grid appearance |
---
### 3.3.3 Applying Various Settings in `plot()` Function π¨
The `plot()` function has many parameters to style your line:
```python
# styled_line_chart.py
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [10, 25, 15, 35, 28]
plt.figure(figsize=(8, 5))
plt.plot(x, y,
color='red', # Line color
linestyle='--', # Dashed line
linewidth=2, # Line thickness
marker='o', # Circle marker at each point
markersize=8, # Marker size
markerfacecolor='blue', # Marker fill color
label='Sales Data' # Label for legend
)
plt.title("Styled Line Chart")
plt.xlabel("Month")
plt.ylabel("Sales")
plt.legend() # Shows the label
plt.grid(True)
plt.show()
```
**Common `plot()` Parameters β Quick Reference:**
| Parameter | Options | Example |
| :--- | :--- | :--- |
| `color` | `'red'`, `'blue'`, `'r'`, `'b'`, `'#FF5733'` | `color='red'` |
| `linestyle` | `'-'` (solid), `'--'` (dashed), `':'` (dotted), `'-.'` (dash-dot) | `linestyle='--'` |
| `linewidth` | Any number | `linewidth=2` |
| `marker` | `'o'` (circle), `'*'` (star), `'s'` (square), `'^'` (triangle), `'+'` | `marker='o'` |
| `markersize` | Any number | `markersize=8` |
| `label` | Any text string | `label='Sales'` |
**Color shortcuts:**
::: grid
::: card π΄ | 'r' | Red | color='r'
::: card π΅ | 'b' | Blue | color='b'
::: card π’ | 'g' | Green | color='g'
::: card π‘ | 'y' | Yellow | color='y'
::: card β« | 'k' | Black | color='k'
::: card π | 'm' | Magenta | color='m'
:::
**Multiple lines on same chart:**
```python
# multiple_lines.py
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
maths = [85, 90, 78, 92, 88]
science = [88, 75, 82, 79, 91]
english = [70, 80, 75, 85, 78]
plt.figure(figsize=(9, 5))
plt.plot(x, maths, color='blue', marker='o', label='Maths', linestyle='-')
plt.plot(x, science, color='red', marker='s', label='Science', linestyle='--')
plt.plot(x, english, color='green', marker='^', label='English', linestyle=':')
plt.title("Subject-wise Marks Trend")
plt.xlabel("Test Number")
plt.ylabel("Marks")
plt.legend()
plt.grid(True)
plt.show()
```
> [!IMPORTANT]
> **Board Exam Tip**
> "Write code to draw a line chart of monthly sales with red dashed line, circle markers, and a title." β **3-mark** question!
> Use: `color='r'`, `linestyle='--'`, `marker='o'`
---
### 3.3.4 Creating Scatter Charts π
A **Scatter Chart** shows individual data points WITHOUT connecting them with lines β used to see the **relationship (correlation)** between two variables.
> **Real Example:** Does studying more hours lead to higher marks? Plot hours on X, marks on Y β if points go up-right, there IS a correlation!
```python
# scatter_chart.py
import matplotlib.pyplot as plt
study_hours = [2, 3, 4, 5, 6, 7, 8, 9, 10]
marks = [45, 55, 60, 70, 72, 80, 85, 88, 95]
plt.figure(figsize=(8, 5))
plt.scatter(study_hours, marks,
color='purple', # Point color
marker='o', # Point shape
s=100, # Point size (s not markersize!)
label='Students',
edgecolors='black' # Border color of markers
)
plt.title("Study Hours vs Marks")
plt.xlabel("Study Hours per Day")
plt.ylabel("Marks Obtained")
plt.legend()
plt.grid(True)
plt.show()
```
**Line Chart vs Scatter Chart β Key Differences:**
| Feature | Line Chart | Scatter Chart |
| :--- | :--- | :--- |
| **Function** | `plt.plot()` | `plt.scatter()` |
| **Connection** | Points connected by lines | Individual standalone points |
| **Best for** | Trends over time | Relationship between two variables |
| **Example** | Monthly temperature | Study hours vs marks |
| **Size param** | `markersize=` | `s=` (capital S) |
---
## 3.4 π Creating Bar Charts and Pie Charts
### Bar Charts β The "Comparison King" π
A **Bar Chart** compares values across **categories**. Each bar's height represents a value.
```python
# basic_bar_chart.py
import matplotlib.pyplot as plt
subjects = ['Maths', 'Science', 'English', 'Hindi', 'IP']
marks = [92, 88, 75, 80, 95]
plt.figure(figsize=(8, 5))
plt.bar(subjects, marks)
plt.title("Subject-wise Marks")
plt.xlabel("Subjects")
plt.ylabel("Marks")
plt.show()
```
---
### 3.4.1 Changing Widths of the Bars π
The default bar width is `0.8`. You can make bars thinner or wider:
```python
# bar_width_demo.py
import matplotlib.pyplot as plt
subjects = ['Maths', 'Science', 'English']
marks = [92, 88, 75]
fig, axes = plt.subplots(1, 3, figsize=(12, 4))
axes[0].bar(subjects, marks, width=0.3) # Thin bars
axes[0].set_title("Width = 0.3 (Thin)")
axes[1].bar(subjects, marks, width=0.6) # Default-ish
axes[1].set_title("Width = 0.6 (Normal)")
axes[2].bar(subjects, marks, width=0.9) # Wide bars
axes[2].set_title("Width = 0.9 (Wide)")
plt.tight_layout()
plt.show()
```
> `width=` accepts values between 0 and 1. Default is 0.8. Smaller = thinner bars with more gap.
---
### 3.4.2 Changing Colors of the Bars π¨
```python
# bar_colors_demo.py
import matplotlib.pyplot as plt
subjects = ['Maths', 'Science', 'English', 'Hindi', 'IP']
marks = [92, 88, 75, 80, 95]
# Single color for all bars:
plt.figure(figsize=(8, 4))
plt.bar(subjects, marks, color='coral')
plt.title("Single Color")
plt.show()
# Different color for each bar (list of colors):
plt.figure(figsize=(8, 4))
colors = ['red', 'blue', 'green', 'orange', 'purple']
plt.bar(subjects, marks, color=colors, edgecolor='black')
plt.title("Multiple Colors")
plt.show()
```
**Popular colors for bar charts:**
```python
# Using hex codes for nicer colors:
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7']
plt.bar(subjects, marks, color=colors, edgecolor='black', linewidth=0.5)
```
---
### 3.4.3 Creating Multiple (Grouped) Bars Chart ππ
When comparing two groups (like Section A vs Section B marks), you need side-by-side bars:
```python
# multiple_bars_chart.py
import matplotlib.pyplot as plt
import numpy as np
subjects = ['Maths', 'Science', 'English']
section_a = [90, 85, 78]
section_b = [82, 92, 74]
# Key trick: shift bar positions manually using numpy
bar_width = 0.35 # Width of each bar
x = np.arange(len(subjects)) # [0, 1, 2] β base positions
plt.figure(figsize=(8, 5))
# Place Section A bars at x positions
plt.bar(x - bar_width/2, section_a,
width=bar_width,
label='Section A',
color='steelblue',
edgecolor='black')
# Place Section B bars SHIFTED RIGHT by bar_width
plt.bar(x + bar_width/2, section_b,
width=bar_width,
label='Section B',
color='coral',
edgecolor='black')
plt.title("Section A vs Section B β Subject Comparison")
plt.xlabel("Subjects")
plt.ylabel("Marks")
plt.xticks(x, subjects) # Replace 0,1,2 with subject names
plt.legend()
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.show()
```
> [!IMPORTANT]
> **Board Exam Tip**
> "Write code to create a multiple bar chart comparing marks of two sections." β **4-mark** question!
> Key points: Use `numpy.arange()`, shift one set by `bar_width/2`, use `xticks()` to set category names.
---
### 3.4.4 Creating a Horizontal Bar Chart πβοΈ
Sometimes category names are long β a horizontal bar chart is easier to read:
```python
# horizontal_bar.py
import matplotlib.pyplot as plt
countries = ['India', 'China', 'USA', 'Indonesia', 'Pakistan']
population = [144, 141, 33, 28, 23] # in crores (approx)
plt.figure(figsize=(8, 5))
plt.barh(countries, population, # barh = horizontal bar
color=['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7'],
edgecolor='black')
plt.title("Population by Country (Crores)")
plt.xlabel("Population (Crores)")
plt.ylabel("Country")
plt.grid(axis='x', linestyle='--', alpha=0.7)
plt.show()
```
> `plt.bar()` β **Vertical** bars (height = value)
> `plt.barh()` β **Horizontal** bars (width = value)
> Notice: arguments swap β first argument is **Y** (categories), second is **width**!
---
### 3.4.5 Creating Pie Charts π₯§
A **Pie Chart** shows what percentage each category is of the whole. Best when you have 3β6 categories.
```python
# basic_pie_chart.py
import matplotlib.pyplot as plt
subjects = ['Maths', 'Science', 'English', 'Hindi', 'IP']
marks = [92, 88, 75, 80, 95]
plt.figure(figsize=(7, 7))
plt.pie(marks,
labels=subjects, # Category names
autopct='%1.1f%%', # Show percentage (1 decimal place)
startangle=90 # Start from top (12 o'clock)
)
plt.title("Marks Distribution by Subject")
plt.show()
```
**Advanced Pie Chart with Explosion and Shadow:**
```python
# advanced_pie.py
import matplotlib.pyplot as plt
categories = ['Food', 'Transport', 'Entertainment', 'Savings', 'Others']
amounts = [35, 20, 15, 20, 10]
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7']
explode = (0.1, 0, 0, 0, 0) # Pull out FIRST slice (Food) by 10%
plt.figure(figsize=(8, 8))
plt.pie(amounts,
labels=categories,
colors=colors,
autopct='%1.1f%%', # Show % on each slice
startangle=140, # Starting angle
explode=explode, # Pull out first slice
shadow=True # Add shadow for 3D look
)
plt.title("Monthly Expense Breakdown", fontsize=16)
plt.show()
```
**Pie Chart Parameters β Quick Reference:**
| Parameter | Purpose | Example |
| :--- | :--- | :--- |
| `labels` | Category names | `labels=['A', 'B', 'C']` |
| `autopct` | Show % on slices | `autopct='%1.1f%%'` |
| `startangle` | Rotation start angle | `startangle=90` |
| `explode` | Pull out a slice | `explode=(0.1, 0, 0)` |
| `shadow` | Add 3D shadow | `shadow=True` |
| `colors` | Slice colors | `colors=['red', 'blue']` |
> [!IMPORTANT]
> **Board Exam Tip**
> "Write code to create a pie chart showing expenses with percentage labels." β **3-mark** question!
> Key: `plt.pie(values, labels=names, autopct='%1.1f%%')`
> The `autopct='%1.1f%%'` parameter is what shows the percentages on the chart!
---
## 3.5 βοΈ Customizing the Plot
### 3.5.1 Anatomy of a Chart ποΈ
Every Matplotlib chart has these parts:
```
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β TITLE β
β β
β Y β * * β
β A β * * * β
β X β Chart Area (Axes) * β
β I β β
β S β β
β ββββββββββββββββββββββββββββββββββββββββββ β
β X AXIS β
β LEGEND: ββ Series1 -- Series2 β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
```
| Part | What it is | How to create |
| :--- | :--- | :--- |
| **Figure** | The entire canvas/window | `plt.figure(figsize=...)` |
| **Axes** | The plot area inside the figure | Created automatically |
| **Title** | Heading of the chart | `plt.title()` |
| **X-Axis Label** | Label below X-axis | `plt.xlabel()` |
| **Y-Axis Label** | Label beside Y-axis | `plt.ylabel()` |
| **Ticks** | Marks on the axis | `plt.xticks()`, `plt.yticks()` |
| **Grid** | Background lines | `plt.grid(True)` |
| **Legend** | Key for multiple lines/bars | `plt.legend()` |
---
### 3.5.2 Adding a Title π
```python
# title_demo.py
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [10, 20, 15, 30, 25]
plt.plot(x, y)
# Simple title:
plt.title("Sales Data")
# Styled title:
plt.title("Sales Data 2024",
fontsize=16, # Font size
fontweight='bold', # Bold text
color='darkblue', # Title color
pad=20 # Space between title and chart
)
plt.show()
```
---
### 3.5.3 Setting X and Y Labels, Limits and Ticks π’
```python
# labels_limits_ticks.py
import matplotlib.pyplot as plt
months = [1, 2, 3, 4, 5, 6]
sales = [5000, 7000, 6500, 8000, 7500, 9000]
plt.figure(figsize=(9, 5))
plt.plot(months, sales, color='steelblue', marker='o')
# Axis Labels:
plt.xlabel("Month Number", fontsize=12)
plt.ylabel("Sales in βΉ", fontsize=12)
# Axis Limits (set the visible range):
plt.xlim(0, 7) # X-axis from 0 to 7
plt.ylim(4000, 10000) # Y-axis from 4000 to 10000
# Ticks β customize the marks on the axes:
plt.xticks([1,2,3,4,5,6],
['Jan','Feb','Mar','Apr','May','Jun'],
rotation=45) # Rotate tick labels
plt.yticks([4000, 5000, 6000, 7000, 8000, 9000, 10000])
plt.title("Monthly Sales")
plt.grid(True)
plt.tight_layout() # Fixes overlapping labels
plt.show()
```
**Summary of customization functions:**
| Function | Purpose |
| :--- | :--- |
| `plt.xlabel("text")` | Label for X-axis |
| `plt.ylabel("text")` | Label for Y-axis |
| `plt.xlim(min, max)` | Set X-axis range |
| `plt.ylim(min, max)` | Set Y-axis range |
| `plt.xticks(positions, labels)` | Set tick marks and labels on X-axis |
| `plt.yticks(positions, labels)` | Set tick marks and labels on Y-axis |
---
### 3.5.4 Adding Legends πΊοΈ
A **Legend** is a key that explains what each line/bar in the chart represents. Essential when you have multiple datasets!
```python
# legend_demo.py
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
maths = [85, 90, 78, 92, 88]
science = [80, 75, 88, 82, 91]
plt.figure(figsize=(8, 5))
# MUST add label= parameter to each plot for legend to work:
plt.plot(x, maths, label='Maths', color='blue', marker='o')
plt.plot(x, science, label='Science', color='red', marker='s')
# Simple legend:
plt.legend()
# Positioned legend:
plt.legend(loc='upper left') # Options: upper/lower + left/center/right
# Custom styled legend:
plt.legend(loc='best', # 'best' auto-picks best position
fontsize=10,
title='Subjects',
framealpha=0.8) # Legend box transparency
plt.title("Subject Marks Comparison")
plt.xlabel("Test Number")
plt.ylabel("Marks")
plt.show()
```
**Legend `loc` options:**
| Value | Position |
| :--- | :--- |
| `'upper right'` | Top-right (default) |
| `'upper left'` | Top-left |
| `'lower right'` | Bottom-right |
| `'lower left'` | Bottom-left |
| `'center'` | Center |
| `'best'` | Auto-picks least crowded spot |
> [!IMPORTANT]
> **Board Exam Tip**
> "What is the purpose of legend? How do you add it?" β **2-mark** question!
> Answer: A legend identifies what different colours/lines represent. Steps: (1) Add `label='name'` inside each `plt.plot()`. (2) Call `plt.legend()` to display it.
---
### 3.5.5 Saving a Figure πΎ
```python
# save_figure.py
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [10, 25, 15, 30, 20]
plt.plot(x, y, color='blue')
plt.title("My Chart")
# SAVE FIRST, then show!
plt.savefig("my_chart.png") # Save as PNG
plt.savefig("my_chart.pdf") # Save as PDF
plt.savefig("my_chart.jpg", dpi=300) # High resolution JPEG
plt.savefig("my_chart.svg") # Scalable Vector Graphics
plt.show() # Always AFTER savefig!
```
**savefig() parameters:**
| Parameter | Purpose | Example |
| :--- | :--- | :--- |
| `dpi` | Resolution (dots per inch) | `dpi=300` (high quality) |
| `bbox_inches` | Trim whitespace | `bbox_inches='tight'` |
| `facecolor` | Background color | `facecolor='white'` |
> [!WARNING]
> **The Blank Image Trap! π¨**
> If you call `plt.savefig()` AFTER `plt.show()` β you'll save a **completely blank white image**!
> `plt.show()` clears the figure from memory after displaying it.
> **ALWAYS: savefig() FIRST β show() SECOND!**
---
## 3.6 π Creating Histograms with PyPlot
A **Histogram** shows how frequently values fall into different ranges (called **bins**). It's used for **continuous numerical data**.
> **Analogy:** Divide 100 students' marks into groups: 0-20, 20-40, 40-60, 60-80, 80-100. Count how many fall in each group. That count-per-range is a histogram!
**Key Difference from Bar Chart:**
```
Bar Chart: Discrete categories (Subjects, Cities) β Gaps between bars
Histogram: Continuous ranges (Marks, Heights) β No gaps between bars
```
```python
# histogram_demo.py
import matplotlib.pyplot as plt
marks = [12, 23, 34, 45, 45, 56, 67, 67, 67, 78,
78, 78, 89, 89, 90, 92, 94, 96, 98, 100]
plt.figure(figsize=(9, 5))
plt.hist(marks,
bins=5, # Divide data into 5 ranges
color='steelblue',
edgecolor='black', # Black border between bars
linewidth=0.5
)
plt.title("Distribution of Student Marks")
plt.xlabel("Marks Range")
plt.ylabel("Number of Students")
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.show()
```
**Understanding `bins`:**
```python
# bins=5 means 5 groups:
# Bin 1: 12β31 (few students)
# Bin 2: 31β51 (some students)
# Bin 3: 51β71 (more students)
# Bin 4: 71β90 (most students)
# Bin 5: 90β100 (many students)
```
**Custom bin edges:**
```python
plt.hist(marks,
bins=[0, 20, 40, 60, 80, 100], # Define exact bin edges
color='coral',
edgecolor='black')
```
**Histogram with density (frequency as %):**
```python
plt.hist(marks,
bins=10,
density=True, # Show as proportion (0 to 1)
color='lightgreen',
edgecolor='black')
plt.ylabel("Frequency Density")
```
> [!IMPORTANT]
> **Board Exam Tip**
> "What is the difference between a Bar Chart and a Histogram?" β **2-mark** question, very common!
> **Bar Chart:** Discrete categories, bars have gaps, order can be changed.
> **Histogram:** Continuous data grouped into bins (ranges), bars touch (no gaps), order is fixed.
---
## 3.7 π Creating Frequency Polygons
A **Frequency Polygon** is a line graph drawn by connecting the **midpoints** of each bar in a histogram. It shows the shape of the data distribution.
> **Think of it as:** Drawing a line chart ON TOP of a histogram, but connecting the middle-top points of each bar.
```python
# frequency_polygon.py
import matplotlib.pyplot as plt
import numpy as np
marks = [12, 23, 34, 45, 45, 56, 67, 67, 67, 78,
78, 78, 89, 89, 90, 92, 94, 96, 98, 100]
plt.figure(figsize=(10, 6))
# Step 1: Create histogram and get frequency counts:
counts, bin_edges, patches = plt.hist(marks,
bins=5,
color='lightblue',
edgecolor='black',
alpha=0.6, # Semi-transparent
label='Histogram')
# Step 2: Calculate midpoints of each bin:
bin_midpoints = (bin_edges[:-1] + bin_edges[1:]) / 2
# Step 3: Draw frequency polygon (line connecting midpoints):
plt.plot(bin_midpoints, counts,
color='red',
marker='o',
linewidth=2,
markersize=6,
label='Frequency Polygon')
plt.title("Marks Distribution β Histogram + Frequency Polygon")
plt.xlabel("Marks")
plt.ylabel("Frequency (No. of Students)")
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
```
**Step-by-step explanation:**
```
Bin 1: 12β31 β midpoint = 21.5 β count = 2
Bin 2: 31β51 β midpoint = 41 β count = 3
Bin 3: 51β71 β midpoint = 61 β count = 4
Bin 4: 71β90 β midpoint = 80 β count = 6
Bin 5: 90β100 β midpoint = 95 β count = 5
Frequency Polygon connects:
(21.5, 2) β (41, 3) β (61, 4) β (80, 6) β (95, 5)
```
> [!NOTE]
> **Frequency Polygon vs Histogram π§ **
> They show the SAME data β just in different visual forms.
> Histogram = bars | Frequency Polygon = line connecting bar tops at midpoints.
> A Frequency Polygon is useful when you want to **compare two distributions** on the same chart (two lines are cleaner than overlapping bars).
---
## 3.8 π¦ Creating Box Plots
A **Box Plot** (also called Box-and-Whisker plot) shows the statistical summary of a dataset in one compact visual β it shows spread, middle, and outliers all at once!
**What does a Box Plot show?**
```
Minimum Q1 Median Q3 Maximum
|ββββββββββ[ BOX | BOX ]ββββββββββββββ|
β β β β β
Whisker 25th% 50th% 75th% Whisker
* β Outliers (dots outside whiskers)
```
::: grid
::: card π | Q1 (25th %) | 25% of data is below this | Lower edge of box
::: card π | Q2 / Median | 50% of data is below | Line inside box
::: card π | Q3 (75th %) | 75% of data is below | Upper edge of box
::: card π | IQR | Q3 - Q1 = spread of middle 50% | Height of the box
:::
```python
# box_plot_demo.py
import matplotlib.pyplot as plt
# Marks of three different sections:
section_a = [78, 85, 90, 92, 88, 76, 95, 82, 87, 91]
section_b = [55, 65, 70, 78, 82, 60, 88, 72, 68, 75]
section_c = [90, 92, 95, 98, 88, 94, 97, 85, 91, 96]
data = [section_a, section_b, section_c]
plt.figure(figsize=(9, 6))
plt.boxplot(data,
labels=['Section A', 'Section B', 'Section C'],
notch=False, # True = notched box (shows CI of median)
patch_artist=True, # Fill boxes with color
boxprops=dict(facecolor='lightblue', color='navy'),
medianprops=dict(color='red', linewidth=2),
whiskerprops=dict(color='gray'),
flierprops=dict(marker='o', color='red', markersize=6)
)
plt.title("Section-wise Marks Distribution (Box Plot)")
plt.xlabel("Section")
plt.ylabel("Marks")
plt.grid(axis='y', linestyle='--', alpha=0.5)
plt.show()
```
**Simple Box Plot (for exam use):**
```python
# simple_boxplot.py
import matplotlib.pyplot as plt
marks = [45, 55, 60, 65, 70, 72, 75, 78, 80, 85, 88, 90, 92, 95, 98]
plt.boxplot(marks)
plt.title("Marks Distribution")
plt.ylabel("Marks")
plt.show()
```
**Multiple box plots for comparison:**
```python
plt.boxplot([section_a, section_b, section_c])
plt.xticks([1, 2, 3], ['Section A', 'Section B', 'Section C'])
```
> [!IMPORTANT]
> **Board Exam Tip**
> "What does a Box Plot show? Name its 5 components." β **2-mark** question!
> Answer: A Box Plot shows data distribution based on a **five-number summary**: Minimum, Q1 (25th percentile), Median (Q2/50th %), Q3 (75th percentile), and Maximum. Points outside the whiskers are **outliers**.
---
## 3.9 π Plotting Data from a DataFrame
Real-world data is stored in DataFrames β here's how to create charts directly from Pandas DataFrames!
---
### 3.9.1 Plotting a DataFrame's Data using PyPlot's Graph Functions
You can pass DataFrame columns directly to plt functions:
```python
# df_to_pyplot.py
import pandas as pd
import matplotlib.pyplot as plt
# Create sample DataFrame:
data = {
'Month': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
'Sales_A': [5000, 7000, 6500, 8000, 7500, 9000],
'Sales_B': [4000, 6000, 7500, 7000, 8500, 8000]
}
df = pd.DataFrame(data)
print(df)
# Line Chart from DataFrame columns:
plt.figure(figsize=(9, 5))
plt.plot(df['Month'], df['Sales_A'],
color='blue', marker='o', label='Branch A')
plt.plot(df['Month'], df['Sales_B'],
color='red', marker='s', label='Branch B')
plt.title("Monthly Sales Comparison")
plt.xlabel("Month")
plt.ylabel("Sales (βΉ)")
plt.legend()
plt.grid(True)
plt.show()
# Bar Chart from DataFrame:
plt.figure(figsize=(9, 5))
plt.bar(df['Month'], df['Sales_A'],
color='steelblue', label='Branch A')
plt.title("Branch A Monthly Sales")
plt.xlabel("Month")
plt.ylabel("Sales")
plt.legend()
plt.show()
# Scatter Chart from DataFrame:
plt.figure(figsize=(7, 5))
plt.scatter(df['Sales_A'], df['Sales_B'],
color='purple', s=100, label='Month')
plt.title("Sales A vs Sales B Correlation")
plt.xlabel("Branch A Sales")
plt.ylabel("Branch B Sales")
plt.legend()
plt.show()
```
---
### 3.9.2 Plotting a DataFrame's Data using DataFrame's `plot()` πΌ
The easiest way! DataFrames have a built-in `plot()` method that creates charts directly:
```python
# df_plot_method.py
import pandas as pd
import matplotlib.pyplot as plt
data = {
'Month': ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
'Maths': [85, 90, 78, 92, 88],
'Science': [88, 82, 75, 90, 85],
'English': [75, 80, 72, 85, 79]
}
df = pd.DataFrame(data)
df = df.set_index('Month') # Set Month as index for clean charts
# LINE CHART (default):
df.plot(kind='line', figsize=(9, 5), marker='o')
plt.title("Monthly Marks β Line Chart")
plt.ylabel("Marks")
plt.grid(True)
plt.show()
# BAR CHART:
df.plot(kind='bar', figsize=(9, 5), color=['blue', 'red', 'green'])
plt.title("Monthly Marks β Bar Chart")
plt.ylabel("Marks")
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
# HORIZONTAL BAR:
df.plot(kind='barh', figsize=(9, 6))
plt.title("Monthly Marks β Horizontal Bar")
plt.show()
# AREA CHART (filled line chart):
df.plot(kind='area', figsize=(9, 5), alpha=0.6)
plt.title("Monthly Marks β Area Chart")
plt.show()
```
**Plotting a SINGLE column:**
```python
# Single column pie chart:
avg_marks = pd.Series({
'Maths': 86.6,
'Science': 84.0,
'English': 78.2
})
avg_marks.plot(kind='pie',
autopct='%1.1f%%',
figsize=(7, 7),
startangle=90)
plt.title("Average Marks Distribution")
plt.ylabel("") # Remove default y-label for pie charts
plt.show()
```
**All `kind=` options for DataFrame's `plot()`:**
| kind= | Chart Type | Use When |
| :--- | :--- | :--- |
| `'line'` | Line Chart | Trends over time |
| `'bar'` | Vertical Bar Chart | Comparing categories |
| `'barh'` | Horizontal Bar Chart | Long category names |
| `'hist'` | Histogram | Distribution of values |
| `'box'` | Box Plot | Statistical spread |
| `'pie'` | Pie Chart | Parts of a whole |
| `'scatter'` | Scatter Plot | Correlation between two columns |
| `'area'` | Area Chart | Cumulative trend |
```python
# Complete example with all customizations:
df.plot(kind='bar',
x='Month', # (if not using index)
y=['Maths', 'Science'], # Plot only specific columns
color=['navy', 'coral'],
figsize=(10, 6),
width=0.7,
edgecolor='black',
title="Subject Marks Comparison"
)
plt.xlabel("Month")
plt.ylabel("Marks")
plt.legend(loc='upper left')
plt.tight_layout()
plt.savefig("subject_chart.png", dpi=150, bbox_inches='tight')
plt.show()
```
> [!IMPORTANT]
> **Board Exam Tip**
> "How do you plot a bar chart directly from a Pandas DataFrame?" β **2-3 mark** question!
> Answer: Use `df.plot(kind='bar')` β the DataFrame's built-in plot method.
> Example:
> ```python
> df.plot(kind='bar', color='steelblue')
> plt.title("My Chart")
> plt.show()
> ```
---
## π All Chart Types β Quick Comparison
```mermaid
graph TD
DATA["Your Data"]
TREND["Shows TREND over time?"]
COMP["COMPARING categories?"]
PART["Parts of a WHOLE?"]
DIST["DISTRIBUTION of numbers?"]
CORR["RELATIONSHIP between 2 vars?"]
STATS["STATISTICAL SPREAD?"]
DATA --> TREND
DATA --> COMP
DATA --> PART
DATA --> DIST
DATA --> CORR
DATA --> STATS
TREND --> LINE["π Line Chart\nplt.plot()"]
COMP --> BAR["π Bar Chart\nplt.bar()"]
PART --> PIE["π₯§ Pie Chart\nplt.pie()"]
DIST --> HIST["π Histogram\nplt.hist()"]
CORR --> SCAT["π Scatter Chart\nplt.scatter()"]
STATS --> BOX["π¦ Box Plot\nplt.boxplot()"]
style LINE fill:#2196F3,color:#fff
style BAR fill:#4CAF50,color:#fff
style PIE fill:#FF9800,color:#fff
style HIST fill:#9C27B0,color:#fff
style SCAT fill:#F44336,color:#fff
style BOX fill:#009688,color:#fff
```
---
## β οΈ Common Errors and Misconceptions
| Mistake | Problem | Fix |
| :--- | :--- | :--- |
| β `plt.savefig()` after `plt.show()` | Saves blank image | β
Always `savefig()` BEFORE `show()` |
| β `plt.bar(y)` without x values | ValueError | β
`plt.bar(x, y)` β must give both |
| β `plt.legend()` without `label=` | Empty legend box | β
Add `label='name'` to each plot call |
| β Using `linestyle` in `scatter()` | Has no effect (scatter has no lines) | β
Use `linewidths=` for marker borders |
| β `plt.pie()` with negative values | ValueError | β
Pie chart values must all be positive |
| β `markersize=` in `scatter()` | No effect | β
Use `s=` (capital S) for scatter size |
| β Forgetting `plt.tight_layout()` | Labels overlap/cut off | β
Call `plt.tight_layout()` before show |
| β Multiple charts overlapping | Not calling `plt.figure()` again | β
Start each new chart with `plt.figure()` |
---
## π Quick Revision β Exam Ready!
**Import:**
```python
import matplotlib.pyplot as plt
```
**Chart Creation Functions:**
| Chart | Function | Key Parameters |
| :--- | :--- | :--- |
| Line | `plt.plot(x, y)` | `color, linestyle, marker, linewidth, label` |
| Scatter | `plt.scatter(x, y)` | `color, s, marker, edgecolors, label` |
| Bar (V) | `plt.bar(x, height)` | `color, width, edgecolor, label` |
| Bar (H) | `plt.barh(y, width)` | Same but `barh` |
| Pie | `plt.pie(values, labels=)` | `autopct, explode, shadow, startangle` |
| Histogram | `plt.hist(data, bins=)` | `color, edgecolor, density` |
| Box Plot | `plt.boxplot(data)` | `labels, patch_artist, notch` |
**Customization Functions:**
| Purpose | Function |
| :--- | :--- |
| Title | `plt.title("text")` |
| X-axis label | `plt.xlabel("text")` |
| Y-axis label | `plt.ylabel("text")` |
| Legend | `plt.legend(loc='best')` |
| Grid | `plt.grid(True)` |
| Axis limits | `plt.xlim(min, max)` / `plt.ylim(min, max)` |
| Tick labels | `plt.xticks(positions, labels)` |
| Figure size | `plt.figure(figsize=(w, h))` |
| Save | `plt.savefig("file.png", dpi=300)` |
| Show | `plt.show()` β ALWAYS LAST! |
---
## π― Sample Board Exam Questions
### Q1: Very Short Answer [1 mark each]
a) Write the import statement for Matplotlib's pyplot.
**β `import matplotlib.pyplot as plt`**
b) Which function is used to display a pie chart in Matplotlib?
**β `plt.pie()`**
c) What does `autopct='%1.1f%%'` do in a pie chart?
**β It displays the percentage value on each slice of the pie chart, formatted to 1 decimal place.**
d) What is the difference between `plt.bar()` and `plt.barh()`?
**β `plt.bar()` creates a vertical bar chart; `plt.barh()` creates a horizontal bar chart.**
e) Why should `savefig()` be called before `show()`?
**β Because `show()` clears the figure from memory. If `savefig()` is called after `show()`, it saves a blank image.**
---
### Q2: Short Answer [2 marks]
**Q: What is a histogram? How is it different from a bar chart?**
A **histogram** is a graph that shows the frequency distribution of continuous data grouped into ranges called bins.
| | Bar Chart | Histogram |
| :--- | :--- | :--- |
| **Data** | Discrete categories | Continuous numerical data |
| **Bars** | Have gaps between them | Touch each other (no gaps) |
| **X-axis** | Category names | Numerical ranges (bins) |
| **Function** | `plt.bar()` | `plt.hist()` |
---
### Q3: Program Writing [3 marks]
**Q: Write a Python program to create a bar chart showing marks of 5 students.**
```python
import matplotlib.pyplot as plt
students = ['Arjun', 'Bina', 'Chirag', 'Divya', 'Esha']
marks = [85, 90, 78, 92, 88]
plt.bar(students, marks, color='steelblue', edgecolor='black')
plt.title("Student Marks")
plt.xlabel("Student Name")
plt.ylabel("Marks")
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.savefig("marks_chart.png")
plt.show()
```
---
### Q4: Program Writing [4 marks]
**Q: Create a DataFrame of monthly sales for two branches and plot a line chart with legends.**
```python
import pandas as pd
import matplotlib.pyplot as plt
data = {
'Month': ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
'Branch_A': [5000, 7000, 6500, 8000, 9000],
'Branch_B': [4000, 6000, 7500, 7000, 8500]
}
df = pd.DataFrame(data)
df = df.set_index('Month')
df.plot(kind='line', figsize=(9, 5), marker='o')
plt.title("Monthly Sales β Both Branches")
plt.ylabel("Sales (βΉ)")
plt.grid(True)
plt.legend(loc='upper left')
plt.tight_layout()
plt.savefig("sales_chart.png")
plt.show()
```
---
## βοΈ Practice Problems
1. Create a line chart showing daily temperature for 7 days. Use red dashed line, square markers, and add grid.
2. Create a pie chart showing how you spend 24 hours: Sleep(8), School(7), Study(4), Play(2), Other(3).
3. Write code to create a histogram of these marks: [45, 52, 63, 71, 72, 80, 82, 85, 87, 90, 91, 93, 95] with 4 bins.
4. Create a multiple bar chart comparing Section A and Section B marks in Maths, Science, and English.
5. Create a Pandas DataFrame of 5 products with their prices. Plot a horizontal bar chart using `df.plot(kind='barh')`.
6. Create a box plot comparing the marks of three classes. What does the box represent?
7. What is a Frequency Polygon? Write code to overlay a frequency polygon on a histogram.
8. Write code to create a scatter chart showing relationship between study hours (2-10) and marks (50-95).
9. Create a line chart with two lines, add a legend, set axis limits, and save the chart as "result.png".
10. What is the `kind=` parameter in `df.plot()`? List at least 5 chart types you can create using it.
π― CBSE BOARD EXAM 2027
Complete Preparation Resources
Prepare smarter with the right combination of CSIP12's FREE digital resources + optional printed study books.
INFORMATICS PRACTICES β 065
2026β27
LEARN β Core Theory
Sumita Arora β Informatics Practices with Python
Primary2026β27 Session Edition β’ Dhanpat Rai & Co.
PRACTISE β Pandas, SQL & Case Studies
Together With CBSE Class 12 Informatics Practices Question Bank
PrimaryChapterwise & Topicwise | For 2027 Exam
Additional Option
Arihant All in One Informatics Practices Class 12
View on Amazon
You don't need every book. Choose resources that complement your preparation. CSIP12 provides notes, programs, quizzes, solved questions and previous-year papers for FREE.
Learning Support
Need Help With This Chapter?
Save key topics for exam revision, ask questions to teachers, or submit content corrections.
Verified Doubts & Teacher Answers
Loading resolved questions for this note...