Aimify IP Material
Class 12 · Chapter 4

Plotting Data using Matplotlib

Partly in syllabusUnit 1: Data Handling using Pandas and Data Visualization (25 marks)~16 periods
20 MCQs36 written Qs6 practicals

Overview

This chapter teaches students to turn data into pictures with Matplotlib's pyplot module and with the pandas plot() method. Students draw line plots, bar graphs and histograms, customise them with titles, labels, legends, colours, markers and line styles, and save them as image files for reports and projects.

The 2025-26 syllabus covers the purpose of plotting; drawing and saving line plots, bar graphs and histograms; and customising plots with labels, title and legend. Pie, scatter, box and area plots from the NCERT chapter are enrichment only. Practicals need at least 4 Matplotlib programs in the practical file.

Learning outcomes

  • Students will be able to explain the purpose of data visualisation and choose a suitable chart (line, bar or histogram) for given data.
  • Students will be able to draw line plots with plt.plot() and customise colour, marker, line style and line width.
  • Students will be able to draw vertical, horizontal and grouped bar graphs with bar() and barh().
  • Students will be able to draw histograms with hist(), choosing bins, edgecolor, histtype and cumulative, and read frequencies from them.
  • Students will be able to add a title, axis labels, legend, grid and custom ticks, and set the figure size.
  • Students will be able to save a chart in different formats with savefig().
  • Students will be able to plot Series and DataFrames, including data read from CSV files, using df.plot(kind=...).
  • Students will be able to complete, correct and predict the output of plotting code in board-style questions.

Lesson plan

Period 1
Why visualise data?

Show the class a table of 30 students' marks and ask who can spot the trend in 10 seconds; then show the same data as a chart. Students list visualisations they see daily (speedometer, weather map, cricket worm). Introduce the three syllabus charts with the 'use it when' table on the board.

Periods 2-3
Matplotlib basics and line plot

Lab: install/check Matplotlib, import pyplot as plt, and plot a week's temperature. Add title, xlabel, ylabel. Pair task: plot two students' unit-test marks with label= and legend(), then add grid().

Periods 4-5
Customising lines

Board: build the colour, marker and line-style code table with students. Lab challenge cards: 'draw a green dotted line with star markers, 3 points thick' in both long form and format-string form. Introduce figsize, xticks with rotation, yticks.

Periods 6-7
Bar graphs

Lab: subject-wise average with bar(), colour list, width and edgecolor; then barh() for long names. Demonstrate the grouped bar trick (x - w/2, x + w/2) and the bug when both calls use the same x. Students compare boys and girls per section.

Periods 8-9
Histograms

Hand count first: students tally a list of 20 marks into 10-mark intervals on paper, then check with hist() and the printed counts. Discuss the left-edge rule. Explore histtype='step' and cumulative=True. Board: bar graph vs histogram table.

Period 10
Saving plots

Lab: savefig() in PNG, PDF and JPG; open the files to check. Deliberately put savefig() after show() to see the blank file, and discuss why.

Periods 11-12
pandas plotting

Lab: df.plot(kind='line'/'bar'/'barh'/'hist') on a canteen or result DataFrame; read result.csv, set_index('Name') and plot selected columns. Students note what pandas does automatically (legend, x labels).

Period 13
Enrichment and project ideas

Quick demo of pie, scatter, box and area plots. Students pick an open dataset (for example from data.gov.in) for their project and decide which chart suits each question they want to answer.

Periods 14-16
Practice and assessment

Worksheet of fill-in-the-blank, error-finding and output-prediction questions; practical-file programs; a 20-minute quiz using the MCQs and assertion-reason items from this page.

Notes

Purpose of plotting data

Data visualisation means showing data as a picture: a chart, graph or diagram. A table of 500 numbers is hard to read, but a single chart can show the pattern in a few seconds.

We plot data to:

  • see a trend over time (for example, the monthly fee collection of a school rising or falling);
  • compare quantities (sales of five products, marks in five subjects);
  • see the distribution of values (how many students scored 40-50, 50-60 and so on);
  • spot outliers and mistakes in data (a mark of 950 entered instead of 95);
  • communicate results to people who will not read the raw numbers (parents, principals, managers).

Everyday examples of visualisation are the speedometer of a scooter, a weather map on the news, a cricket run-rate graph (the worm) and an ECG report.

ChartUse it when you want to showSchool example
Line plotChange over time or an ordered sequenceMarks of a student across four unit tests
Bar graphComparison between separate categoriesAverage marks in each subject
HistogramHow numeric data is spread over intervals (frequency)Number of students in the 40-50, 50-60, ... marks ranges
Teacher tip

The 2025-26 CBSE syllabus names exactly three plot types: line plot, bar graph and histogram, plus adding a label, title and legend, and saving a plot. Pie, scatter, box and area plots are enrichment only.

Matplotlib and the pyplot module

Matplotlib is a Python library for drawing 2D charts. It is not part of standard Python, so it is installed once with pip install matplotlib at the command prompt.

Its pyplot module contains simple functions such as plot(), bar(), hist(), title() and show(). By convention it is imported with the alias plt.

Every chart is drawn on a figure (the whole window or image). Inside the figure is a plot area (axes) with an x-axis and a y-axis. Each pyplot call adds something to the current figure, and plt.show() finally displays it.

Steps to draw any chart:

  1. Import pyplot: import matplotlib.pyplot as plt
  2. Prepare the data in lists, NumPy arrays or a pandas Series/DataFrame.
  3. Call a plotting function such as plt.plot(x, y).
  4. Customise: title, axis labels, legend, grid, colours.
  5. Save with plt.savefig() (optional) and display with plt.show().
Python
import matplotlib.pyplot as plt

days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
temp = [31, 33, 34, 32, 35, 36, 34]   # maximum temperature in Jaipur (deg C)

plt.plot(days, temp)
plt.show()
Teacher tip

The output is a single blue line joining seven points, with the day names on the x-axis and temperatures on the y-axis. There is no title or label yet: point out to students that an unlabelled chart is incomplete, and board answers lose marks for it.

Line plot with title, axis labels, legend and grid

plt.plot(x, y) joins the points (x, y) with straight lines. If only one list is given, as in plt.plot(y), Python uses 0, 1, 2, ... as the x values.

To make a chart readable we add:

  • plt.title('text'): heading at the top of the chart;
  • plt.xlabel('text') and plt.ylabel('text'): names of the x-axis and y-axis;
  • plt.legend(): a small box that tells which line is which. It uses the label= given to each plot() call;
  • plt.grid(True): background grid lines that help read values.

Calling plot() more than once before show() draws several lines on the same chart, each in a new default colour.

Python
import matplotlib.pyplot as plt

tests = ['UT1', 'UT2', 'UT3', 'UT4']
riya = [68, 74, 81, 88]
kabir = [72, 70, 77, 79]

plt.plot(tests, riya, label='Riya')
plt.plot(tests, kabir, label='Kabir')
plt.title('Unit Test Marks in Informatics Practices')
plt.xlabel('Unit Test')
plt.ylabel('Marks (out of 100)')
plt.legend()
plt.grid(True)
plt.show()
Teacher tip

plt.legend() shows labels only for lines drawn with label=. Another way is plt.legend(['Riya', 'Kabir']), where the names are given in the order the lines were drawn. The loc parameter moves the box, for example plt.legend(loc='upper left').

Customising lines: color, marker, linestyle, linewidth

