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.
Back to List
Calculating...
UNIT 1 : CH 3
Dec 14, 2025
π Plotting with PyPlot
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...