Optional keyword arguments of plot() change how a line looks:

  • color (or c): a name such as 'red', a one-letter code such as 'r', or a hex code such as '#1f77b4';
  • marker: a symbol drawn at each data point, such as 'o', '*', 's', '^', 'D', '+', 'x';
  • markersize (or ms) and markeredgecolor: size and border colour of the marker;
  • linestyle (or ls): '-' or 'solid', '--' or 'dashed', ':' or 'dotted', '-.' or 'dashdot';
  • linewidth (or lw): thickness of the line in points (default 1.5).

A short format string combines colour, marker and line style in one argument. 'ro--' means red, circle markers, dashed line. 'g^:' means green, triangle markers, dotted line.

CodeColourCodeMarkerCodeLine style
'b'blue'o'circle'-'solid
'g'green's'square'--'dashed
'r'red'^'triangle up':'dotted
'c'cyan'*'star'-.'dash-dot
'm'magenta'D'diamond
'y'yellow'+' / 'x'plus / cross
'k'black'.'point
'w'white'p' / 'h'pentagon / hexagon
Python
import matplotlib.pyplot as plt

overs = [1, 2, 3, 4, 5, 6]
india = [8, 14, 25, 31, 42, 55]
australia = [6, 15, 21, 30, 37, 44]

plt.plot(overs, india, color='blue', marker='o', markersize=8,
         linestyle='--', linewidth=2, label='India')
plt.plot(overs, australia, 'y^:', linewidth=3, label='Australia')
plt.title('Powerplay: cumulative runs')
plt.xlabel('Over')
plt.ylabel('Runs')
plt.legend()
plt.show()
Teacher tip

Black is 'k', not 'b' (that is blue). This is a favourite one-mark question. Also note the spelling: the parameter is color (American spelling). Writing colour= gives an error.

Figure size, xticks and yticks

  • plt.figure(figsize=(width, height)) sets the size of the figure in inches. It must be called before the plotting function. The default is about 6.4 x 4.8 inches.
  • plt.xticks(positions, labels) decides where the marks (ticks) on the x-axis appear and what text is written there. rotation=45 tilts long labels so they do not overlap.
  • plt.yticks() does the same for the y-axis. plt.xlim() and plt.ylim() set the range of an axis.

In the example, the months are stored as numbers 1 to 12, and xticks() replaces the numbers with month names.

Python
import matplotlib.pyplot as plt

month = list(range(1, 13))
rain = [1, 0, 1, 1, 11, 520, 840, 590, 340, 90, 15, 4]   # Mumbai, mm (approx.)
names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
         'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']

plt.figure(figsize=(10, 4))
plt.plot(month, rain, color='navy', marker='s')
plt.xticks(month, names, rotation=45)
plt.yticks(range(0, 901, 100))
plt.title('Average monthly rainfall in Mumbai')
plt.xlabel('Month')
plt.ylabel('Rainfall (mm)')
plt.grid(True)
plt.show()
Teacher tip

The chart is wide and short, the x-axis shows tilted month names instead of 1-12, and the y-axis has a tick every 100 mm. The sharp peak in July makes the monsoon pattern obvious, which is a good discussion point on why a line plot suits time-ordered data.

Bar graph: plt.bar()

A bar graph compares values of separate categories. Each category gets one rectangular bar whose height is the value. Bars have gaps between them because the categories are not continuous.

Syntax: plt.bar(x, height, width=0.8, color=..., edgecolor=..., label=...)

  • x: category names or positions;
  • height: the values;
  • width: width of each bar (default 0.8);
  • color: one colour for all bars, or a list with one colour per bar;
  • edgecolor and linewidth: border colour and thickness of the bars.
Python
import matplotlib.pyplot as plt

subjects = ['English', 'Maths', 'Physics', 'Chemistry', 'IP']
average = [72, 65, 61, 68, 81]

plt.bar(subjects, average, width=0.6,
        color=['tomato', 'orange', 'gold', 'yellowgreen', 'skyblue'],
        edgecolor='black')
plt.title('Class XII-B: subject-wise average marks')
plt.xlabel('Subject')
plt.ylabel('Average marks')
plt.show()
Teacher tip

Ask students: "Would a line plot be right here?" No. Joining English to Maths with a line suggests a trend between subjects, which is meaningless. Use a line plot for ordered data (time), a bar graph for categories.

Horizontal bar graph: plt.barh()

plt.barh(y, width) draws bars that run left to right. It is useful when category names are long or there are many categories.

In barh(), the categories go on the y-axis and the values on the x-axis, so the axis labels swap: the values are named with xlabel(). The thickness of each bar is set with height= (default 0.8), because width now means the length of the bar.

Python
import matplotlib.pyplot as plt

players = ['Shubman', 'Yashasvi', 'Rinku', 'Tilak', 'Hardik']
runs = [412, 375, 298, 260, 214]

plt.barh(players, runs, color='darkorange', height=0.5)
plt.title('Runs scored in the series')
plt.xlabel('Runs')
plt.ylabel('Batter')
plt.show()

Comparing two sets of data: grouped (multiple) bar graph

To compare two values for every category (boys and girls in each section, 2024 and 2025 sales of each product) we draw two bar() calls side by side.

The trick is to shift the x positions. We use numbers 0, 1, 2, ... as positions (with numpy.arange()), draw the first set at x - w/2 and the second at x + w/2, where w is the bar width. Finally xticks() puts the category names back under each pair, and legend() tells which colour is which.

Python
import matplotlib.pyplot as plt
import numpy as np

sections = ['XII-A', 'XII-B', 'XII-C', 'XII-D']
boys = [18, 20, 15, 17]
girls = [16, 14, 19, 18]

x = np.arange(len(sections))   # positions 0, 1, 2, 3
w = 0.35
plt.bar(x - w/2, boys, width=w, color='steelblue', label='Boys')
plt.bar(x + w/2, girls, width=w, color='hotpink', label='Girls')
plt.xticks(x, sections)
plt.title('Strength of Class XII sections')
plt.xlabel('Section')
plt.ylabel('Number of students')
plt.legend()
plt.show()
Teacher tip

Without NumPy, students can build the shifted positions with a list comprehension: x = [0, 1, 2, 3] and x2 = [i + 0.35 for i in x]. If both bar() calls use the same x values, the second set of bars hides the first. This is a common practical-exam mistake.

Histogram: plt.hist() and bins

A histogram shows the frequency distribution of numeric data. The range of the data is divided into intervals called bins, and the height of each bar is the number of values that fall in that bin. Because the bins are continuous, the bars touch each other (no gaps).

Syntax: plt.hist(x, bins=10, color=..., edgecolor=..., histtype='bar', cumulative=False)

  • x: a single list, array or Series of numbers (the raw data, not counts);
  • bins as an integer: that many equal-width bins from the minimum to the maximum value (default 10);
  • bins as a list of edges, for example [40, 50, 60, 70]: bins 40-50, 50-60 and 60-70;
  • edgecolor: colour of the bar borders, which makes adjacent bars easy to see.

Boundary rule: every bin includes its left edge and excludes its right edge, except the last bin, which includes both. So with edges [40, 50, 60], a mark of 50 is counted in the 50-60 bin, and a mark of 60 is counted in the last bin.

plt.hist() also returns the counts, the bin edges and the drawn bars, so we can print the frequency table.

Python
import matplotlib.pyplot as plt

marks = [45, 52, 58, 61, 63, 67, 68, 70, 72, 74,
         75, 77, 78, 81, 83, 85, 88, 90, 92, 97]

counts, edges, bars = plt.hist(marks, bins=[40, 50, 60, 70, 80, 90, 100],
                               color='skyblue', edgecolor='black')
print('Frequencies:', counts)
print('Bin edges  :', edges)
plt.title('Distribution of IP marks, Class XII-A')
plt.xlabel('Marks')
plt.ylabel('Number of students')
plt.show()
Output
Frequencies: [1. 2. 4. 6. 4. 3.]
Bin edges  : [ 40.  50.  60.  70.  80.  90. 100.]
Teacher tip

Make students count by hand first: 70 goes in 70-80 (left edge included), 90 goes in 90-100. Then run the code and match their counts with the printed frequencies. This removes the most common confusion about bins.

Histogram options: histtype and cumulative

  • histtype controls the drawing style:
  • 'bar' (default): ordinary filled bars;
  • 'barstacked': when several data sets are given, their bars are stacked on top of each other;
  • 'step': only the outline is drawn, with no fill. Useful to compare two data sets on one chart;
  • 'stepfilled': an outline that is filled in, with no lines between bars.
  • cumulative=True: each bar shows the count of all values up to and including that bin. The last bar always equals the total number of values. This answers questions such as "How many students scored below 70?"
  • Other useful parameters: alpha (transparency between 0 and 1), orientation='horizontal', and range=(low, high).
Bar graphHistogram
Compares separate categoriesShows the distribution of continuous numeric data
Gaps between barsNo gaps: bars touch
Each bar is one category; you supply the heightsEach bar is an interval (bin); Python counts the values in it
Order of bars can be changedOrder of bins is fixed (numeric scale)
Function: bar() / barh()Function: hist()
Python
import matplotlib.pyplot as plt

heights = [142, 145, 147, 149, 150, 151, 152, 153, 154, 155,
           156, 156, 157, 158, 159, 160, 161, 163, 165, 168]

counts, edges, bars = plt.hist(heights, bins=[140, 145, 150, 155, 160, 165, 170],
                               cumulative=True, histtype='step',
                               color='purple', linewidth=2)
print('Cumulative counts:', counts)
plt.title('Heights of Class IX students (cumulative)')
plt.xlabel('Height (cm)')
plt.ylabel('Students up to this height')
plt.show()
Output
Cumulative counts: [ 1.  4.  9. 15. 18. 20.]

Saving a plot: plt.savefig()

plt.savefig('file name') writes the current figure to a file. The format is taken from the extension: .png, .jpg, .pdf, .svg and others. Useful parameters are dpi= (dots per inch, image quality) and bbox_inches='tight' (trims extra white space).

Call savefig() before show(). When the window opened by show() is closed, the figure is cleared, so a savefig() written after it saves a blank image.

A file name without a folder is saved in the current working folder. A full path can be given; on Windows use forward slashes or a raw string, for example plt.savefig('D:/IP/charts/sales.png') or plt.savefig(r'D:\IP\charts\sales.png').

Python
import matplotlib.pyplot as plt

items = ['Samosa', 'Sandwich', 'Juice', 'Idli', 'Noodles']
sold = [120, 85, 60, 95, 70]

plt.bar(items, sold, color='seagreen')
plt.title('Canteen sales on Monday')
plt.xlabel('Item')
plt.ylabel('Plates sold')
plt.savefig('canteen_sales.png')
plt.savefig('canteen_sales.pdf', bbox_inches='tight')
plt.show()
Teacher tip

Board question pattern: "Write the statement to save the chart as sales.jpg". Answer: plt.savefig('sales.jpg'). Students often write plt.save() or plt.savefig(sales.jpg) without quotes. Both are wrong.

Plotting with pandas: df.plot(kind=...)

pandas Series and DataFrames have a plot() method that uses Matplotlib internally. One call draws the chart, adds a legend from the column names and labels the x-axis from the index.

General syntax: df.plot(kind='...', x='column', y='column or list', title='...', color=..., ...)

Values of kind used in the syllabus:

  • 'line' (default): line plot, one line per numeric column;
  • 'bar': vertical bars; for several numeric columns the bars are grouped automatically;
  • 'barh': horizontal bars;
  • 'hist': histogram of the numeric columns (accepts bins, edgecolor, cumulative).

Enrichment values: 'pie', 'scatter', 'box', 'area'.

Most Matplotlib parameters (color, marker, linestyle, linewidth, figsize, edgecolor) can be passed straight to df.plot(). Axis labels, savefig() and show() still come from plt, so we import both libraries.

Python
import pandas as pd
import matplotlib.pyplot as plt

canteen = pd.DataFrame({
    'Month': ['Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep'],
    'Tea': [520, 480, 300, 450, 470, 510],
    'Coffee': [310, 290, 180, 260, 300, 330]
})

canteen.plot(kind='line', x='Month', y=['Tea', 'Coffee'],
             marker='o', title='Cups sold in the staff canteen')
plt.ylabel('Cups')
plt.show()

canteen.plot(kind='bar', x='Month', color=['brown', 'peru'],
             title='Tea vs Coffee (bar)')
plt.ylabel('Cups')
plt.show()
Teacher tip

The first chart has two lines with markers and a legend (Tea, Coffee) created automatically. The second has a pair of bars for each month. Remind students that with kind='bar' the x-axis labels are the index unless x= names a column.

pandas: kind='barh' and kind='hist'

  • df.plot(kind='barh', x='Name', y='Total') gives a horizontal bar chart; the categories are on the y-axis.
  • df.plot(kind='hist', y='column', bins=..., edgecolor=...) gives a histogram of a column. If y is not given, all numeric columns are drawn as overlapping histograms, so name the column you want.
  • Series.plot(kind='hist') works the same way on a single column, e.g. df['IP'].plot(kind='hist').

Both examples below use the same small result DataFrame.

Python
import pandas as pd
import matplotlib.pyplot as plt

result = pd.DataFrame({
    'Name': ['Aman', 'Bhavya', 'Chirag', 'Divya', 'Esha', 'Farhan', 'Gauri', 'Harsh'],
    'Total': [412, 455, 380, 470, 398, 431, 446, 365]
})

result.plot(kind='barh', x='Name', y='Total', color='slateblue',
            legend=False, title='Total marks (out of 500)')
plt.xlabel('Total marks')
plt.show()

result.plot(kind='hist', y='Total', bins=[350, 380, 410, 440, 470, 500],
            edgecolor='black', title='Distribution of totals')
plt.xlabel('Total marks')
plt.show()

Plotting data from a CSV file

In projects and practicals, data usually comes from a CSV file. The steps are:

  1. Read the file with pd.read_csv().
  2. If needed, set a column as the index with set_index() so it becomes the x-axis.
  3. Select the columns to plot and call plot().

The file result.csv used here has the columns shown in the table. In the code, set_index('Name') puts student names on the x-axis, and selecting three columns draws a grouped bar chart.

NameEnglishMathsPhysicsChemistryIP
Aarav7885726991
Diya8892818495
Ishaan6558617074
Meera9176798889
Rohan7081686480
Sana8467737786
Python
import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv('result.csv')
df = df.set_index('Name')
print(df.mean())

df[['English', 'Maths', 'IP']].plot(kind='bar', figsize=(9, 4),
                                    edgecolor='black')
plt.title('Marks in three subjects')
plt.ylabel('Marks')
plt.xticks(rotation=0)
plt.savefig('three_subjects.png')
plt.show()
Output
English      79.333333
Maths        76.500000
Physics      72.333333
Chemistry    75.333333
IP           85.833333
dtype: float64
Teacher tip

df.mean() here works because the only text column, Name, has been moved to the index. If Name were still a column, newer pandas versions raise an error; use df.mean(numeric_only=True) in that case.

Pie chart and scatter plot (Enrichment)

These are not in the CBSE 2025-26 syllabus but appear in the NCERT book and are useful for projects.

  • Pie chart: shows parts of a whole as slices of a circle. plt.pie(values, labels=..., autopct='%1.1f%%') prints the percentage on each slice. With pandas: df.plot(kind='pie', y='column').
  • Scatter plot: shows the relationship between two numeric variables as unconnected dots. plt.scatter(x, y); with pandas: df.plot(kind='scatter', x='col1', y='col2').
Python
import matplotlib.pyplot as plt

transport = ['Bus', 'Walk', 'Cycle', 'Parent', 'Auto']
students = [420, 150, 110, 230, 90]
plt.pie(students, labels=transport, autopct='%1.1f%%')
plt.title('How students come to school')
plt.show()

hours = [1, 2, 2, 3, 4, 4, 5, 6, 6, 7]
score = [42, 50, 55, 58, 66, 70, 74, 80, 83, 90]
plt.scatter(hours, score, color='crimson', marker='D')
plt.title('Self-study hours vs test score')
plt.xlabel('Hours of self-study per day')
plt.ylabel('Score')
plt.show()

Box plot and area plot (Enrichment)

  • Box plot (box-and-whisker): summarises a column using the minimum, first quartile, median, third quartile and maximum, and marks outliers as separate dots. Good for comparing the spread of marks in two sections. plt.boxplot(data) or df.plot(kind='box').
  • Area plot: a line plot with the area below the line filled in. With several columns the areas are stacked. df.plot(kind='area').
Python
import pandas as pd
import matplotlib.pyplot as plt

marks = pd.DataFrame({
    'XII-A': [55, 62, 68, 70, 71, 74, 78, 81, 85, 97],
    'XII-B': [40, 58, 60, 63, 66, 67, 69, 72, 75, 79]
})
marks.plot(kind='box', title='Spread of IP marks')
plt.ylabel('Marks')
plt.show()

energy = pd.DataFrame({'Solar': [20, 35, 50, 70],
                       'Grid': [80, 70, 60, 45]},
                      index=['2022', '2023', '2024', '2025'])
energy.plot(kind='area', title='School electricity sources (units x 100)')
plt.show()

Quick reference: pyplot functions in this chapter

Teachers can project or print this table as a one-page revision sheet before the unit test.

Function / parameterPurposeExample
plot()Line plotplt.plot(x, y, 'ro--')
bar()Vertical bar graphplt.bar(names, values, width=0.5)
barh()Horizontal bar graphplt.barh(names, values)
hist()Histogramplt.hist(data, bins=5, edgecolor='k')
title()Chart headingplt.title('Sales 2025')
xlabel() / ylabel()Axis namesplt.xlabel('Month')
legend()Key for several data setsplt.legend(loc='upper right')
grid()Background gridplt.grid(True)
xticks() / yticks()Tick positions and labelsplt.xticks([0, 1], ['A', 'B'])
figure(figsize=)Size of chart in inchesplt.figure(figsize=(8, 4))
savefig()Save chart to a fileplt.savefig('chart.png')
show()Display the chartplt.show()
df.plot(kind=)Plot from pandasdf.plot(kind='bar', x='Name')

Key terms

Data visualisation
Representing data as charts or graphs so that patterns, trends and comparisons are easy to see.
Matplotlib
A Python library for creating 2D static, animated and interactive plots.
pyplot
The module of Matplotlib with simple functions such as plot(), bar(), hist() and show(); imported as plt.
Figure
The whole window or image on which one or more plots are drawn.
Line plot
A chart that joins data points with straight lines; used for trends over time.
Bar graph
A chart of rectangular bars, with gaps, whose lengths compare values of separate categories.
Histogram
A chart of touching bars showing how many values of numeric data fall in each interval.
Bin
One interval of a histogram; bins are set by the bins parameter of hist().
Frequency
The number of data values that fall in a bin.
Legend
A key on the chart that tells which colour or line stands for which data set.
Marker
A symbol (circle, star, square, ...) drawn at each data point of a line plot.
Line style
The pattern of a line: solid, dashed, dotted or dash-dot.
Tick
A small mark with a label along an axis; changed with xticks() and yticks().
figsize
A parameter giving (width, height) of a figure in inches.
savefig()
A pyplot function that saves the current figure to a file such as PNG, JPG, PDF or SVG.
kind
The parameter of pandas plot() that chooses the chart type: 'line', 'bar', 'barh', 'hist' and others.
Cumulative histogram
A histogram in which each bar counts all values up to and including that bin.

MCQs

Tap an option to check it, or use Show answers above to reveal them all.

  1. Which Matplotlib module provides simple functions such as plot(), bar() and hist()?

    Answer

    (b) matplotlib.pyplot

    pyplot is the Matplotlib module with simple plotting functions. It is usually imported as import matplotlib.pyplot as plt.

  2. What does plt.xticks([0, 1, 2], ['Mon', 'Tue', 'Wed']) do?

    Answer

    (c) Shows the labels Mon, Tue and Wed at x positions 0, 1 and 2

    The first list gives tick positions and the second gives the text shown at those positions.

  3. By default, plt.plot(x, y) draws:

    Answer

    (a) a line joining the points

    plot() draws a line plot. Markers appear only if a marker is given.

  4. Which function writes a name below the horizontal axis?

    Answer

    (d) xlabel()

    xlabel() names the x-axis; ylabel() names the y-axis; title() writes the heading.

  5. A program calls plt.plot(x, a) and plt.plot(x, b), then plt.legend(), but no legend appears on the chart. What is the most likely reason?

    Answer

    (a) The label parameter was not given in the plot() calls

    legend() takes its text from the label= of each plotted line. Without labels there is nothing to show.

  6. The format string 'g*--' in plt.plot(x, y, 'g*--') gives:

    Answer

    (c) a green dashed line with star markers

    g = green, * = star marker, -- = dashed line.

  7. Which value of linestyle draws a dotted line?

    Answer

    (d) ':'

    ':' (or 'dotted') is dotted; '-' solid, '--' dashed, '-.' dash-dot.

  8. Which colour code stands for black in Matplotlib?

    Answer

    (b) 'k'

    'k' is black. 'b' is blue.

  9. Which parameter of plot() makes the line thicker?

    Answer

    (a) linewidth

    linewidth (or lw) sets the thickness of the line in points.

  10. Which function draws bars from left to right, with categories on the y-axis?

    Answer

    (d) barh()

    barh() draws a horizontal bar graph.

  11. What is the default width of each bar in plt.bar()?

    Answer

    (b) 0.8

    The default width is 0.8, which leaves a gap of 0.2 between bars placed at positions 0, 1, 2, ...

  12. A histogram is the most suitable chart to show:

    Answer

    (a) how the heights of 200 students are spread over intervals

    A histogram shows the distribution of continuous numeric data over intervals. State populations need a bar graph and a daily price needs a line plot.

  13. plt.hist(data, bins=5) divides the data into:

    Answer

    (c) 5 equal-width bins from the smallest to the largest value

    An integer bins value gives that many equal-width intervals covering the range of the data.

  14. With bins=[0, 10, 20, 30], in which bin is the value 20 counted?

    Answer

    (c) 20-30

    Each bin includes its left edge and excludes its right edge (except the last bin), so 20 goes in 20-30.

  15. Which histtype draws only the outline of the histogram, without filling?

    Answer

    (b) 'step'

    'step' draws an unfilled outline. 'stepfilled' fills it.

  16. If cumulative=True is passed to hist(), then:

    Answer

    (d) each bar shows the count of all values up to and including that bin

    A cumulative histogram adds up counts, so the last bar equals the total number of values.

  17. A student writes plt.show() and then plt.savefig('a.png'). The saved file is blank. Why?

    Answer

    (b) The figure is cleared once the shown window is closed, so savefig must come first

    Always call savefig() before show().

  18. Which file type can NOT be produced by plt.savefig()?

    Answer

    (d) .docx

    savefig supports image and vector formats such as png, jpg, pdf and svg, but not Word documents.

  19. In plt.figure(figsize=(8, 4)), the numbers 8 and 4 are:

    Answer

    (c) width and height in inches

    figsize is (width, height) in inches.

  20. A DataFrame df has a column Month and two numeric columns, Tea and Coffee. What does df.plot(kind='bar', x='Month') draw?

    Answer

    (a) A grouped bar chart with one pair of bars per month and a legend for Tea and Coffee

    pandas draws one bar per numeric column for each x value and builds the legend from the column names.

Assertion–Reason

Choose: (A) Both A and R are true and R is the correct explanation of A. (B) Both A and R are true but R is not the correct explanation of A. (C) A is true but R is false. (D) A is false but R is true.
  1. Assertion (A): In a histogram there are no gaps between adjacent bars.

    Reason (R): The bins of a histogram are continuous intervals; the right edge of one bin is the left edge of the next.

    Answer

    (A)

    Both are true and the continuity of bins is exactly why the bars touch.

  2. Assertion (A): plt.legend() can show a separate name for each line in a multi-line plot.

    Reason (R): The legend reads the text from the label parameter of each plot() call.

    Answer

    (A)

    Both are true and R explains how legend() knows the names.

  3. Assertion (A): Calling plt.savefig('x.png') after plt.show() always saves the complete chart.

    Reason (R): savefig() can save a chart in formats such as PNG, PDF and SVG.

    Answer

    (D)

    A is false: after the shown window is closed the figure is cleared and a blank image is saved. R is true.

  4. Assertion (A): A bar graph is suitable for comparing the sales of different products in a shop.

    Reason (R): The bars of a bar graph must always be vertical.

    Answer

    (C)

    A is true. R is false: barh() draws horizontal bars.

  5. Assertion (A): The marker parameter shows a symbol at each data point of a line plot.

    Reason (R): The linestyle parameter decides whether a line is solid, dashed or dotted.

    Answer

    (B)

    Both statements are true, but the line style has nothing to do with markers, so R does not explain A.

Short answer

  1. 2 marks

    What is data visualisation? Give two reasons why we plot data.

    Answer

    Data visualisation is the graphical representation of data using charts and graphs.

    Reasons: (1) trends and patterns, such as rising or falling sales, are seen at a glance; (2) it is easier to compare values and spot errors or outliers, and to communicate results to people who will not read raw numbers.

  2. 2 marks

    Give two differences between a bar graph and a histogram.

    Answer
    • A bar graph compares separate categories; a histogram shows the distribution of continuous numeric data over intervals.
    • Bars of a bar graph have gaps; bars of a histogram touch each other. (Also: bar() is given the heights, hist() counts the values itself.)
  3. 2 marks

    Fill in the blanks so that the program draws a line plot of runs scored in each over, with a title and an x-axis label.

    1. import matplotlib.________ as plt
    2. overs = [1, 2, 3, 4, 5]
    3. runs = [6, 11, 4, 9, 14]
    4. plt.________(overs, runs)
    5. plt.________('Runs per over')
    6. plt.________('Over number')
    7. plt.show()
    Answer

    Blanks: pyplot, plot, title, xlabel. Complete program:

    Python
    import matplotlib.pyplot as plt
    overs = [1, 2, 3, 4, 5]
    runs = [6, 11, 4, 9, 14]
    plt.plot(overs, runs)
    plt.title('Runs per over')
    plt.xlabel('Over number')
    plt.show()
  4. 2 marks

    Write a single statement to plot lists x and y as a red dashed line, 3 points thick, with circle markers, and labelled 'Sales'.

    Answer

    Either form is correct:

    Python
    import matplotlib.pyplot as plt
    x = [1, 2, 3]
    y = [5, 7, 4]
    plt.plot(x, y, color='red', linestyle='--', linewidth=3, marker='o', label='Sales')
    # or: plt.plot(x, y, 'ro--', linewidth=3, label='Sales')
    plt.show()
  5. 2 marks

    What is the purpose of plt.legend()? What must the programmer do for it to show meaningful text?

    Answer

    legend() displays a key on the chart telling which colour, line or bar belongs to which data set. For it to show names, each plotting call must have a label= argument (for example plt.plot(x, y, label='2025')), or the names must be passed as a list: plt.legend(['2024', '2025']).

  6. 2 marks

    Fill in the blanks to draw a histogram of the list ages with bins 10-20, 20-30, 30-40, 40-50 and 50-60, with black borders around the bars.

    plt.hist(ages, ________ = [________], ________ = 'black')

    Answer

    bins, 10, 20, 30, 40, 50, 60 and edgecolor:

    Python
    import matplotlib.pyplot as plt
    ages = [12, 18, 25, 27, 33, 38, 41, 45, 47, 52, 58]
    plt.hist(ages, bins=[10, 20, 30, 40, 50, 60], edgecolor='black')
    plt.show()
  7. 2 marks

    What does plt.savefig() do? Write the statement to save the current chart as result.pdf in the folder D:/IP.

    Answer

    savefig() saves the current figure to a file; the format comes from the extension. It must be called before show().

    plt.savefig('D:/IP/result.pdf')

  8. 2 marks

    Predict the number of bars and the height of each bar drawn by: plt.hist([5, 15, 25, 35, 45], bins=[0, 20, 40, 60])

    Answer

    Three bins: 0-20 has 5 and 15 (2 values), 20-40 has 25 and 35 (2 values), 40-60 has 45 (1 value). So there are 3 bars of heights 2, 2 and 1. Checking with Python:

    Python
    import matplotlib.pyplot as plt
    counts, edges, bars = plt.hist([5, 15, 25, 35, 45], bins=[0, 20, 40, 60])
    print(counts)
    Output
    [2. 2. 1.]
  9. 2 marks

    A DataFrame stock has columns Item and Qty. Fill in the blanks to draw a horizontal bar chart of quantity for each item.

    stock.plot(kind=________, x=________, y='Qty')

    Answer

    'barh' and 'Item':

    Python
    import pandas as pd
    import matplotlib.pyplot as plt
    stock = pd.DataFrame({'Item': ['Pen', 'Pencil', 'Eraser'], 'Qty': [120, 300, 90]})
    stock.plot(kind='barh', x='Item', y='Qty')
    plt.show()
  10. 2 marks

    Name any four parameters of plot() used to customise a line and state what each does.

    Answer
    • color: colour of the line, e.g. 'green'.
    • marker: symbol at each point, e.g. 'o', '*'.
    • linestyle: pattern of the line, e.g. '--', ':'.
    • linewidth: thickness of the line, e.g. 2.5.

    (Also accepted: markersize, label, markeredgecolor.)

  11. 2 marks

    Differentiate between xlabel() and xticks() with an example of each.

    Answer

    xlabel() writes one name for the whole x-axis, e.g. plt.xlabel('Month').

    xticks() sets the positions and text of the individual tick marks along the x-axis, e.g. plt.xticks([1, 2, 3], ['Jan', 'Feb', 'Mar']).

  12. 2 marks

    What is the role of the bins parameter in hist()? Explain the two ways it can be given.

    Answer

    bins decides the intervals into which the data is grouped.

    • As an integer, e.g. bins=4: four equal-width bins from the minimum to the maximum value.
    • As a list of edges, e.g. bins=[0, 33, 60, 100]: bins 0-33, 33-60 and 60-100, which may be of unequal width. Each bin includes its left edge; the last bin also includes its right edge.

Long answer

  1. 3 marks

    Write a Python program to draw a bar graph showing the house-wise points of a school sports meet: Tagore 145, Raman 160, Shivaji 132, Ashoka 171. Give each bar a different colour, add a title and axis labels, and save the chart as houses.png.

    Answer

    Program (savefig comes before show):

    Python
    import matplotlib.pyplot as plt
    
    houses = ['Tagore', 'Raman', 'Shivaji', 'Ashoka']
    points = [145, 160, 132, 171]
    
    plt.bar(houses, points, color=['red', 'blue', 'green', 'gold'])
    plt.title('Annual Sports Meet: House Points')
    plt.xlabel('House')
    plt.ylabel('Points')
    plt.savefig('houses.png')
    plt.show()
  2. 3 marks

    Fill in the five blanks so that the program plots the maximum temperatures of Delhi and Shimla for five days on the same chart, with markers, a legend and a grid.

    1. import matplotlib.pyplot as plt
    2. days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri']
    3. delhi = [39, 41, 40, 42, 38]
    4. shimla = [24, 25, 23, 26, 22]
    5. plt.plot(days, delhi, marker='o', ________='Delhi')
    6. plt.plot(days, shimla, marker='s', label='Shimla')
    7. plt.________('Maximum temperature in May')
    8. plt.ylabel('Temperature (deg C)')
    9. plt.________()
    10. plt.________(True)
    11. plt.________()
    Answer

    Blanks: label, title, legend, grid, show.

    Python
    import matplotlib.pyplot as plt
    days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri']
    delhi = [39, 41, 40, 42, 38]
    shimla = [24, 25, 23, 26, 22]
    plt.plot(days, delhi, marker='o', label='Delhi')
    plt.plot(days, shimla, marker='s', label='Shimla')
    plt.title('Maximum temperature in May')
    plt.ylabel('Temperature (deg C)')
    plt.legend()
    plt.grid(True)
    plt.show()
  3. 3 marks

    Find and correct the errors in the following code. Rewrite the correct code and underline (mention) each correction.

    1. import matplotlib.pyplot as pl
    2. x = [1, 2, 3, 4]
    3. y = [10, 20, 15]
    4. plt.plot(x, y, colour='red')
    5. plt.title = 'Weekly sales'
    6. plt.show
    Answer

    Corrections: (1) alias must match its use, so as plt; (2) x and y must be the same length, so add a fourth value to y; (3) colour must be color; (4) title is a function, so plt.title('Weekly sales'); (5) show must be called with brackets: plt.show().

    Python
    import matplotlib.pyplot as plt
    x = [1, 2, 3, 4]
    y = [10, 20, 15, 25]
    plt.plot(x, y, color='red')
    plt.title('Weekly sales')
    plt.show()
  4. 3 marks

    Explain the histtype and cumulative parameters of hist(). Write code that draws a cumulative, outline-only histogram of the list wt = [38, 41, 44, 45, 47, 49, 50, 52, 55, 58] using bins 35-40-45-50-55-60, and print the cumulative counts.

    Answer

    histtype sets the drawing style: 'bar' (filled bars, default), 'barstacked' (stacked bars for several data sets), 'step' (outline only) and 'stepfilled' (filled outline). cumulative=True makes each bar count all values up to and including that bin, so the last bar equals the number of values.

    Bins: 35-40 has 38 (1); 40-45 has 41, 44 (2); 45-50 has 45, 47, 49 (3); 50-55 has 50, 52 (2); 55-60 has 55, 58 (2). Cumulative counts: 1, 3, 6, 8, 10.

    Python
    import matplotlib.pyplot as plt
    wt = [38, 41, 44, 45, 47, 49, 50, 52, 55, 58]
    c, e, b = plt.hist(wt, bins=[35, 40, 45, 50, 55, 60],
                       histtype='step', cumulative=True)
    print(c)
    plt.title('Weights of students (cumulative)')
    plt.xlabel('Weight (kg)')
    plt.ylabel('Number of students')
    plt.show()
    Output
    [ 1.  3.  6.  8. 10.]
  5. 5 marks

    The file sales.csv contains quarterly sales (in lakh rupees) of a company's North and South regions, with columns Region, Quarter and Sales.

    Write a program to (a) read the file into a DataFrame, (b) arrange it so that each quarter is a row and each region a column, (c) draw a grouped bar chart with a title, axis labels and legend, and (d) save the chart as quarterly.png. Also print the total sales of each region.

    Answer

    pivot() turns the long table into one row per quarter and one column per region. df.plot(kind='bar') then draws a pair of bars per quarter, and the legend is built from the column names North and South.

    Python
    import pandas as pd
    import matplotlib.pyplot as plt
    
    df = pd.read_csv('sales.csv')
    table = df.pivot(index='Quarter', columns='Region', values='Sales')
    print(table.sum())
    
    table.plot(kind='bar', color=['teal', 'coral'], edgecolor='black')
    plt.title('Quarterly sales by region')
    plt.xlabel('Quarter')
    plt.ylabel('Sales (Rs lakh)')
    plt.xticks(rotation=0)
    plt.legend(title='Region')
    plt.savefig('quarterly.png')
    plt.show()
    Output
    Region
    North    1780
    South    1710
    dtype: int64
  6. 5 marks

    Compare a line plot, a bar graph and a histogram: say when each is used and write one short pyplot statement for each. Then, for each situation below, name the best chart: (i) monthly electricity bill of a school for a year, (ii) number of medals won by five states, (iii) waiting times of 300 patients at a hospital.

    Answer
    • Line plot: shows change over time or ordered data; points are joined. plt.plot(months, bill)
    • Bar graph: compares separate categories; bars with gaps. plt.bar(states, medals)
    • Histogram: shows how numeric data is spread over intervals; bars touch and heights are frequencies. plt.hist(waiting, bins=10)

    (i) Line plot, because the bill changes over time. (ii) Bar graph, because states are separate categories. (iii) Histogram, because waiting time is continuous data and we want its distribution.

  7. 5 marks

    Write a program that creates a DataFrame of five students (Name, Term1, Term2 marks out of 100), then draws (a) a line chart of both terms with markers and (b) a horizontal bar chart of Term2 marks, both from the DataFrame using plot(kind=...). Add suitable titles and axis labels.

    Answer

    One possible program:

    Python
    import pandas as pd
    import matplotlib.pyplot as plt
    
    df = pd.DataFrame({
        'Name': ['Arjun', 'Pooja', 'Kunal', 'Neha', 'Vikram'],
        'Term1': [72, 85, 64, 90, 58],
        'Term2': [78, 88, 70, 86, 66]
    })
    
    df.plot(kind='line', x='Name', y=['Term1', 'Term2'], marker='o',
            title='Term-wise marks')
    plt.ylabel('Marks')
    plt.show()
    
    df.plot(kind='barh', x='Name', y='Term2', color='olive',
            legend=False, title='Term 2 marks')
    plt.xlabel('Marks')
    plt.show()

Case-based

Case study 1

The PT teacher of Kendriya Vidyalaya, Bhopal recorded the runs scored by two inter-house teams, Tigers and Eagles, in five matches:

  • Matches: M1, M2, M3, M4, M5
  • Tigers: 145, 162, 128, 171, 150
  • Eagles: 138, 155, 149, 160, 166

Riya, a Class XII student, is writing a program to compare the two teams. Her incomplete code is:

  1. import ________ as plt
  2. m = ['M1', 'M2', 'M3', 'M4', 'M5']
  3. t = [145, 162, 128, 171, 150]
  4. e = [138, 155, 149, 160, 166]
  5. plt.plot(m, t, 'bo-', label='Tigers')
  6. plt.plot(m, e, ________, label='Eagles')
  7. plt.________
  8. plt.________
  9. plt.show()
  1. 1 mark

    Fill in line 1.

    Answer

    import matplotlib.pyplot as plt

  2. 1 mark

    Fill in line 6 so that the Eagles line is red, dashed, with star markers.

    Answer

    plt.plot(m, e, 'r*--', label='Eagles')

  3. 1 mark

    Fill in lines 7 and 8 to add the title 'Tigers vs Eagles' and show the legend.

    Answer

    Line 7: plt.title('Tigers vs Eagles'); line 8: plt.legend()

  4. 1 mark

    Riya wants to save the chart as teams.png. Write the statement and say where it must be placed.

    Answer

    plt.savefig('teams.png') must be placed before plt.show(), i.e. between lines 8 and 9. Complete program:

    Python
    import matplotlib.pyplot as plt
    m = ['M1', 'M2', 'M3', 'M4', 'M5']
    t = [145, 162, 128, 171, 150]
    e = [138, 155, 149, 160, 166]
    plt.plot(m, t, 'bo-', label='Tigers')
    plt.plot(m, e, 'r*--', label='Eagles')
    plt.title('Tigers vs Eagles')
    plt.legend()
    plt.savefig('teams.png')
    plt.show()
Case study 2

Gupta General Store, Lucknow keeps its weekly sales in a DataFrame shop:

  • Columns: Day, Grocery, Dairy, Snacks
  • Rows: Mon to Sat, values in rupees

The owner's son, Aditya, wants to use pandas plotting to present this to his father.

  1. 1 mark

    Write the statement to draw a line chart of all three categories with Day on the x-axis.

    Answer

    shop.plot(kind='line', x='Day')

  2. 1 mark

    Write the statement to draw a grouped bar chart of only Dairy and Snacks, with the title 'Dairy vs Snacks'.

    Answer

    shop.plot(kind='bar', x='Day', y=['Dairy', 'Snacks'], title='Dairy vs Snacks')

  3. 1 mark

    Which kind value draws a histogram of the Grocery column? Write the statement with 4 bins.

    Answer

    kind='hist': shop.plot(kind='hist', y='Grocery', bins=4)

  4. 2 marks

    Write the complete program for the bar chart, including the DataFrame creation (any sample values), a y-axis label and showing the plot.

    Answer

    Sample program:

    Python
    import pandas as pd
    import matplotlib.pyplot as plt
    shop = pd.DataFrame({
        'Day': ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
        'Grocery': [5200, 4800, 5100, 4900, 6100, 7800],
        'Dairy': [2100, 2000, 2250, 1950, 2300, 2900],
        'Snacks': [1500, 1350, 1600, 1400, 1900, 2600]
    })
    shop.plot(kind='bar', x='Day', y=['Dairy', 'Snacks'], title='Dairy vs Snacks')
    plt.ylabel('Sales (Rs)')
    plt.show()
Case study 3

A school counsellor collected the number of hours of sleep of 16 Class X students on a school night:

sleep = [5, 5.5, 6, 6, 6.5, 6.5, 7, 7, 7, 7.5, 7.5, 8, 8, 8.5, 9, 9.5]

She wants a chart that shows how many students sleep 5-6, 6-7, 7-8, 8-9 and 9-10 hours.

  1. 1 mark

    Which type of chart should she use, and why?

    Answer

    A histogram, because sleep hours are continuous numeric data and she wants the number of students in each interval (a frequency distribution).

  2. 1 mark

    Write the hist() statement with the required bins and black bar borders.

    Answer

    plt.hist(sleep, bins=[5, 6, 7, 8, 9, 10], edgecolor='black')

  3. 1 mark

    How many students fall in the 7-8 hour bin? Explain how a value of exactly 8 is treated.

    Answer

    The 7-8 bin includes 7 but not 8, so it holds 7, 7, 7, 7.5, 7.5: 5 students. A value of 8 goes in the 8-9 bin. Verified:

    Python
    import matplotlib.pyplot as plt
    sleep = [5, 5.5, 6, 6, 6.5, 6.5, 7, 7, 7, 7.5, 7.5, 8, 8, 8.5, 9, 9.5]
    c, e, b = plt.hist(sleep, bins=[5, 6, 7, 8, 9, 10], edgecolor='black')
    print(c)
    Output
    [2. 4. 5. 3. 2.]
  4. 1 mark

    What change to the statement would make each bar show the number of students sleeping up to that many hours?

    Answer

    Add cumulative=True: plt.hist(sleep, bins=[5, 6, 7, 8, 9, 10], edgecolor='black', cumulative=True)

Practicals

1Subject-wise performance: line plot

Create a DataFrame of the marks of four students in five subjects. Draw a line plot with one line per student (subjects on the x-axis), using a different marker for each line. Add a title, axis labels, legend and grid.

Solution
Python
import pandas as pd
import matplotlib.pyplot as plt

marks = pd.DataFrame({
    'Ananya': [88, 92, 79, 85, 95],
    'Bharat': [72, 65, 70, 68, 81],
    'Charu': [91, 78, 84, 80, 87],
    'Dev': [60, 74, 66, 71, 77]
}, index=['English', 'Maths', 'Physics', 'Chemistry', 'IP'])
print(marks)

styles = ['o', 's', '^', 'D']
for name, m in zip(marks.columns, styles):
    plt.plot(marks.index, marks[name], marker=m, label=name)
plt.title('Subject-wise marks of four students')
plt.xlabel('Subject')
plt.ylabel('Marks')
plt.legend()
plt.grid(True)
plt.show()
Output
           Ananya  Bharat  Charu  Dev
English        88      72     91   60
Maths          92      65     78   74
Physics        79      70     84   66
Chemistry      85      68     80   71
IP             95      81     87   77
Viva questions (3)
  • Why is a legend needed here? There are four lines, and the legend tells which line belongs to which student.
  • What does marker='s' draw? A square at each data point.
  • What happens if plt.legend() is called but no label is given? No legend is drawn and Matplotlib shows a warning.

2Class-wise average: bar graph and savefig

The average IP marks of sections XII-A to XII-E are 74, 68, 81, 77 and 63. Draw a bar graph with bar width 0.5, a different colour for each bar and black edges. Add a title and labels, and save the chart as both PNG and PDF before displaying it.

Solution
Python
import matplotlib.pyplot as plt

sec = ['XII-A', 'XII-B', 'XII-C', 'XII-D', 'XII-E']
avg = [74, 68, 81, 77, 63]

plt.bar(sec, avg, width=0.5, edgecolor='black',
        color=['#4e79a7', '#f28e2b', '#59a14f', '#e15759', '#b07aa1'])
plt.title('Section-wise average in IP')
plt.xlabel('Section')
plt.ylabel('Average marks')
plt.savefig('section_avg.png')
plt.savefig('section_avg.pdf')
plt.show()
Viva questions (3)
  • What is the default bar width? 0.8.
  • Why must savefig() come before show()? Closing the shown window clears the figure, so a later savefig() saves a blank image.
  • How do you make the bars horizontal? Use plt.barh() with the values on the x-axis.

3Term 1 vs Term 2: grouped bar graph

Compare the Term 1 and Term 2 class averages in five subjects using a grouped (side-by-side) bar graph. Put subject names under each pair of bars and add a legend.

Solution
Python
import matplotlib.pyplot as plt
import numpy as np

subjects = ['English', 'Maths', 'Physics', 'Chemistry', 'IP']
term1 = [70, 62, 58, 66, 78]
term2 = [74, 69, 63, 65, 84]

x = np.arange(len(subjects))
w = 0.4
plt.bar(x - w/2, term1, width=w, label='Term 1')
plt.bar(x + w/2, term2, width=w, label='Term 2')
plt.xticks(x, subjects)
plt.title('Class average: Term 1 vs Term 2')
plt.ylabel('Average marks')
plt.legend()
plt.show()

for s, a, b in zip(subjects, term1, term2):
    print(f'{s:10s} change: {b - a:+d}')
Output
English    change: +4
Maths      change: +7
Physics    change: +5
Chemistry  change: -1
IP         change: +6
Viva questions (3)
  • Why are the x positions shifted by w/2? So that the two bars of each subject stand side by side instead of on top of each other.
  • What does np.arange(5) give? The array [0 1 2 3 4].
  • Which subject's average fell in Term 2? Chemistry, by 1 mark.

4Frequency distribution: histogram

The marks (out of 50) of 25 students in an IP unit test are given. Draw a histogram with bins of width 10 from 0 to 50, sky-blue bars with black edges, and print the frequency of each bin. Then draw a second, cumulative histogram using histtype='step'.

Solution
Python
import matplotlib.pyplot as plt

marks = [12, 18, 22, 25, 27, 28, 30, 31, 31, 33, 34, 35, 36,
         37, 38, 38, 40, 41, 42, 43, 44, 46, 47, 49, 50]
edges = [0, 10, 20, 30, 40, 50]

freq, b, p = plt.hist(marks, bins=edges, color='skyblue', edgecolor='black')
plt.title('IP unit test marks')
plt.xlabel('Marks (out of 50)')
plt.ylabel('Number of students')
plt.show()

for i in range(len(freq)):
    print(f'{edges[i]}-{edges[i+1]}: {int(freq[i])}')

plt.hist(marks, bins=edges, cumulative=True, histtype='step', linewidth=2)
plt.title('Cumulative frequency')
plt.xlabel('Marks (out of 50)')
plt.ylabel('Students up to this mark')
plt.show()
Output
0-10: 0
10-20: 2
20-30: 4
30-40: 10
40-50: 9
Viva questions (3)
  • In which bin is the mark 30 counted? In 30-40, because a bin includes its left edge.
  • In which bin is the mark 50 counted? In 40-50, because the last bin includes both edges.
  • What does the last bar of a cumulative histogram show? The total number of values, here 25.

5Aggregate and plot data from a CSV file

Read sales.csv (columns Region, Quarter, Sales). Use groupby to find the total sales of each region and the total for each quarter. Plot region totals as a horizontal bar chart and quarter totals as a line chart, each with a title.

Solution
Python
import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv('sales.csv')
by_region = df.groupby('Region')['Sales'].sum()
by_quarter = df.groupby('Quarter')['Sales'].sum()
print(by_region)
print(by_quarter)

by_region.plot(kind='barh', color='darkcyan', title='Total sales by region')
plt.xlabel('Sales (Rs lakh)')
plt.show()

by_quarter.plot(kind='line', marker='o', color='maroon', title='Total sales by quarter')
plt.ylabel('Sales (Rs lakh)')
plt.show()
Output
Region
North    1780
South    1710
Name: Sales, dtype: int64
Quarter
Q1    800
Q2    870
Q3    840
Q4    980
Name: Sales, dtype: int64
Viva questions (3)
  • Which function reads a CSV file into a DataFrame? pandas.read_csv().
  • Why do we select ['Sales'] before sum()? So that only the numeric column is added, not the text columns.
  • What is on the y-axis of the barh chart? The index of the Series, i.e. the region names.

6One DataFrame, many charts with df.plot(kind=...)

Create a DataFrame of daily AQI (air quality index) readings for two cities over seven days. Using only df.plot(), draw (a) a line plot with markers and a figure size of 9 x 4 inches, (b) a grouped bar chart, and (c) a histogram of one city's values with 4 bins and black edges.

Solution
Python
import pandas as pd
import matplotlib.pyplot as plt

aqi = pd.DataFrame({
    'Delhi': [312, 290, 335, 360, 298, 275, 320],
    'Chennai': [72, 85, 64, 90, 78, 69, 81]
}, index=['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'])
print(aqi.describe().loc[['mean', 'min', 'max']])

aqi.plot(kind='line', marker='o', figsize=(9, 4), title='Daily AQI')
plt.ylabel('AQI')
plt.show()

aqi.plot(kind='bar', title='Daily AQI (bar)')
plt.ylabel('AQI')
plt.xticks(rotation=0)
plt.show()

aqi.plot(kind='hist', y='Delhi', bins=4, edgecolor='black', title='Delhi AQI spread')
plt.xlabel('AQI')
plt.show()
Output
           Delhi  Chennai
mean  312.857143     77.0
min   275.000000     64.0
max   360.000000     90.0
Viva questions (3)
  • Which kind is the default in df.plot()? 'line'.
  • Where does the legend text come from in df.plot()? From the column names.
  • Name two kinds of df.plot() that are outside the syllabus. 'pie' and 'scatter' (also 'box', 'area').

Common mistakes

  • Writing plt.savefig() after plt.show(). The figure is cleared when the window closes, so the saved file is blank. Always save first, then show.

  • Using colour= (British spelling) as a parameter. Matplotlib accepts only color= (or c=) and raises an error for colour.

  • Calling plt.legend() without giving label= to any plot. No legend is drawn and Matplotlib prints a warning (No artists with labels found to put in legend). Give each plot()/bar() a label, or pass a list of names to legend().

  • Passing counts to hist() instead of raw data, for example plt.hist([5, 8, 3]) meaning "5 students, 8 students, 3 students". hist() counts the values itself; for ready-made counts use bar().

  • Drawing a grouped bar chart with the same x positions for both bar() calls, so one set of bars hides the other. Shift the positions by the bar width.

  • Assigning instead of calling: plt.title = 'Sales' replaces the function and no title appears. Write plt.title('Sales').

  • Lists of different lengths in plt.plot(x, y). Python raises a ValueError; x and y must have the same number of values.

  • Confusing 'b' (blue) with black, which is 'k', and confusing xlabel() (axis name) with xticks() (labels on each tick).