Introduction to Matplotlib
Learn what Matplotlib is, why it is used, and how to create your first visualization in Python.
- What Matplotlib is
- Why Matplotlib is important
- How Matplotlib works
- How to install Matplotlib
- How to import Matplotlib into Python
- How to create your first graph
- How to display and save a chart
01. What is Matplotlib?
Matplotlib is a popular Python library used to create graphs, charts, plots, and other forms of data visualization. It allows programmers and data scientists to represent numerical data visually instead of working with numbers alone.
Matplotlib can create many different types of visualizations, including line graphs, bar charts, scatter plots, histograms, pie charts, and more.
Matplotlib is a Python library for creating data visualizations.
02. Why is Matplotlib Important?
Data can often be difficult to understand when it is presented only as numbers. Visualization makes patterns, relationships, trends, and differences much easier to identify.
For example, imagine having the following monthly sales data:
sales = [120, 150, 180, 210, 250]
Looking at the numbers tells us that sales are increasing, but a graph makes this trend much easier to understand immediately.
- Identify trends
- Compare values
- Find patterns
- Understand large datasets
- Communicate information clearly
- Identify unusual values or outliers
03. Where is Matplotlib Used?
Matplotlib is widely used in programming, data analysis, scientific computing, artificial intelligence, and machine learning.
Data Science
Visualize datasets and discover patterns in data.
Machine Learning
Display training results, accuracy, loss, and predictions.
Scientific Computing
Visualize mathematical and scientific measurements.
Data Analysis
Explore relationships and trends within datasets.
04. Installing Matplotlib
Matplotlib can be installed using Python's package manager, pip.
Open your Command Prompt or Terminal and run:
pip install matplotlib
If the installation is successful, pip will download and install Matplotlib and its required dependencies.
You can verify that Matplotlib is installed by opening Python and importing the library.
05. Importing Matplotlib
After installing Matplotlib, you need to import it into your Python program before using its plotting functionality.
The most commonly used module is pyplot. It is usually imported using the name plt.
import matplotlib.pyplot as plt
- matplotlib is the main visualization library.
- pyplot provides functions for creating plots.
- plt is a short alias commonly used for pyplot.
06. Creating Your First Plot
Let's create a simple line graph. We will begin with two lists containing values for the X and Y axes.
import matplotlib.pyplot as plt x = [1, 2, 3, 4, 5] y = [10, 20, 30, 40, 50] plt.plot(x, y) plt.show()
The plot() function creates the graph, while
show() displays the graph on the screen.
- Matplotlib was imported.
- The X-axis values were created.
- The Y-axis values were created.
plt.plot()created the line graph.plt.show()displayed the graph.
07. Adding a Title and Labels
A graph becomes much easier to understand when it has a title and labels for its axes.
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [10, 20, 30, 40, 50]
plt.plot(x, y)
plt.title("My First Graph")
plt.xlabel("X Values")
plt.ylabel("Y Values")
plt.show()
plt.plot()โ creates a plotplt.title()โ adds a titleplt.xlabel()โ labels the X-axisplt.ylabel()โ labels the Y-axisplt.show()โ displays the graph
08. Saving a Graph
Matplotlib can also save your visualization as an image file.
The savefig() function is used for this purpose.
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [10, 20, 30, 40, 50]
plt.plot(x, y)
plt.title("Sales Data")
plt.xlabel("Month")
plt.ylabel("Sales")
plt.savefig("sales.png")
plt.show()
09. Matplotlib and Machine Learning
Matplotlib is especially important when working with machine learning because models often produce numerical results that need to be visualized.
For example, Matplotlib can be used to visualize training loss, model accuracy, predictions, datasets, and relationships between variables.
Suppose a machine learning model is trained for 20 epochs. You can use Matplotlib to create a graph showing how the model's loss changes during training.
10. What You Should Remember
- Matplotlib is a Python visualization library.
- It is commonly used for creating graphs and charts.
pyplotprovides many plotting functions.pltis the common alias for pyplot.plt.plot()creates a line plot.plt.show()displays a plot.plt.title()adds a title.plt.xlabel()andplt.ylabel()label axes.plt.savefig()saves a visualization.
Create a Python program that produces a line graph using Matplotlib.
- Create an X list containing: 1, 2, 3, 4, 5.
- Create a Y list containing: 5, 10, 15, 20, 25.
- Plot the two lists.
- Add the title "My First Matplotlib Graph".
- Label the X-axis as "Numbers".
- Label the Y-axis as "Values".
- Display the graph.
Expected starting point:
import matplotlib.pyplot as plt x = [1, 2, 3, 4, 5] y = [5, 10, 15, 20, 25] Your code here
In Lecture 02, we will learn about Matplotlib Figures, Axes, and the basic structure of a plot.
Install and Set Up Matplotlib
Install Matplotlib, verify that it is available in your Python environment, and learn the import used throughout this course.
- How to install Matplotlib with pip
- How to check that the installation worked
- Why
pyplotis usually imported asplt - How Python packages and environments work
- How to create your first Matplotlib chart
- How to identify and fix common installation problems
Before starting this lesson, you should have Python installed on your computer and know how to open a terminal or command prompt.
You should also be comfortable running a basic Python program.
01. What Is Matplotlib?
Matplotlib is a Python library used to create visualizations such as line charts, bar charts, scatter plots, histograms and many other types of graphs.
Instead of displaying a large amount of numerical data as plain text, a visualization can help you identify patterns, trends and differences more easily.
Suppose you have the monthly sales figures for a business. You could print every number, but a line chart can make it much easier to see whether sales are increasing or decreasing over time.
02. Install Matplotlib
Open a terminal or command prompt and run:
python -m pip install matplotlib
Using python -m pip helps make sure the package is installed
into the same Python environment that runs your programs.
pip is Python's package installer. It allows you to
install libraries that are not included in Python's standard library.
Matplotlib is one of these external packages.
03. Verify the Installation
Create a Python file and import the library:
import matplotlib
print(matplotlib.__version__)
If this prints a version number without an error, Matplotlib is ready to use.
You should see a version number similar to:
3.x.x
The exact version may be different depending on when you install Matplotlib.
04. Import pyplot
Most basic charts use the pyplot module. The conventional
short name is plt:
import matplotlib.pyplot as plt
The as plt part creates a shorter name for
matplotlib.pyplot. This means that instead of repeatedly
writing the full module name, you can use plt.
plt is not a special Python keyword. It is simply the
commonly used alias for matplotlib.pyplot.
05. Create Your First Chart
Now that Matplotlib is installed, let's create a simple line chart.
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]
plt.plot(x, y)
plt.show()
When you run this program, Matplotlib creates a line chart using the
values stored in x and y.
06. Understanding the Code
Importing pyplot
The first line gives your program access to the plotting functionality provided by Matplotlib.
import matplotlib.pyplot as plt
Creating the Data
The x list contains the horizontal values, while the
y list contains the corresponding vertical values.
x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]
Drawing the Line
plt.plot() tells Matplotlib to create a plot using the
supplied data.
plt.plot(x, y)
Displaying the Chart
plt.show() displays the generated figure.
plt.show()
07. Add a Title and Labels
A chart becomes easier to understand when it has a title and labels describing its axes.
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]
plt.plot(x, y)
plt.title("Simple Growth")
plt.xlabel("Time")
plt.ylabel("Value")
plt.show()
plt.title()adds a chart title.plt.xlabel()labels the x-axis.plt.ylabel()labels the y-axis.plt.show()displays the chart.
08. Common Installation Problems
Problem: pip Is Not Recognized
If your terminal says that pip cannot be found, try using
the Python module form instead:
python -m pip install matplotlib
Problem: Matplotlib Cannot Be Imported
If your program produces a ModuleNotFoundError, Matplotlib
may not be installed in the Python environment running your program.
Run the installation command again using the same Python installation that you use to execute your program.
Problem: Multiple Python Installations
Computers can have more than one Python installation. A package can therefore be installed in one environment while your program runs in another.
When working on larger projects, virtual environments can help keep project dependencies separated.
09. Quick Knowledge Check
Which command is commonly used to install Matplotlib?
python -m pip install matplotlibpython install matplotlibpip create matplotlibmatplotlib install python
What alias is conventionally used for matplotlib.pyplot?
pyplotpltgraph
Which function displays a Matplotlib figure?
plt.display()plt.show()plt.open()plt.view()
10. Practice Exercise
Create a Python program that imports Matplotlib and creates a line chart using the following data:
months = ["Jan", "Feb", "Mar", "Apr", "May"]
sales = [20, 35, 30, 45, 55]
Your program should:
- Import
matplotlib.pyplotasplt - Create a line chart
- Add a title
- Label both axes
- Display the chart using
plt.show()
11. Lesson Summary
- Matplotlib is a Python library for creating visualizations.
- Matplotlib can be installed using pip.
python -m pip install matplotlibinstalls the package.matplotlib.__version__can be used to check the installed version.matplotlib.pyplotprovides many common plotting functions.pltis the conventional alias for pyplot.plt.plot()creates a basic line plot.plt.show()displays the figure.
In the next lecture, you will learn how to create and customize your first line charts, including titles, labels, colors, markers and grid lines.
Without copying the complete example above, create a new chart using your own x and y values. Give it a meaningful title and label both axes.
Create Your First Matplotlib Plot
Build a simple line chart and understand the two calls that display it.
01. Plot Data
Pass a list of values to plt.plot(). Matplotlib uses positions 0, 1, 2, and so on for the X-axis when no X values are supplied.
import matplotlib.pyplot as plt scores = [52, 68, 75, 83, 91] plt.plot(scores) plt.show()
02. Supply X and Y Values
For meaningful coordinates, give plot() an X list followed by a Y list. Both lists must contain the same number of values.
import matplotlib.pyplot as plt months = [1, 2, 3, 4, 5] sales = [12, 19, 15, 25, 30] plt.plot(months, sales) plt.show()
plt.plot(x, y)creates a line chart.plt.show()displays the chart window or inline chart.- X and Y data need matching lengths.
Make a line plot for five daily temperatures. Use the day numbers on the X-axis and the temperatures on the Y-axis.
Matplotlib Figures and Axes
Learn the fundamental structure of Matplotlib plots and understand the difference between a Figure, Axes, and Axis.
- What a Figure is
- What an Axes object is
- The difference between Figure and Axes
- What X-axis and Y-axis objects represent
- How Figures contain one or more Axes
- How to create plots using the object-oriented approach
- How to create multiple plots inside one Figure
01. Understanding the Structure of Matplotlib
Before creating advanced visualizations, it is important to understand how Matplotlib organizes a graph.
A Matplotlib visualization is built using several components. The most important components are the Figure, Axes, and Axis objects.
- Figure โ the overall container for the visualization.
- Axes โ the actual plotting area inside the Figure.
- Axis โ controls the X-axis or Y-axis scale, ticks, and labels.
02. What is a Figure?
A Figure is the overall container that holds one or more plots. You can think of it as the complete canvas on which your visualizations are placed.
A Figure can contain a single plot or multiple plots. This makes Figures especially useful when you need to compare several visualizations.
import matplotlib.pyplot as plt fig = plt.figure() plt.show()
The plt.figure() function creates a new Figure.
Imagine a blank sheet of paper. The entire sheet is the Figure. You can place one or several graphs on that sheet.
03. What is an Axes Object?
An Axes object represents the area where an actual graph is drawn. It contains the plotted data and provides access to titles, labels, limits, ticks, legends, and other parts of the plot.
Despite its name, an Axes object is not the same thing as the X-axis or Y-axis. An Axes object represents the complete plotting area.
Figure = entire canvas
Axes = individual plotting area
Axis = X or Y coordinate system
04. Creating a Figure and Axes
The object-oriented approach allows you to explicitly create a Figure and an Axes object.
import matplotlib.pyplot as plt fig, ax = plt.subplots() plt.show()
The plt.subplots() function creates both a Figure and
an Axes object.
The variable fig represents the Figure, while
ax represents the Axes.
This line:
fig, ax = plt.subplots()
creates a Figure and an Axes object at the same time.
05. Plotting Through the Axes Object
Once you have an Axes object, you can use its methods to create and customize your graph.
import matplotlib.pyplot as plt fig, ax = plt.subplots() x = [1, 2, 3, 4, 5] y = [10, 20, 30, 40, 50] ax.plot(x, y) plt.show()
Notice that we use ax.plot() instead of
plt.plot().
The plot() method belongs to the Axes object and draws
the data inside that specific plotting area.
06. Adding a Title and Labels
The Axes object provides methods for adding titles and labels to the plot.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
x = [1, 2, 3, 4, 5]
y = [10, 20, 30, 40, 50]
ax.plot(x, y)
ax.set_title("Sales Data")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
plt.show()
ax.plot()โ creates a line plotax.set_title()โ sets the plot titleax.set_xlabel()โ sets the X-axis labelax.set_ylabel()โ sets the Y-axis labelax.legend()โ displays a legendax.grid()โ displays grid lines
07. What is an Axis?
An Axis represents one dimension of the coordinate system used by an Axes object.
A normal two-dimensional graph has two Axis objects:
X-Axis
Represents the horizontal dimension of the graph and normally contains the independent variable.
Y-Axis
Represents the vertical dimension of the graph and normally contains the dependent variable.
08. Figure vs Axes vs Axis
These three terms are often confused by beginners. Understanding their relationship is essential when working with Matplotlib's object-oriented interface.
- Figure: The complete canvas or container.
- Axes: The area where a particular graph is drawn.
- Axis: The X or Y coordinate system belonging to an Axes.
09. Creating Multiple Axes
One of the major advantages of using Figures and Axes is the ability to place multiple plots inside a single Figure.
For example, we can create four plotting areas arranged in two rows and two columns.
import matplotlib.pyplot as plt fig, axes = plt.subplots(2, 2) axes[0, 0].plot([1, 2, 3], [1, 4, 9]) axes[0, 1].plot([1, 2, 3], [2, 4, 6]) axes[1, 0].plot([1, 2, 3], [3, 6, 9]) axes[1, 1].plot([1, 2, 3], [4, 8, 12]) plt.show()
Here, plt.subplots(2, 2) creates a Figure containing
four Axes objects.
2 ร 2 means:
- 2 rows
- 2 columns
- 4 plotting areas in total
10. Accessing Individual Axes
When multiple Axes are created, each plotting area can be accessed individually.
import matplotlib.pyplot as plt
fig, axes = plt.subplots(2, 2)
axes[0, 0].set_title("Graph 1")
axes[0, 1].set_title("Graph 2")
axes[1, 0].set_title("Graph 3")
axes[1, 1].set_title("Graph 4")
plt.show()
The indexes identify the position of each Axes object.
For example, axes[0, 0] represents the first row and
first column.
11. Figure Size
You can control the size of a Figure using the
figsize parameter.
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot([1, 2, 3, 4], [10, 20, 30, 40])
ax.set_title("My Graph")
plt.show()
The first value represents the width and the second value represents the height. Matplotlib uses inches for these dimensions.
12. Object-Oriented vs Pyplot Style
Matplotlib supports different ways of creating visualizations. Beginners often start with the pyplot interface.
import matplotlib.pyplot as plt
plt.plot([1, 2, 3], [10, 20, 30])
plt.title("My Graph")
plt.xlabel("X")
plt.ylabel("Y")
plt.show()
The object-oriented approach explicitly works with Figure and Axes objects.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [10, 20, 30])
ax.set_title("My Graph")
ax.set_xlabel("X")
ax.set_ylabel("Y")
plt.show()
The pyplot interface is convenient for simple plots. The object-oriented approach is generally more useful when creating complex visualizations, multiple plots, or reusable plotting code.
13. The Complete Matplotlib Hierarchy
You can think about a Matplotlib visualization as a hierarchy:
Figure
โ
Axes
โ
Axis โ X-axis / Y-axis
โ
Data, lines, labels, ticks, legends, grid, etc.
14. Key Points to Remember
- A Figure is the overall container for a visualization.
- A Figure can contain one or multiple Axes.
- An Axes object represents an individual plotting area.
- An Axes object normally contains an X-axis and Y-axis.
- An Axis controls scales, ticks, and labels.
plt.subplots()can create Figures and Axes together.ax.plot()creates a plot on a specific Axes.- Multiple Axes can be used to create subplot layouts.
- The object-oriented approach is useful for complex visualizations.
Create a Figure containing two separate plots.
- Create a Figure with two Axes arranged horizontally.
- Plot
[1, 2, 3, 4, 5]on the first Axes. - Plot
[5, 10, 15, 20, 25]on the second Axes. - Give each plot a different title.
- Label the X-axis and Y-axis.
- Display the Figure.
Starting point:
import matplotlib.pyplot as plt fig, axes = plt.subplots(1, 2) Your code here plt.show()
In Lecture 05, we will learn how to add clear titles, labels, and legends to a Matplotlib chart.
Make Your Charts Easy to Read
Add clear titles, axis labels, and a legend so that a chart can be understood without guessing. A good visualization should communicate its meaning quickly, even to someone who did not write the code that created it.
01. Add a Title and Axis Labels
Use a descriptive title and label both axes. These details explain what the chart measures and make it useful to other readers.
The plt.title() function adds a title at the top of the chart. The plt.xlabel() function names the horizontal (x) axis, while plt.ylabel() names the vertical (y) axis.
Axis labels are especially important when the numbers have a specific meaning or unit. For example, a value of 32 could represent dollars, students, kilograms, or thousands of sales. Adding the unit removes this ambiguity.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr"]
sales = [18, 25, 21, 32]
plt.plot(months, sales)
plt.title("Monthly Sales")
plt.xlabel("Month")
plt.ylabel("Sales (thousands)")
plt.show()
In this example, the list months provides the values shown along the x-axis, while sales provides the corresponding values on the y-axis.
The title tells us that the chart is about monthly sales. The x-axis tells us which month each point represents, and the y-axis tells us that the sales values are measured in thousands.
Notice that the labels do not change the actual data. They only provide context for the reader. This is an important part of data visualization: the chart should explain itself as much as possible.
02. Add a Legend
When a chart contains more than one data series, give each line a label and call plt.legend().
A legend acts like a key for the chart. It tells the reader which line, marker, or other visual element belongs to each dataset.
For example, if a chart contains online sales and store sales, both lines may look similar. Without a legend, the reader would have to guess which line represents which type of sale.
import matplotlib.pyplot as plt
months = [1, 2, 3, 4]
online = [12, 18, 22, 30]
store = [10, 15, 17, 24]
plt.plot(months, online, label="Online")
plt.plot(months, store, label="Store")
plt.title("Sales by Channel")
plt.xlabel("Month")
plt.ylabel("Sales")
plt.legend()
plt.show()
Here, two separate lines are drawn using two calls to plt.plot(). Each call has its own label.
The first line is given the label "Online", while the second line is given the label "Store". When plt.legend() is called, Matplotlib uses these labels to create the legend automatically.
The legend is particularly useful when a chart compares multiple categories, such as two students, two products, different cities, or different years.
03. Choose Meaningful Labels
Good labels should tell the reader exactly what the data represents. Avoid labels such as "X", "Y", or "Data" when you can provide a more descriptive name.
For example, instead of using plt.ylabel("Value"), you could use plt.ylabel("Temperature (ยฐC)"). The second version immediately tells the reader what the numbers represent and which unit is being used.
A useful rule is to ask yourself: Could someone understand this chart without seeing my Python code? If the answer is no, improve the title or axis labels.
04. Titles Should Explain the Chart
A title should describe the subject of the visualization rather than simply stating the type of chart being used.
A title such as "Line Chart" tells the reader very little. A title such as "Monthly Sales from January to April" gives useful information about what is being displayed.
Clear titles become even more important when several charts are displayed together on a webpage, report, or dashboard.
- Write titles that describe the data, not just the chart type.
- Include units in an axis label when they matter.
- Use a legend only when there are multiple series to identify.
- Make labels specific enough that the chart can be understood without reading the code.
- Keep titles and labels short, clear, and directly related to the data.
- Use the same naming style throughout a group of related charts.
Create a chart with two lines, a title, labels for both axes, and a legend. Choose a dataset such as study hours for two students or rainfall in two cities.
For example, create a list of four months and two sets of values. Plot both datasets on the same chart and give each line a meaningful label.
Your final chart should allow another person to answer these questions without looking at your code: What is being measured? What does each axis represent? What are the units? Which line belongs to which dataset?
Customize a Plot for Clarity
A default chart is a useful start, but thoughtful styling makes data easier to read. Learn to control line appearance, markers, colours, limits, and grid lines without letting decoration hide the message. Customization should have a purpose: help the reader understand the data faster, identify different series, and focus on important patterns.
- How to choose line colours, styles, widths, and markers
- How to set useful axis limits and grid lines
- How to customize a chart through an Axes object
- How to avoid common chart-design mistakes
- How to make visual choices that improve readability
- How to combine several customization options in one chart
01. Style a Line
The plot() function accepts keyword arguments that describe a line. Use these options when the appearance communicates something useful, such as measured versus predicted values.
The color argument controls the line colour, linestyle controls the pattern of the line, and linewidth controls its thickness. You can also add markers to make individual data points easier to identify.
Markers are especially useful when a dataset contains a small number of observations. They allow the reader to see exactly where the values are located rather than relying only on the connecting line.
import matplotlib.pyplot as plt
days = [1, 2, 3, 4, 5]
temperature = [22, 24, 23, 27, 29]
plt.plot(days, temperature,
color="teal",
linestyle="--",
linewidth=2,
marker="o",
markersize=7)
plt.xlabel("Day")
plt.ylabel("Temperature (°C)")
plt.title("Daily Temperature")
plt.show()In this example, color="teal" changes the colour of the line, while linestyle="--" creates a dashed line. The linewidth value controls how thick the line appears.
The marker="o" option places a circular marker at each data point. Increasing markersize makes those points easier to see.
Common line styles are "-" (solid), "--" (dashed), ":" (dotted), and "-." (dash-dot). Useful markers include "o", "s", "^", and "x".
Choose a style based on what the chart needs to communicate. For example, a solid line could represent actual measurements while a dashed line represents an estimate. Styling should add meaning rather than simply make the chart look decorative.
02. Use Colour Deliberately
Matplotlib accepts named colours such as "navy", hexadecimal values such as "#2563eb", and RGB tuples. Prefer a small, consistent palette. Do not rely on red and green alone to communicate an important distinction, because some readers cannot distinguish that pair reliably.
When a chart contains multiple data series, colour can help readers distinguish them quickly. However, using too many colours can make a visualization confusing. A small number of consistent colours is usually easier to understand.
Hexadecimal colours are useful when you want precise control over the appearance of a chart. A hexadecimal colour such as "#2563eb" represents a specific colour value.
fig, ax = plt.subplots()
ax.plot(days, temperature, color="#2563eb", label="Measured")
ax.plot(days, [21, 23, 25, 26, 28], color="#f97316",
linestyle="--", label="Forecast")
ax.legend()
plt.show()Here, the first line represents measured temperature and the second line represents forecast temperature. The different colours and line styles make the two series easier to distinguish.
Notice that the legend also provides text labels. This is important because colour alone should not be the only way the reader can understand the chart.
03. Control the Visible Range
Use xlim() and ylim(), or ax.set_xlim() and ax.set_ylim(), to focus on a meaningful range. Be careful with a truncated y-axis: it can exaggerate small differences. For bar charts, a y-axis starting at zero is generally necessary for an honest comparison.
Axis limits determine which part of the coordinate system is visible. Matplotlib normally chooses limits automatically based on the data, but sometimes you may want to control them yourself.
For example, if you know that temperatures in your dataset normally fall between 20°C and 30°C, setting the y-axis to that range can make the chart easier to examine. However, the chosen range should not mislead the reader or hide important values.
fig, ax = plt.subplots()
ax.plot(days, temperature, marker="o")
ax.set_xlim(1, 5)
ax.set_ylim(20, 30)
ax.set_xlabel("Day")
ax.set_ylabel("Temperature (°C)")
plt.show()In this example, set_xlim(1, 5) makes the x-axis cover days 1 through 5, while set_ylim(20, 30) makes the y-axis cover temperatures from 20°C to 30°C.
Setting limits is useful when comparing several charts because using the same scale makes comparisons more meaningful. If every chart uses a different scale, visual differences can sometimes appear larger or smaller than they really are.
04. Add a Helpful Grid
A light grid helps a reader estimate values. It should support the data rather than compete with it. For a line chart, a horizontal grid is often enough.
Use grid() to add grid lines to an Axes object. The axis argument lets you choose whether to show grid lines on the x-axis, y-axis, or both.
fig, ax = plt.subplots()
ax.plot(days, temperature, marker="o", color="#2563eb")
ax.grid(axis="y", linestyle=":", alpha=0.6)
ax.set_title("Daily Temperature")
plt.show()The alpha argument sets transparency from 0 (fully transparent) to 1 (fully opaque). A lighter grid is normally easier to read.
Using axis="y" adds horizontal grid lines. These lines help the reader compare the plotted points with values on the y-axis.
A grid should not become the most noticeable element of the chart. If the grid is too dark or too dense, it can distract from the actual data.
05. Complete Example
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
visitors = [120, 145, 160, 155, 190, 220]
fig, ax = plt.subplots(figsize=(8, 4.5))
ax.plot(months, visitors, color="#2563eb", linewidth=2.5,
marker="o", label="Website visitors")
ax.set_title("Monthly Website Visitors")
ax.set_xlabel("Month")
ax.set_ylabel("Visitors")
ax.set_ylim(0, 250)
ax.grid(axis="y", linestyle=":", alpha=0.5)
ax.legend()
fig.tight_layout()
plt.show()This example combines several of the techniques from this lecture into one complete visualization.
The chart starts by creating a Figure and an Axes object with plt.subplots(). The figsize argument controls the size of the figure.
The line is then customized with a blue colour, a thicker line, circular markers, and a descriptive label. The title and axis labels explain what the data represents.
The y-axis is limited from 0 to 250, giving enough space to display all the visitor values while keeping the scale easy to understand.
A horizontal dotted grid is added to make the visitor counts easier to estimate. Finally, ax.legend() identifies the data series and fig.tight_layout() adjusts the spacing so that labels and other chart elements fit neatly inside the figure.
- Use styles only when they improve identification.
- Include units in labels where appropriate.
- Use axis limits carefully so comparison remains fair.
fig.tight_layout()helps prevent labels from being clipped.- Use markers when individual data points need to be easy to identify.
- Keep colours consistent and avoid unnecessary visual decoration.
- Use grids lightly so they support rather than dominate the data.
Plot five days of study hours. Use a marker, a line colour, labels with units, a title, and a light horizontal grid. Decide whether the y-axis should begin at zero and explain why.
Try changing the line style and marker to see how they affect readability. Then create a second series representing another student's study hours and use a legend to distinguish the two datasets.
Finally, experiment with the axis limits and decide which settings make the comparison easiest to understand without exaggerating the differences between the values.
Project: Student Performance Visualization
In this project, you will use the Matplotlib skills from the previous lessons to build a complete data visualization. You will start with raw student scores, choose an appropriate chart, create the visualization, label it correctly, and interpret what the chart tells you. The goal is to learn how individual Matplotlib techniques work together to communicate information clearly.
01. Understand the Data
Before writing any plotting code, look at the data you want to visualize. We have a list of students and a list of their examination scores. Each student has one score, so we are interested in comparing separate categories.
This is an important step in data visualization: do not choose a chart simply because you know how to create it. Choose a chart based on the relationship you want the reader to understand.
A bar chart is a good choice because each student is an independent category and the height of each bar represents that student's score. A line chart would be less appropriate because the students do not represent a continuous sequence such as time.
We can therefore describe our visualization problem as: compare the final examination score of each student.
02. Build the Chart
import matplotlib.pyplot as plt
students = ["Aisha", "Ben", "Chen", "Dev", "Elena"]
scores = [88, 73, 94, 81, 90]
fig, ax = plt.subplots(figsize=(8, 4.5))
bars = ax.bar(students, scores)
ax.set_title("Final Examination Scores")
ax.set_xlabel("Student")
ax.set_ylabel("Score (%)")
ax.set_ylim(0, 100)
ax.bar_label(bars, padding=3, fmt="%d%%")
fig.tight_layout()
plt.show()Start by importing matplotlib.pyplot. We use the conventional name plt so that we can access Matplotlib's plotting functions easily.
The students list contains the categories that will appear along the x-axis. The scores list contains the numerical values that determine the height of the bars.
The two lists are connected by their positions. The first student, "Aisha", has the first score, 88. The second student, "Ben", has the second score, 73, and so on. Therefore, both lists must contain the same number of items.
plt.subplots() creates two important objects: a Figure, which represents the overall image, and an Axes object, which represents the area where the chart is drawn. We store them in fig and ax.
The main visualization is created with ax.bar(students, scores). Matplotlib creates one bar for every student and uses the corresponding score as its height.
Next, the chart is given a title and meaningful axis labels. The y-axis is labelled Score (%) because the values represent percentages. The limit is set from 0 to 100, which matches the natural range of examination percentages.
Finally, ax.bar_label() places the exact score above each bar. This means the reader can use the bar heights for quick comparison while also seeing the precise values.
03. Read and Interpret the Chart
Creating a chart is only part of the job. A useful visualization should allow us to answer questions about the data.
Looking at the results, Chen has the highest score at 94%, while Ben has the lowest score at 73%. Elena scored 90%, Aisha scored 88%, and Dev scored 81%.
The chart makes these comparisons easier because our eyes can compare the heights of the bars quickly. The data labels provide the exact values when precision is required.
This demonstrates an important principle: a visualization should make a question easier to answer. In this case, the question is about comparing student performance, so the differences between the bar heights are the main visual information.
Notice that the chart does not need unnecessary decoration. A clear title, meaningful labels, an appropriate scale, and readable values are enough to communicate the results effectively.
04. Extend the Project
Once the basic chart works, improve the project by asking new questions about the same data. For example, you could calculate the average score and compare individual students against that average.
You could also add a passing score and use a horizontal reference line to show the minimum required mark. This would make it immediately clear which students passed or failed.
Another useful extension is to collect scores for two subjects, such as Mathematics and Science. Instead of one bar for each student, you can create grouped bars so that the two subjects can be compared side by side.
If your dataset contains many students, a vertical bar chart may become crowded. In that situation, a horizontal bar chart can make long names easier to read. You can also sort the students by their scores when ranking is an important part of the analysis.
When extending the project, always return to the question you want the visualization to answer. Adding more elements is useful only when those elements help the reader understand the data.
- Understand the data before choosing a chart type.
- Keep related values aligned between your data lists.
- Use a descriptive title that explains what is being measured.
- Label axes clearly and include units where necessary.
- Use a sensible y-axis range that does not distort comparisons.
- Add exact data labels when they provide useful information.
- Keep the design simple and remove decoration that does not communicate information.
- Check the final chart from the reader's perspective: can its main message be understood quickly?
Create a new dataset containing Mathematics and Science scores for at least five students. Build a grouped bar chart that places the two subject scores beside each other for every student.
Your chart should include a descriptive title, labelled axes, a y-axis ranging from 0 to 100, and a legend identifying Mathematics and Science.
After creating the chart, study your results and identify which student has the highest combined performance and which student has the largest difference between the two subjects.
Show Change with Line Charts
Line charts are designed to show how values change across an ordered sequence. They are especially useful for time-based data because the position of each point and the line connecting the points reveal trends, increases, decreases, peaks, and sudden changes.
01. Understand What a Line Chart Shows
A line chart represents data points and connects them with lines. The x-axis contains an ordered variable, while the y-axis contains the measurement you want to observe.
The important idea is that the order of the x-axis matters. When the points are connected, the reader naturally interprets the movement from one point to the next as meaningful.
For example, suppose you record the temperature every day. Monday comes before Tuesday, and Tuesday comes before Wednesday. Connecting the measurements helps us see how temperature changed throughout the week.
This makes line charts particularly useful for time series such as daily temperatures, monthly revenue, website traffic, stock prices, or model training loss across epochs.
A line chart is not automatically appropriate just because your data contains numbers. If you are comparing unrelated categories such as the sales of five different products, a bar chart will usually communicate the comparison more clearly.
02. Create a Basic Line Chart
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
revenue = [24, 28, 31, 29, 35, 42]
fig, ax = plt.subplots()
ax.plot(months, revenue, marker="o")
ax.set_title("Monthly Revenue")
ax.set_xlabel("Month")
ax.set_ylabel("Revenue (thousands of dollars)")
ax.grid(axis="y", linestyle=":", alpha=0.5)
plt.show()The months list provides the ordered values for the x-axis, while revenue contains the corresponding measurements.
When we call ax.plot(months, revenue), Matplotlib creates a point for each pair of values and connects the points in order.
The first point represents January with a revenue value of 24. The next point represents February with a value of 28, and the process continues through June.
The marker="o" argument places a circular marker at each observation. This makes individual monthly measurements easier to identify.
The title and axis labels explain what the chart represents. Notice that the y-axis includes thousands of dollars. Without the unit, a reader would not know what the numbers mean.
The horizontal grid lines make it easier to estimate values. Because this chart is mainly concerned with the revenue values, the grid is applied only to the y-axis.
03. Understand Trends and Changes
One of the main strengths of a line chart is that it allows you to study direction and change.
If the line moves upward from one point to the next, the measured value increased. If it moves downward, the value decreased. A relatively flat section indicates that the value changed very little.
In the example, revenue increases from January through March, falls slightly in April, and then increases again during May and June.
The steepness of the line can also provide a visual indication of how quickly the value is changing. A sharp movement represents a larger change between observations, while a shallow movement represents a smaller change.
However, remember that the visual steepness depends partly on the axis scales. Always use the actual values and axis labels when making precise comparisons.
04. Compare Multiple Series
Line charts become especially useful when you want to compare how two or more measurements change across the same ordered x-axis.
Give every series a meaningful label and make the lines visually distinguishable. Different markers, line styles, or colours can help the reader identify each series.
online = [12, 16, 18, 20, 25, 29]
store = [10, 12, 13, 12, 15, 18]
fig, ax = plt.subplots()
ax.plot(months, online, marker="o", label="Online")
ax.plot(months, store, marker="s", linestyle="--", label="Store")
ax.set_title("Sales by Channel")
ax.set_xlabel("Month")
ax.set_ylabel("Sales (thousands)")
ax.legend()
ax.grid(axis="y", alpha=0.3)
plt.show()Both lines use the same months list, so their values can be compared month by month.
The first series represents online sales and uses circular markers. The second represents store sales and uses square markers with a dashed line.
The label argument gives each series a name. Calling ax.legend() then creates a legend using those names.
From the chart, you can compare not only the individual values but also the overall trends. For example, online sales generally increase more quickly than store sales in this dataset.
Be careful when adding many lines. If several series overlap, the chart can quickly become difficult to read. When the number of series becomes large, consider whether another visualization or multiple smaller charts would communicate the information better.
05. Work with Missing Data
Real datasets are often incomplete. A measurement may be unavailable because a sensor failed, a record was not collected, or information was not reported.
A missing value should not automatically be treated as zero. Zero means that the measured quantity was actually zero, while a missing value means that no measurement is available.
When working with numerical data, numpy.nan can be used to represent a missing value. Matplotlib can then leave a break in the plotted line instead of pretending that the missing measurement was zero.
This distinction is important because incorrectly replacing missing data with zero can create a false drop in the line and lead the reader to an incorrect conclusion.
06. Use Dates and Uneven Intervals Correctly
Time-based data is not always recorded at perfectly regular intervals. You might have measurements on January 1, January 5, and January 20 rather than every day.
When this happens, use actual date or time values on the x-axis whenever possible. This allows the chart to represent the amount of time between observations correctly.
If you replace real dates with equally spaced category names, the visual distance between points may no longer represent the actual elapsed time. For a time series, that can make the pattern misleading.
Matplotlib works with Python date and time objects, making it possible to create charts that represent real chronological spacing.
07. Choose the Right Scale
The axis range affects how a line chart appears. Matplotlib normally selects a suitable range automatically, but you can control it when necessary.
Do not change the scale simply to make a trend look more dramatic. The purpose of a visualization is to communicate the data accurately.
For example, if your measurements range from 0 to 100, showing only a very small section of the y-axis can make a relatively small difference appear much larger. Whether a non-zero baseline is appropriate depends on the data and the question being asked, but the selected range should always be clear to the reader.
- Use an ordered x-axis, especially when showing change over time.
- Make sure connecting the points has a meaningful interpretation.
- Label both axes and include units where appropriate.
- Use markers when there are relatively few observations.
- Avoid excessive markers when plotting dense datasets.
- Use legends when multiple series need to be identified.
- Do not replace missing measurements with zero unless zero is actually the correct value.
- Use real dates when uneven time intervals matter.
- Choose axis limits carefully and avoid scales that exaggerate the message.
Create a line chart showing a measurement across seven days. You could use daily temperature, website visitors, study hours, rainfall, or another dataset that changes over time.
Add a clear title, labels for both axes, appropriate units, markers, and a light horizontal grid.
After creating the chart, examine the data rather than only the appearance of the line. Identify the largest increase between two consecutive days, the largest decrease, and the overall trend.
As an additional challenge, create a second series and use a legend to compare the two trends.
Compare Categories with Bar Charts
Bar charts are one of the most useful ways to compare separate categories. Each bar represents a category, and its length or height represents a numerical value. They are commonly used for counts, scores, sales, survey results, enrolments, and other data where individual categories need to be compared.
01. Understand What a Bar Chart Shows
A bar chart compares discrete categories. Each category has a value, and Matplotlib represents that value using the size of a bar.
For example, if you want to compare how many students are learning different programming languages, each programming language is a category and the number of students is its value.
The important thing to remember is that the categories are separate. Python, Java, C++, and JavaScript are not points along a continuous scale. They are individual groups that we want to compare.
Bar charts are therefore different from line charts. A line chart emphasizes change across an ordered sequence, while a bar chart emphasizes comparison between categories.
02. Make a Vertical Bar Chart
import matplotlib.pyplot as plt
languages = ["Python", "Java", "C++", "JavaScript"]
students = [38, 24, 18, 31]
fig, ax = plt.subplots()
bars = ax.bar(languages, students)
ax.set_title("Students Enrolled by Language")
ax.set_xlabel("Programming language")
ax.set_ylabel("Number of students")
ax.set_ylim(0, 45)
ax.bar_label(bars, padding=3)
ax.grid(axis="y", linestyle=":", alpha=0.4)
plt.show()The languages list contains the category names, while students contains the corresponding values.
When we call ax.bar(languages, students), Matplotlib creates one bar for every category. The first language is matched with the first value, the second language with the second value, and so on.
The height of each bar represents the number of students. A taller bar means a larger value, while a shorter bar means a smaller value.
The ax.bar_label() method places the exact value above each bar. This is useful when the reader needs to know the actual number rather than estimating it from the axis.
The y-axis is limited to 45 using ax.set_ylim(0, 45). Notice that the lower limit is zero. Because the height of a bar represents its value, starting from zero makes the visual comparison honest.
03. Read and Interpret the Chart
Creating a chart is only part of the job. You should also be able to extract information from it.
In this example, Python has the highest enrolment with 38 students. JavaScript follows with 31, Java has 24, and C++ has 18.
You can also identify the difference between categories. Python has 7 more students than JavaScript, while JavaScript has 13 more students than C++.
This is one reason bar charts are effective: the reader can quickly identify the largest category, smallest category, and differences between categories.
04. Sort Categories When Order Helps
The order of categories can affect how quickly a reader understands a chart.
If the categories have a natural order, keep that order. For example, months should normally appear from January to December, and age groups should normally progress from younger to older.
However, if the categories do not have a natural order and your main goal is to show a ranking, sorting the bars can make the comparison much easier.
import matplotlib.pyplot as plt
languages = ["Python", "Java", "C++", "JavaScript"]
students = [38, 24, 18, 31]
ranking = sorted(zip(students, languages), reverse=True)
students, languages = zip(*ranking)
fig, ax = plt.subplots()
bars = ax.bar(languages, students)
ax.set_title("Programming Language Enrolment")
ax.set_xlabel("Programming language")
ax.set_ylabel("Number of students")
ax.bar_label(bars, padding=3)
ax.grid(axis="y", linestyle=":", alpha=0.4)
plt.show()The zip() function keeps each value connected to its category while the data is being sorted.
After sorting, the largest value appears first. This makes the chart read like a ranking, allowing the reader to identify the most popular category immediately.
Do not sort only the numerical list. If you change the order of the values without changing the corresponding categories, the chart can display incorrect information even though the Python code still runs.
05. Compare Two Values Per Category
Sometimes each category contains more than one value. For example, you may want to compare students' average scores in Term 1 and Term 2.
A grouped bar chart places related bars next to each other for every category. This lets the reader compare both the categories and the different series.
import numpy as np
import matplotlib.pyplot as plt
subjects = ["Math", "Science", "English"]
term_one = [76, 82, 79]
term_two = [84, 78, 88]
x = np.arange(len(subjects))
width = 0.35
fig, ax = plt.subplots()
ax.bar(x - width / 2, term_one, width, label="Term 1")
ax.bar(x + width / 2, term_two, width, label="Term 2")
ax.set_xticks(x, subjects)
ax.set_ylabel("Average score")
ax.set_title("Average Scores by Term")
ax.legend()
plt.show()Here, x provides a numerical position for each subject. The bars are then shifted slightly left and right so that the two series can sit beside each other.
The expression x - width / 2 places the Term 1 bars to the left of each subject position, while x + width / 2 places the Term 2 bars to the right.
The label argument gives each series a name, and ax.legend() displays those names so the reader knows which bars represent each term.
Grouped bars work well for two or three related series. Adding too many series can make the chart crowded and difficult to compare.
06. Choose the Right Bar Chart
There are several ways to use bars depending on the question you are trying to answer.
Use a simple bar chart when each category has one value. Use a grouped bar chart when you want to compare multiple related values for every category.
A horizontal bar chart is often better when category names are long or when you are presenting a ranking. You will use this type in the next lecture.
Choose the chart based on the structure of your data and the comparison you want the reader to make. Adding more bars or more visual effects does not automatically make a chart more informative.
- Begin the value axis at zero when bar length represents magnitude.
- Keep equal bar widths and consistent spacing.
- Keep categories and their values correctly matched.
- Use one scale when comparing values that belong to the same measurement.
- Avoid unnecessary 3D effects because they can distort the apparent size of bars.
- Use grouped bars when related series need direct comparison.
- Use stacked bars when the relationship between parts and a total is the main story.
- Do not add decorative effects that make the actual data harder to read.
Create a bar chart showing the number of books read by five classmates. Give each classmate a name and a numerical value.
Sort the values from highest to lowest, add a clear title, label the value axis, and display the exact count above each bar.
After creating the chart, identify who read the most books, who read the fewest, and calculate the difference between the two.
As an additional challenge, create a second set of values representing another month and turn your chart into a grouped bar chart.
Use Horizontal Bars for Long Labels
Horizontal bar charts are useful when the categories contain long names, when you have many categories, or when you want to present a clear ranking. Instead of making categories run across the bottom of the chart, horizontal bars place them along the vertical axis where they are usually easier to read.
01. Understand Horizontal Bar Charts
A horizontal bar chart displays one bar for each category, but the bars extend from left to right instead of from bottom to top.
The main idea is the same as a normal bar chart: the length of each bar represents a numerical value. The difference is the orientation of the axes.
In a vertical bar chart, categories are normally placed on the x-axis and values on the y-axis. In a horizontal bar chart, categories are placed on the y-axis and values are placed on the x-axis.
This orientation is particularly useful when category names are long. A label such as "Machine Learning and Artificial Intelligence" can be difficult to display underneath a vertical bar, but it can be written naturally beside a horizontal bar.
02. Create a Horizontal Bar Chart
import matplotlib.pyplot as plt
courses = ["Data Analysis", "Web Development", "Machine Learning", "Cyber Security"]
enrolments = [62, 48, 57, 39]
fig, ax = plt.subplots(figsize=(8, 4.5))
bars = ax.barh(courses, enrolments)
ax.set_title("Course Enrolments")
ax.set_xlabel("Number of students")
ax.set_ylabel("Course")
ax.bar_label(bars, padding=3)
ax.grid(axis="x", linestyle=":", alpha=0.45)
fig.tight_layout()
plt.show()The courses list contains the categories, while enrolments contains the number of students in each course.
The function ax.barh() creates the horizontal bars. The h in barh stands for horizontal.
Matplotlib matches the items in the two lists by position. Therefore, "Data Analysis" is associated with 62, "Web Development" with 48, and so on.
The value axis runs horizontally, so larger values produce longer bars. The category axis runs vertically, allowing the course names to be displayed beside the bars.
ax.bar_label() adds the exact enrolment value to each bar. This is useful when the reader needs both a quick visual comparison and the precise number.
The grid is placed on the x-axis because that is where the numerical values are measured. The grid helps the reader estimate the length of each bar.
03. Read the Chart
A chart is useful only if the reader can extract information from it. Look at the length of the bars and compare them with the values on the horizontal axis.
In this example, Data Analysis has the largest number of enrolments with 62 students. Machine Learning follows with 57, while Web Development has 48 and Cyber Security has 39.
The horizontal orientation makes the course names easy to scan. This becomes increasingly valuable as category names become longer or the number of categories increases.
Remember that bar charts represent comparisons using bar lengths. For an accurate comparison, the value axis should normally begin at zero. Starting the axis at a larger value can make relatively small differences appear much larger.
04. Create a Ranking
Horizontal bar charts are particularly effective for rankings. A ranking orders categories from highest to lowest or lowest to highest so that the reader can immediately identify their position.
Python's sorted() function can be used to arrange the data before plotting. When sorting multiple related values, it is important to keep each category connected to its corresponding value.
cities = ["Pune", "Delhi", "Bengaluru", "Mumbai"]
population = [7.4, 19.3, 13.6, 21.7]
ranking = sorted(zip(population, cities), reverse=True)
population, cities = zip(*ranking)
fig, ax = plt.subplots()
ax.barh(cities, population)
ax.invert_yaxis()
ax.set_xlabel("Population (millions)")
ax.set_title("Selected City Populations")
plt.show()The expression zip(population, cities) combines each population with its corresponding city. This is important because sorting the population list by itself would separate the numbers from the correct city names.
sorted(..., reverse=True) sorts the combined data from the largest population to the smallest.
After sorting, zip(*ranking) separates the sorted pairs back into two sequences: one for population and one for city names.
There is one more detail to understand. A horizontal bar chart normally places the first category at the bottom. Because our ranking is sorted from largest to smallest, the largest city would initially appear at the bottom.
ax.invert_yaxis() reverses the category axis, moving the first item to the top. The result reads naturally like a leaderboard: first place at the top, followed by the remaining positions.
05. Keep Related Data Together
When working with categories and numerical values, always make sure the relationship between them is preserved.
For example, if "Mumbai" has a population of 21.7, that value must remain attached to Mumbai after sorting or modifying the data.
A common beginner mistake is to sort one list without sorting the corresponding category list. The chart may still run without producing a Python error, but it will display incorrect information.
This is an important lesson beyond Matplotlib: correct data preparation is just as important as correct plotting code.
06. Vertical or Horizontal?
Both vertical and horizontal bar charts represent categorical comparisons. The best choice depends on the structure of the data and what you want the reader to notice.
Choose vertical bars when you have a small number of categories with short labels, or when the categories have a natural left-to-right order.
Choose horizontal bars when category names are long, when there are many categories, or when you are presenting a ranking. Horizontal bars often make it easier to scan names and compare the lengths of the bars.
For either orientation, keep the numerical axis starting at zero when the bar length is being used to represent magnitude. This ensures that the visual length of one bar can be compared fairly with another.
ax.barh(categories, values)creates horizontal bars.- The category axis is vertical and the value axis is horizontal.
- Horizontal bars are useful for long labels and many categories.
- Use
ax.invert_yaxis()when you want the first ranked item at the top. - Keep categories and their values correctly matched when sorting.
- Use
ax.bar_label()when exact values are useful to the reader. - Keep the numerical axis starting at zero when bar length represents magnitude.
Create a dataset containing five categories and numerical values. You could rank programming languages by popularity, subjects by student enrolment, products by sales, or another set of categories you are interested in.
Create a horizontal bar chart and sort the data from the largest value to the smallest. Put the highest-ranked category at the top using ax.invert_yaxis().
Add a descriptive title, a label for the value axis, and data labels showing the exact values.
Finally, explain why a horizontal bar chart is more suitable for your chosen data than a vertical bar chart.
Discover Relationships with Scatter Plots
Scatter plots help you investigate whether two numerical variables are related. Each point represents one observation, with its position determined by an x-value and a y-value. They are useful for finding patterns, clusters, unusual observations, and possible relationships in data.
01. Understand What a Scatter Plot Shows
A scatter plot displays individual observations as points on a coordinate system. One numerical variable is placed on the x-axis and another numerical variable is placed on the y-axis.
For example, imagine recording how many hours students study and the scores they receive in an exam. Each student provides one observation:
- The number of study hours becomes the x-value.
- The exam score becomes the y-value.
- One student is represented by one point.
When many observations are plotted together, the collection of points can reveal whether the variables appear to move together.
This makes scatter plots different from bar and line charts. A bar chart mainly compares categories, while a line chart emphasizes an ordered sequence. A scatter plot focuses on the relationship between two numerical variables.
02. Create a Basic Scatter Plot
import matplotlib.pyplot as plt
study_hours = [1, 2, 2.5, 3, 4, 5, 6, 7]
exam_scores = [48, 55, 58, 63, 68, 75, 82, 88]
fig, ax = plt.subplots()
ax.scatter(study_hours, exam_scores)
ax.set_title("Study Hours and Exam Scores")
ax.set_xlabel("Study hours")
ax.set_ylabel("Exam score")
ax.grid(alpha=0.3)
plt.show()The study_hours list contains the x-values, while exam_scores contains the corresponding y-values.
The call ax.scatter(study_hours, exam_scores) creates one point for every pair of values. The first study time is matched with the first exam score, the second with the second, and so on.
For example, the first observation is (1, 48). This means one hour of study corresponds to an exam score of 48 for that observation.
The position of a point therefore contains information about both variables at the same time.
03. Read the Pattern of the Points
The most important skill when using a scatter plot is learning to look for the overall pattern rather than focusing on one individual point.
If the points generally move upward from left to right, the variables have a positive association. Larger x-values tend to occur with larger y-values.
If the points generally move downward from left to right, the variables have a negative association. Larger x-values tend to occur with smaller y-values.
If the points appear scattered without a clear direction, there may be little or no obvious relationship between the variables.
In the study-hours example, the points generally move upward as study hours increase. This suggests a positive relationship in this particular dataset.
However, a scatter plot shows an association, not automatically a cause-and-effect relationship. A second factor could influence both variables, so you should avoid claiming that one variable directly causes another based only on the plot.
04. Understand Clusters and Outliers
Scatter plots can reveal more than just an overall direction. They can also show clusters and outliers.
A cluster occurs when several observations are concentrated in one region of the chart. A cluster may indicate that the data contains different groups or populations.
An outlier is an observation that is noticeably separated from the general pattern of the other points.
For example, if most students who study more hours have higher scores but one observation is far away from the rest, that point deserves investigation.
Do not automatically delete an unusual observation. First determine whether it represents a genuine situation, a measurement problem, or an error in the data.
05. Customize the Points
Scatter plots often contain many observations, so adjusting the appearance of the points can make the chart easier to read.
import matplotlib.pyplot as plt
study_hours = [1, 2, 2.5, 3, 4, 5, 6, 7]
exam_scores = [48, 55, 58, 63, 68, 75, 82, 88]
fig, ax = plt.subplots()
ax.scatter(
study_hours,
exam_scores,
s=70,
alpha=0.7,
edgecolors="black"
)
ax.set_title("Study Hours and Exam Scores")
ax.set_xlabel("Study hours")
ax.set_ylabel("Exam score")
ax.grid(alpha=0.3)
plt.show()The s argument controls the approximate size of the markers. Larger markers can make a small dataset easier to see.
The alpha argument controls transparency. This is particularly useful when many observations overlap. Transparent points can help reveal areas where observations are concentrated.
The edgecolors argument adds an outline around the points, which can make individual observations easier to distinguish.
Do not use customization simply for decoration. Every visual change should make the data easier to understand.
06. Compare Two Groups
Sometimes your observations belong to different groups. For example, you might want to compare the relationship between study hours and exam scores for two different classes.
You can plot the groups separately and give each one a meaningful label.
import matplotlib.pyplot as plt
class_a_hours = [1, 2, 3, 4, 5]
class_a_scores = [48, 55, 63, 70, 77]
class_b_hours = [1, 2, 3, 4, 5]
class_b_scores = [52, 60, 67, 74, 84]
fig, ax = plt.subplots()
ax.scatter(
class_a_hours,
class_a_scores,
label="Class A"
)
ax.scatter(
class_b_hours,
class_b_scores,
label="Class B"
)
ax.set_title("Study Hours and Exam Scores")
ax.set_xlabel("Study hours")
ax.set_ylabel("Exam score")
ax.legend()
ax.grid(alpha=0.3)
plt.show()Each call to ax.scatter() adds another group of observations to the same axes.
The label argument identifies each group, and ax.legend() displays those labels.
This allows you to compare whether the groups show similar patterns or whether one group tends to occupy a different region of the chart.
07. Scatter Plot or Another Chart?
Choosing the correct chart depends on the question you are asking.
Use a scatter plot when you have two numerical variables and want to investigate their relationship.
Use a bar chart when the main goal is comparing values across separate categories.
Use a line chart when the x-axis represents an ordered sequence, especially time, and the change from one observation to the next is important.
A scatter plot should not be used simply because both columns in your dataset contain numbers. The key question is whether you want to investigate how two numerical variables are related.
- Use
ax.scatter(x, y)to create a scatter plot. - Each point represents one observation.
- The x-axis and y-axis should normally contain numerical variables.
- An upward pattern suggests a positive association.
- A downward pattern suggests a negative association.
- A scattered pattern may indicate little or no obvious relationship.
- Look for clusters and unusual observations.
- An association does not automatically prove causation.
- Use transparency when many points overlap.
- Choose a scatter plot when the relationship between two numerical variables is the main question.
Create a scatter plot using two numerical variables. You could investigate study hours and exam scores, advertising spend and sales, distance travelled and fuel used, or another pair of measurements.
Plot at least eight observations and add a clear title and labels for both axes.
Study the resulting points and describe whether you can see a positive relationship, negative relationship, or no obvious relationship.
Identify any clusters or unusual observations you can see.
As an additional challenge, change the marker size and transparency to make your chart easier to read.
Understand Data Distribution with Histograms
A histogram shows how numerical data is distributed by grouping values into intervals called bins. Instead of displaying every individual observation, it helps you see where values are concentrated, how spread out they are, and whether the distribution has unusual patterns.
01. Understand What a Histogram Shows
A histogram is used to study the distribution of numerical data. It divides a range of values into intervals and counts how many observations fall inside each interval.
For example, suppose you have the exam scores of 100 students. Looking at all 100 scores individually can make it difficult to understand the overall pattern.
A histogram can group the scores into ranges such as 40โ49, 50โ59, 60โ69, and so on. The height of each bar then represents how many students fall within that range.
This allows you to quickly see whether most students scored around the middle, whether scores are spread across a wide range, or whether there are unusual concentrations of values.
A histogram looks similar to a bar chart, but the two charts answer different questions. A bar chart compares separate categories, while a histogram shows the distribution of a continuous numerical variable.
02. Create a Basic Histogram
import matplotlib.pyplot as plt
scores = [
42, 45, 48, 51, 52, 54, 55, 57, 58, 60,
61, 62, 64, 65, 66, 68, 69, 70, 72, 74,
75, 76, 78, 80, 82, 84, 86, 88, 91, 94
]
fig, ax = plt.subplots()
ax.hist(scores, bins=6, edgecolor="black")
ax.set_title("Distribution of Exam Scores")
ax.set_xlabel("Exam score")
ax.set_ylabel("Number of students")
plt.show()The scores list contains the numerical observations we want to study.
The ax.hist() method creates the histogram. The bins=6 argument tells Matplotlib to divide the range of scores into six intervals.
Matplotlib then counts how many observations fall into each interval and draws a bar for that group.
The x-axis represents the range of values, while the y-axis represents the frequency, or number of observations in each bin.
The edgecolor makes the boundaries between bins easier to see. This is especially useful when neighbouring bars have similar heights.
03. Understand Bins
The intervals used by a histogram are called bins. Choosing the number of bins is important because it affects how much detail the histogram shows.
Too few bins can hide important patterns. Many different values may be combined into large intervals, making the distribution appear overly simple.
Too many bins can make the histogram noisy. Small changes between neighbouring observations may create many tiny bars that are difficult to interpret.
There is no single number of bins that is correct for every dataset. The appropriate choice depends on the amount of data, the range of values, and the pattern you are trying to understand.
04. Control the Number of Bins
You can change the number of bins to examine the same dataset at different levels of detail.
import matplotlib.pyplot as plt
scores = [
42, 45, 48, 51, 52, 54, 55, 57, 58, 60,
61, 62, 64, 65, 66, 68, 69, 70, 72, 74,
75, 76, 78, 80, 82, 84, 86, 88, 91, 94
]
fig, ax = plt.subplots()
ax.hist(scores, bins=10, edgecolor="black")
ax.set_title("Exam Score Distribution")
ax.set_xlabel("Exam score")
ax.set_ylabel("Frequency")
plt.show()Changing bins=6 to bins=10 creates more intervals and therefore shows more detail.
When experimenting with bins, do not simply choose the histogram that looks the most interesting. Your goal is to represent the distribution clearly and avoid hiding or exaggerating patterns.
05. Recognize the Shape of a Distribution
A histogram allows you to describe the general shape of your data.
A distribution that has most observations concentrated around the centre may appear approximately symmetric. A distribution with a long tail toward larger values is often described as right-skewed, while a long tail toward smaller values is described as left-skewed.
You may also find more than one noticeable concentration of observations. This can produce a distribution with multiple peaks, sometimes called a multimodal distribution.
These patterns can provide useful clues about the data, but a histogram alone does not explain why the pattern exists. You need to investigate the underlying data and context to understand the reason.
06. Find Spread and Unusual Values
Histograms are also useful for understanding the spread of a dataset.
If values occupy a narrow range, the distribution is relatively concentrated. If values extend across a large range, the data is more spread out.
A histogram can also help reveal possible unusual values. For example, if almost all observations are concentrated between 50 and 90 but a few values occur far outside that range, those observations may deserve further investigation.
An unusual value is not necessarily an error. It could represent a genuine observation from the population. Always investigate unusual values before deciding what to do with them.
07. Histogram or Bar Chart?
Histograms and bar charts look similar because both use rectangular bars, but their purposes are different.
Use a bar chart when comparing separate categories, such as the number of students in different programming courses.
Use a histogram when studying the distribution of numerical measurements, such as exam scores, ages, heights, response times, or temperatures.
Another important difference is that histogram bins represent continuous ranges of numerical values. Because neighbouring bins represent adjacent intervals, the bars normally touch each other.
In a categorical bar chart, categories are separate groups, so gaps between bars are commonly used.
- Use
ax.hist()to create a histogram. - A histogram shows the distribution of numerical data.
- Bins divide the numerical range into intervals.
- The height of a bar usually represents the number of observations in that interval.
- Too few bins can hide useful patterns.
- Too many bins can make a distribution difficult to read.
- Histograms can reveal concentration, spread, skewness, clusters, and unusual values.
- Use a bar chart for categorical comparisons and a histogram for numerical distributions.
Create a histogram using at least 20 numerical observations. You could use exam scores, ages, heights, temperatures, reaction times, or another dataset.
Try the histogram with three different numbers of bins and compare the results.
Choose the bin setting that gives you the clearest view of the distribution. Add a title and labels for both axes.
Finally, describe where most of the values are concentrated, how widely the data is spread, and whether you can see any unusual values or interesting patterns.
Show Parts of a Whole with Pie Charts
Pie charts show how individual categories contribute to one complete total. Each slice represents a category, and the size of the slice represents its share of the whole. They are most useful when there are only a few categories and the parts form a meaningful total.
01. Understand What a Pie Chart Shows
A pie chart represents a complete quantity as a circle divided into slices. The entire circle represents 100% of the total, while each slice represents one category's contribution to that total.
For example, imagine tracking how a student spends their weekly study time. If the total study time is divided between Mathematics, Science, Programming, and English, a pie chart can show how much of the total belongs to each subject.
The larger the slice, the larger that category's share of the total.
Pie charts are therefore different from bar charts. A bar chart is usually better when the main goal is to compare exact values or rank many categories. A pie chart is useful when the main question is "How does this total break down?"
02. Create a Basic Pie Chart
import matplotlib.pyplot as plt
subjects = ["Mathematics", "Science", "Programming", "English"]
hours = [8, 6, 10, 4]
fig, ax = plt.subplots()
ax.pie(hours, labels=subjects)
ax.set_title("Weekly Study Time")
plt.show()The subjects list contains the categories, while hours contains the corresponding values.
The ax.pie() method converts the values into proportional slices. Matplotlib calculates each category's share of the total automatically.
In this example, the total study time is 28 hours. Programming accounts for 10 of those hours, so its slice is larger than the slices for subjects with fewer hours.
The labels argument places the category names around the chart so the reader can identify each slice.
03. Display Percentages
Sometimes the reader needs to know the percentage represented by each slice. Matplotlib can calculate and display these percentages using the autopct argument.
import matplotlib.pyplot as plt
subjects = ["Mathematics", "Science", "Programming", "English"]
hours = [8, 6, 10, 4]
fig, ax = plt.subplots()
ax.pie(
hours,
labels=subjects,
autopct="%1.1f%%"
)
ax.set_title("Weekly Study Time")
plt.show()The autopct argument tells Matplotlib to write the percentage inside each slice.
The format "%1.1f%%" displays the percentage with one decimal place. For example, a category representing approximately one quarter of the total could appear as 25.0%.
Using percentages is helpful when the purpose of the chart is to communicate each category's share rather than just its raw value.
04. Make the Chart Easier to Read
As with every visualization, the goal is clarity. A pie chart should make the relationship between the parts and the whole easy to understand.
If you have several small categories, the labels can begin to overlap or become difficult to follow. In such situations, a legend can provide a cleaner way to identify the slices.
import matplotlib.pyplot as plt
subjects = ["Mathematics", "Science", "Programming", "English"]
hours = [8, 6, 10, 4]
fig, ax = plt.subplots()
wedges, texts, autotexts = ax.pie(
hours,
autopct="%1.1f%%",
startangle=90
)
ax.legend(
wedges,
subjects,
title="Subjects",
loc="center left",
bbox_to_anchor=(1, 0.5)
)
ax.set_title("Weekly Study Time")
plt.show()The startangle=90 argument rotates the chart so that the first slice begins at the top. This can make the layout easier to read depending on the data.
The result returned by ax.pie() includes the slice objects. These are stored in wedges and then passed to ax.legend() so the legend can connect each slice with its category.
The bbox_to_anchor argument moves the legend outside the main plotting area. This gives the pie chart more space and prevents the category names from crowding the slices.
05. Show a Specific Slice
Sometimes one category is particularly important and you want to draw attention to it. Matplotlib provides the explode argument for this purpose.
import matplotlib.pyplot as plt
subjects = ["Mathematics", "Science", "Programming", "English"]
hours = [8, 6, 10, 4]
explode = [0, 0, 0.08, 0]
fig, ax = plt.subplots()
ax.pie(
hours,
labels=subjects,
autopct="%1.1f%%",
explode=explode,
startangle=90
)
ax.set_title("Weekly Study Time")
plt.show()The explode list controls how far each slice is separated from the centre. A value of 0 keeps a slice in its normal position, while a positive value moves it outward.
Here, the third value corresponds to Programming, so that slice is slightly separated from the rest.
Use this feature sparingly. If several slices are pulled away from the centre, the chart can become distracting rather than clearer.
06. Choose When to Use a Pie Chart
Pie charts work best when the categories represent parts of one meaningful total.
For example, a company's expenses divided into categories can be represented by a pie chart if all categories together represent the company's total expenses for the same period.
Pie charts become less effective when there are many categories. Comparing several similar-sized slices is difficult because humans are generally better at comparing lengths than angles.
If you need to compare ten categories precisely, a bar chart will usually be a better choice.
Also avoid using a pie chart when the values do not represent parts of the same whole. For example, comparing the populations of five unrelated cities is better suited to a bar chart because those populations are not components of one total.
07. Understand Percentages and Totals
Every slice in a pie chart represents a proportion of the total. The percentages of all slices should therefore add up to approximately 100%, allowing for small rounding differences.
For example, if three categories have values of 20, 30, and 50, the total is 100. Their shares are therefore 20%, 30%, and 50%.
This also means that the raw values do not have to already be percentages. Matplotlib can calculate the proportions from ordinary numerical values.
However, the data must represent comparable parts of the same whole. Mixing unrelated measurements, such as hours, kilometres, and kilograms, would not produce a meaningful pie chart.
- Use
ax.pie()to create a pie chart. - The complete circle represents 100% of the total.
- Each slice represents one category's share of that total.
- Use
autopctto display percentages. - Use
startangleto control the starting rotation. - Use
explodesparingly when one slice needs emphasis. - Pie charts work best with a small number of categories.
- All categories should represent parts of the same meaningful whole.
- Use a bar chart instead when precise comparison or ranking is more important.
Create a pie chart showing how a total is divided among four or five categories. You could use study time, a monthly budget, website traffic sources, project tasks, or another dataset where the categories form one meaningful whole.
Add category labels and display the percentage represented by each slice.
Use startangle=90 to rotate the chart and experiment with explode to highlight one important category.
Finally, explain why your data is suitable for a pie chart and identify the largest and smallest shares.
Create Multiple Plots in One Figure
Subplots allow you to place multiple charts inside a single figure. They are useful when you want to compare different datasets, views, or chart types without opening separate figures.
01. Understand What a Subplot Is
A subplot is an individual plot placed inside a larger Matplotlib figure. A figure can contain one subplot or many subplots arranged in rows and columns.
For example, you can create two charts side by side: one showing a line chart and another showing a bar chart. This makes it easier to compare related information in one view.
The main function used to create subplots is plt.subplots().
02. Create Two Subplots
The easiest way to create multiple plots is to use plt.subplots(). The first value specifies the number of rows and the second specifies the number of columns.
import matplotlib.pyplot as plt
days = ["Mon", "Tue", "Wed", "Thu", "Fri"]
temperatures = [24, 26, 25, 28, 27]
sales = [12, 18, 15, 22, 20]
fig, ax = plt.subplots(1, 2)
ax[0].plot(days, temperatures)
ax[0].set_title("Temperature")
ax[1].bar(days, sales)
ax[1].set_title("Sales")
plt.show()
Here, plt.subplots(1, 2) creates 1 row and 2 columns, giving us two plots next to each other.
The variable ax contains the two subplot axes. We access them using ax[0] and ax[1].
03. Arrange Subplots in Rows and Columns
You are not limited to two plots. You can arrange several subplots into a grid.
For example, plt.subplots(2, 2) creates 2 rows and 2 columns, giving you four plots.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr"]
values = [20, 35, 30, 45]
fig, ax = plt.subplots(2, 2)
ax[0, 0].plot(months, values)
ax[0, 0].set_title("Line Chart")
ax[0, 1].bar(months, values)
ax[0, 1].set_title("Bar Chart")
ax[1, 0].scatter(months, values)
ax[1, 0].set_title("Scatter Plot")
ax[1, 1].plot(months, values, marker="o")
ax[1, 1].set_title("Data Points")
plt.show()
When there are multiple rows and columns, each subplot is accessed using two indexes:
ax[row, column].
For example, ax[0, 0] means the first row and first column, while ax[1, 1] means the second row and second column.
04. Add Titles and Labels
Each subplot has its own axes, so you can give every chart its own title and axis labels.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr"]
sales = [120, 150, 180, 210]
fig, ax = plt.subplots(1, 2, figsize=(10, 4))
ax[0].plot(months, sales)
ax[0].set_title("Monthly Sales")
ax[0].set_xlabel("Month")
ax[0].set_ylabel("Sales")
ax[1].bar(months, sales)
ax[1].set_title("Sales Comparison")
ax[1].set_xlabel("Month")
ax[1].set_ylabel("Sales")
plt.show()
Notice that set_title(), set_xlabel(), and set_ylabel() are called on each individual axes object.
05. Control the Figure Size
When several plots are placed together, the default figure size may not provide enough space. You can use figsize to make the entire figure larger.
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2, 2, figsize=(10, 7))
ax[0, 0].plot([1, 2, 3, 4], [10, 15, 13, 20])
ax[0, 0].set_title("Chart 1")
ax[0, 1].bar(["A", "B", "C"], [12, 18, 10])
ax[0, 1].set_title("Chart 2")
ax[1, 0].scatter([1, 2, 3, 4], [8, 14, 11, 19])
ax[1, 0].set_title("Chart 3")
ax[1, 1].plot([1, 2, 3, 4], [5, 9, 7, 12])
ax[1, 1].set_title("Chart 4")
plt.show()
The figsize=(10, 7) argument controls the width and height of the complete figure in inches.
06. Improve Spacing with Tight Layout
Multiple plots can sometimes overlap, especially when they have long titles or axis labels. Matplotlib provides plt.tight_layout() to automatically adjust the spacing.
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2, 2, figsize=(9, 6))
ax[0, 0].plot([1, 2, 3], [10, 15, 12])
ax[0, 0].set_title("Temperature Over Three Days")
ax[0, 1].bar(["A", "B", "C"], [20, 35, 25])
ax[0, 1].set_title("Product Sales")
ax[1, 0].scatter([1, 2, 3], [5, 8, 6])
ax[1, 0].set_title("Student Scores")
ax[1, 1].plot([1, 2, 3], [30, 25, 40])
ax[1, 1].set_title("Monthly Visitors")
plt.tight_layout()
plt.show()
tight_layout() is especially useful when a figure contains several subplots because it reduces unnecessary overlap and improves readability.
07. Share an Axis
When two subplots use the same type of scale, you can share an axis. This is useful when comparing multiple datasets.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr"]
city_a = [20, 24, 27, 30]
city_b = [18, 22, 25, 28]
fig, ax = plt.subplots(2, 1, sharex=True, figsize=(8, 6))
ax[0].plot(months, city_a)
ax[0].set_title("City A")
ax[1].plot(months, city_b)
ax[1].set_title("City B")
ax[1].set_xlabel("Month")
plt.tight_layout()
plt.show()
sharex=True tells Matplotlib that both subplots should use the same x-axis. This makes comparisons between the charts easier.
08. When Should You Use Subplots?
Subplots are useful when several charts are related and should be viewed together.
- Compare different datasets.
- Show different views of the same data.
- Compare different chart types.
- Create dashboards and analytical reports.
- Keep related visualizations inside one figure.
Avoid adding too many subplots to one figure. A crowded figure can be harder to understand than several simple charts.
plt.subplots()creates a figure and one or more axes.plt.subplots(1, 2)creates two subplots in one row.plt.subplots(2, 2)creates four subplots in a 2-by-2 grid.- Use
ax[0]for a simple one-row or one-column collection of axes. - Use
ax[row, column]when working with a grid. figsizecontrols the size of the complete figure.plt.tight_layout()helps prevent overlapping elements.- Subplots are most useful when the charts are related and need to be compared.
Create a figure containing four subplots arranged in a 2-by-2 grid.
Use the same dataset to create a line chart, bar chart, scatter plot, and another chart of your choice.
Give every subplot a meaningful title and at least one axis label.
Use figsize to make the figure easy to read and finish with plt.tight_layout().
Compare Multiple Data Series with Line Charts
A single line can show how one set of values changes, but real datasets often contain several related series. Matplotlib allows you to draw multiple lines on the same chart so you can compare trends, patterns, and changes between different groups.
01. Understand Multiple Data Series
A data series is a related collection of values that represents one variable, group, or category. For example, if you are tracking sales for two products, each product can be represented by its own data series.
When multiple series use the same x-axis, you can plot them on the same axes. This makes it easier to compare how they change over the same period.
02. Plot Two Lines
To create multiple lines, call ax.plot() once for each data series.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May"]
product_a = [120, 150, 170, 160, 190]
product_b = [100, 130, 145, 175, 180]
fig, ax = plt.subplots()
ax.plot(months, product_a)
ax.plot(months, product_b)
ax.set_title("Monthly Product Sales")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
plt.show()
Both lines are drawn on the same axes. The first call plots product_a, while the second call plots product_b.
Because both series use the same months values, their positions can be compared directly.
03. Add Labels with a Legend
When a chart contains more than one line, the reader needs to know which line belongs to which dataset.
Use the label parameter with ax.plot(), then call ax.legend().
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May"]
product_a = [120, 150, 170, 160, 190]
product_b = [100, 130, 145, 175, 180]
fig, ax = plt.subplots()
ax.plot(months, product_a, label="Product A")
ax.plot(months, product_b, label="Product B")
ax.set_title("Monthly Product Sales")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
ax.legend()
plt.show()The legend connects each line to its corresponding data series. This is especially important when several lines have similar shapes or cross each other.
04. Customize Each Data Series
You can give each series its own visual properties. For example, markers can make individual data points easier to identify, while line styles can help distinguish different series.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May"]
website_a = [20, 28, 35, 42, 50]
website_b = [15, 24, 30, 38, 46]
fig, ax = plt.subplots()
ax.plot(
months,
website_a,
marker="o",
linestyle="-",
label="Website A"
)
ax.plot(
months,
website_b,
marker="s",
linestyle="--",
label="Website B"
)
ax.set_title("Website Visitors")
ax.set_xlabel("Month")
ax.set_ylabel("Visitors")
ax.legend()
plt.show()The first series uses circular markers and a solid line. The second uses square markers and a dashed line. Using different line styles or markers can make a chart easier to understand, especially when it may be viewed without relying on color.
05. Plot More Than Two Series
You can plot three or more data series on the same axes. The important rule is that the chart should remain readable.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May"]
north = [120, 135, 150, 165, 180]
south = [100, 125, 140, 155, 170]
west = [90, 110, 130, 145, 160]
fig, ax = plt.subplots()
ax.plot(months, north, marker="o", label="North")
ax.plot(months, south, marker="o", label="South")
ax.plot(months, west, marker="o", label="West")
ax.set_title("Regional Sales")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
ax.legend()
plt.show()
Each call to ax.plot() adds another series to the same axes. The legend identifies all three series.
06. Compare Trends, Not Just Values
Multiple-line charts are particularly useful for identifying trends. Look for whether a series is increasing, decreasing, remaining stable, or changing direction.
You can also compare how quickly different series change. For example, two products might both increase in sales, but one may grow faster than the other.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
online = [40, 45, 52, 60, 72, 85]
store = [70, 68, 72, 75, 78, 80]
fig, ax = plt.subplots()
ax.plot(months, online, marker="o", label="Online")
ax.plot(months, store, marker="o", label="Store")
ax.set_title("Monthly Sales by Channel")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
ax.legend()
plt.show()In this example, both series increase overall, but the online series grows more quickly. The store series changes more gradually.
07. Use a Common X-Axis
Multiple series are easiest to compare when they use the same x-axis values. Each x value should normally correspond to the matching value in every series.
For example, if the x-axis contains five months, each data series should contain five corresponding values.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr"]
students = [42, 48, 55, 61]
teachers = [8, 9, 10, 11]
fig, ax = plt.subplots()
ax.plot(months, students, marker="o", label="Students")
ax.plot(months, teachers, marker="s", label="Teachers")
ax.set_title("School Population")
ax.set_xlabel("Month")
ax.set_ylabel("Count")
ax.legend()
plt.show()
Each position in the lists corresponds to the same month. For example, students[0] and teachers[0] both represent January.
08. Avoid Overcrowding the Chart
Although Matplotlib can display many lines, adding too many series can make the chart difficult to read.
If you have many categories, consider whether all of them need to appear on the same chart. You may be better off using separate charts, subplots, or another visualization such as a bar chart.
- A data series is a related collection of values representing one variable or group.
- Use
ax.plot()multiple times to draw multiple lines. - Use
labelandax.legend()to identify each series. - Markers and line styles can make different series easier to distinguish.
- Multiple-line charts are useful for comparing trends over the same x-axis.
- Each series should normally contain a value corresponding to every x-axis position.
- Too many lines can make a chart confusing, so keep comparisons focused.
Create a multiple-line chart comparing the monthly sales of three products. Use six months of data and give each product its own line. Add a meaningful title, x-axis label, y-axis label, markers, and a legend. Then examine your chart and identify which product increased the most from the first month to the last month.
Control Grids, Ticks, and Axes
A chart is easier to understand when its axes, tick marks, and grid lines are clearly organized. Matplotlib gives you precise control over these elements so you can make charts easier to read without changing the underlying data.
01. Understand Ticks and Axes
The x-axis and y-axis provide the coordinate system of a chart. They show where values are located and help the reader understand the scale of the data.
Ticks are the small marks and labels placed along an axis. For example, an axis might have tick labels such as 0, 20, 40, 60, and 80.
Grid lines extend from selected tick positions across the plotting area. They help the reader estimate values from the chart.
02. Add Grid Lines
You can add grid lines with ax.grid(). By default, this affects the major grid lines on both axes.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May"]
sales = [120, 150, 135, 180, 210]
fig, ax = plt.subplots()
ax.plot(months, sales, marker="o")
ax.set_title("Monthly Sales")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
ax.grid()
plt.show()The grid makes it easier to compare each point with the values on the y-axis.
03. Control Which Axis Gets a Grid
Sometimes you only need horizontal or vertical grid lines. Use the axis parameter to control this.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May"]
sales = [120, 150, 135, 180, 210]
fig, ax = plt.subplots()
ax.plot(months, sales, marker="o")
ax.grid(axis="y")
ax.set_title("Monthly Sales")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
plt.show()
Using axis="y" creates horizontal grid lines based on the y-axis ticks. This is useful for comparing the heights of values in a line or bar chart.
You can also use axis="x" when you only want vertical grid lines.
04. Change the Tick Positions
Matplotlib normally chooses tick positions automatically. However, you can specify exactly where ticks should appear with set_xticks() and set_yticks().
import matplotlib.pyplot as plt
days = [1, 2, 3, 4, 5, 6, 7]
temperatures = [22, 24, 23, 27, 29, 28, 30]
fig, ax = plt.subplots()
ax.plot(days, temperatures, marker="o")
ax.set_xticks([1, 2, 3, 4, 5, 6, 7])
ax.set_yticks([20, 22, 24, 26, 28, 30])
ax.set_title("Weekly Temperature")
ax.set_xlabel("Day")
ax.set_ylabel("Temperature")
ax.grid(axis="y")
plt.show()
set_xticks() controls the positions of ticks on the x-axis, while set_yticks() controls the positions on the y-axis.
05. Change Tick Labels
Tick positions and tick labels are separate concepts. You can choose where a tick appears and what text should be displayed at that position.
import matplotlib.pyplot as plt
days = [1, 2, 3, 4, 5]
sales = [25, 40, 35, 50, 60]
fig, ax = plt.subplots()
ax.plot(days, sales, marker="o")
ax.set_xticks([1, 2, 3, 4, 5])
ax.set_xticklabels(["Mon", "Tue", "Wed", "Thu", "Fri"])
ax.set_title("Weekly Sales")
ax.set_xlabel("Day")
ax.set_ylabel("Sales")
plt.show()
Here, the actual x values are numbers from 1 to 5, but the displayed labels are the day names.
This technique is useful when your data uses numeric positions but the reader should see meaningful category names.
06. Control the Axis Limits
Matplotlib automatically chooses the visible range of an axis. You can override this using set_xlim() and set_ylim().
import matplotlib.pyplot as plt
days = [1, 2, 3, 4, 5]
sales = [25, 40, 35, 50, 60]
fig, ax = plt.subplots()
ax.plot(days, sales, marker="o")
ax.set_xlim(1, 5)
ax.set_ylim(0, 70)
ax.set_title("Weekly Sales")
ax.set_xlabel("Day")
ax.set_ylabel("Sales")
ax.grid(axis="y")
plt.show()
set_xlim() controls the visible minimum and maximum values of the x-axis. set_ylim() does the same for the y-axis.
Axis limits should be chosen carefully. Do not use limits that hide important data or make a comparison misleading.
07. Show Minor Ticks and Minor Grid Lines
Axes can have major ticks and minor ticks. Major ticks are the primary divisions, while minor ticks provide smaller divisions between them.
Minor ticks can be enabled with minorticks_on(). You can then create a separate grid for the minor ticks.
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [10, 18, 15, 22, 28]
fig, ax = plt.subplots()
ax.plot(x, y, marker="o")
ax.minorticks_on()
ax.grid(which="major", axis="y")
ax.grid(which="minor", axis="y")
ax.set_title("Values with Minor Ticks")
ax.set_xlabel("X")
ax.set_ylabel("Value")
plt.show()
The which parameter specifies whether the grid should apply to "major" or "minor" ticks.
Minor ticks are useful when the reader needs a more detailed scale, but they should not be added unnecessarily because too many lines can make a chart visually crowded.
08. Move Tick Labels
Tick labels can sometimes overlap or become difficult to read. You can rotate them with tick_params().
import matplotlib.pyplot as plt
months = [
"January",
"February",
"March",
"April",
"May",
"June"
]
sales = [120, 150, 135, 180, 210, 230]
fig, ax = plt.subplots()
ax.bar(months, sales)
ax.tick_params(axis="x", labelrotation=45)
ax.set_title("Monthly Sales")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
plt.tight_layout()
plt.show()
tick_params() provides control over tick appearance. In this example, the x-axis labels are rotated by 45 degrees so that the month names have more room.
09. Control the Spines
The visible borders around a plotting area are called spines. Matplotlib normally displays four spines: top, bottom, left, and right.
You can access individual spines through ax.spines.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May"]
sales = [120, 150, 135, 180, 210]
fig, ax = plt.subplots()
ax.plot(months, sales, marker="o")
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.set_title("Monthly Sales")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
ax.grid(axis="y")
plt.show()Removing unnecessary spines can create a cleaner chart. However, do not remove visual elements simply for decoration if doing so makes the chart harder to interpret.
10. Put It All Together
Grid lines, ticks, and axis limits work together. A well-designed chart should provide enough scale information for the reader without becoming crowded.
import matplotlib.pyplot as plt
days = [1, 2, 3, 4, 5, 6, 7]
sales = [35, 42, 38, 50, 56, 61, 68]
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(days, sales, marker="o", label="Sales")
ax.set_title("Weekly Sales")
ax.set_xlabel("Day")
ax.set_ylabel("Sales")
ax.set_xticks(days)
ax.set_xticklabels([
"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
])
ax.set_ylim(0, 80)
ax.grid(axis="y")
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.legend()
plt.tight_layout()
plt.show()This example combines several techniques: custom tick labels, a controlled y-axis range, horizontal grid lines, selected spines, and a legend.
- Axes provide the coordinate system used to read a chart.
- Ticks mark positions along an axis and usually have labels.
- Use
ax.grid()to add grid lines. - Use
set_xticks()andset_yticks()to control tick positions. - Use
set_xticklabels()andset_yticklabels()when you need custom displayed labels. - Use
set_xlim()andset_ylim()to control the visible axis range. minorticks_on()enables minor ticks.tick_params()provides additional control over tick appearance.- Spines are the borders around the plotting area.
- Good axis design should improve readability without hiding or distorting the data.
Create a line chart showing values for seven days of the week. Replace the numeric x-axis values with day names, add horizontal grid lines, set a sensible y-axis range, and rotate the x-axis labels if necessary. Remove the top and right spines and add a clear title and axis labels.
Control Figure Size and Resolution
A chart can contain correct data but still look poor if it is too small, blurry, or difficult to read. Matplotlib lets you control the size of a figure and the resolution of the output so your charts are suitable for screens, presentations, reports, and printed documents.
01. Understand Figure Size
A figure is the complete area that contains your chart. Its size is controlled with the figsize parameter.
The value of figsize is written as (width, height) and is measured in inches.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May"]
sales = [120, 150, 135, 180, 210]
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(months, sales, marker="o")
ax.set_title("Monthly Sales")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
plt.show()
In this example, figsize=(10, 5) creates a figure that is 10 inches wide and 5 inches tall.
02. Change the Width and Height
Changing the width and height allows you to choose a shape that fits the content of your chart. A wide chart can be useful for time-series data, while a taller figure may work better when there are many categories.
import matplotlib.pyplot as plt
categories = ["Python", "Java", "C++", "JavaScript"]
students = [80, 65, 50, 72]
fig, ax = plt.subplots(figsize=(7, 6))
ax.bar(categories, students)
ax.set_title("Programming Languages")
ax.set_xlabel("Language")
ax.set_ylabel("Students")
plt.tight_layout()
plt.show()
The important idea is that figsize controls the size of the entire figure, not the amount of data being displayed.
03. Understand DPI
DPI means dots per inch. In Matplotlib, it describes the resolution used to render a figure.
A higher DPI generally produces more pixels for the same physical figure size. This can make saved images sharper, especially when they are printed or displayed at a larger size.
You can specify DPI when creating the figure with the dpi parameter.
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [10, 15, 13, 20, 25]
fig, ax = plt.subplots(
figsize=(8, 5),
dpi=120
)
ax.plot(x, y, marker="o")
ax.set_title("Values Over Time")
ax.set_xlabel("X")
ax.set_ylabel("Value")
plt.show()Here, the figure has a physical size of 8 by 5 inches and is rendered at 120 DPI.
04. Understand Figure Size and Pixels
Figure size and DPI work together to determine the pixel dimensions of a raster image. The approximate relationship is:
pixels = inches × DPI
For example, a figure that is 8 inches wide at 100 DPI produces approximately 800 pixels in width. At 200 DPI, the same 8-inch width produces approximately 1600 pixels.
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(8, 5), dpi=100)
ax.plot([1, 2, 3, 4], [10, 20, 15, 25])
ax.set_title("Figure Dimensions")
plt.show()In this example, the figure is approximately 800 × 500 pixels when rendered as a raster image at that DPI.
05. Set DPI When Saving
The DPI used to display a figure and the DPI used when saving it do not have to be the same.
You can specify the output resolution in savefig().
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May"]
sales = [120, 150, 135, 180, 210]
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(months, sales, marker="o")
ax.set_title("Monthly Sales")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
plt.tight_layout()
plt.savefig("monthly_sales.png", dpi=300)
plt.show()
The dpi=300 argument tells Matplotlib to save the PNG at 300 DPI.
Higher-resolution output is often useful for printing and documents where image quality matters.
06. Use Bounding Boxes When Saving
Sometimes a saved figure contains extra whitespace around the chart. The bbox_inches="tight" option can reduce unnecessary space around the figure.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr"]
sales = [100, 140, 125, 180]
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(months, sales, marker="o")
ax.set_title("Monthly Sales")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
plt.tight_layout()
plt.savefig(
"sales_chart.png",
dpi=300,
bbox_inches="tight"
)
plt.show()
bbox_inches="tight" asks Matplotlib to fit the saved output closely around the figure's visible content.
07. Choose the Right Resolution
The best DPI depends on where the chart will be used. Higher DPI is not always necessary.
- Screen display: a moderate DPI is usually enough.
- Presentations: use enough resolution for the image to remain sharp when displayed.
- Reports: higher resolution can be useful when the figure will be inserted into a document.
- Printing: high-resolution raster output is often appropriate.
Increasing DPI also increases the number of pixels in a raster image, which can increase file size and processing requirements.
08. Size Is Not the Same as Resolution
Figure size and resolution solve different problems.
Figure size determines the physical dimensions of the figure. DPI determines how densely the image is rendered when using raster output.
A large figure with low DPI can still look pixelated when saved as an image. A small figure with very high DPI can be sharp but may not provide enough physical space for labels and other chart elements.
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [12, 18, 15, 22, 28]
fig, ax = plt.subplots(
figsize=(10, 6),
dpi=120
)
ax.plot(x, y, marker="o")
ax.set_title("Size and Resolution")
ax.set_xlabel("X")
ax.set_ylabel("Value")
plt.tight_layout()
plt.show()09. Save Different Output Formats
Matplotlib can save figures in several formats. Common choices include PNG, JPEG, PDF, and SVG.
Raster formats such as PNG are made from pixels, so DPI affects their resolution. Vector formats such as SVG and PDF can preserve scalable graphical elements without depending on a fixed pixel resolution in the same way.
import matplotlib.pyplot as plt
x = [1, 2, 3, 4]
y = [10, 15, 13, 20]
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x, y, marker="o")
ax.set_title("Exporting a Chart")
ax.set_xlabel("X")
ax.set_ylabel("Value")
plt.tight_layout()
plt.savefig("chart.png", dpi=300)
plt.savefig("chart.svg")
plt.savefig("chart.pdf")
plt.show()The appropriate format depends on how the image will be used. PNG is convenient for general image use, while SVG and PDF are useful when scalable graphics are important.
10. Create a Professional Output
When preparing a chart for a website, presentation, or report, think about both its physical size and its output quality.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
revenue = [120, 145, 138, 175, 190, 220]
fig, ax = plt.subplots(
figsize=(10, 6),
dpi=120
)
ax.plot(months, revenue, marker="o")
ax.set_title("Monthly Revenue")
ax.set_xlabel("Month")
ax.set_ylabel("Revenue")
ax.grid(axis="y")
plt.tight_layout()
plt.savefig(
"monthly_revenue.png",
dpi=300,
bbox_inches="tight"
)
plt.show()This example creates a reasonably sized working figure and then saves a high-resolution PNG for use outside Matplotlib.
figsize=(width, height)controls the figure's physical size in inches.- DPI means dots per inch and controls the rendering density of raster output.
- For raster images, pixel dimensions are approximately the figure dimensions multiplied by DPI.
- Use
savefig()to save a figure to an image or document format. - Use
dpi=300when high-resolution raster output is appropriate. bbox_inches="tight"can reduce unnecessary whitespace around saved content.- Figure size and resolution are different concepts and should be chosen independently.
- SVG and PDF can be useful when scalable vector output is required.
- Higher DPI is not automatically better; it can increase image dimensions and file size.
Create a line chart containing six months of data.
Set the figure size to (10, 6), add a title and axis labels, and include horizontal grid lines.
Save the chart as a PNG using dpi=300 and bbox_inches="tight".
Then save the same chart as an SVG file and compare the two output formats.
Add Annotations to Your Charts
Annotations allow you to draw attention to important information in a chart. You can add text, arrows, and highlighted points to explain unusual values, important events, peaks, or other features of your data.
01. Understand Annotations
An annotation is an explanation added directly to a chart. Instead of making the reader guess why a particular point is important, you can label it with text or an arrow.
For example, if a line chart contains the highest sales value of the year, an annotation can point to that value and explain that it was the company's best month.
Matplotlib provides the ax.annotate() method for creating annotations.
02. Add Simple Annotation Text
The simplest annotation contains text and a position on the chart.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May"]
sales = [120, 150, 135, 180, 210]
fig, ax = plt.subplots()
ax.plot(months, sales, marker="o")
ax.annotate(
"Highest sales",
xy=("May", 210)
)
ax.set_title("Monthly Sales")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
plt.show()
The xy argument specifies the position where the annotation is placed. In this example, it points to the May value of 210.
03. Add an Arrow
An annotation becomes more useful when an arrow connects the text to the exact point being explained.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May"]
sales = [120, 150, 135, 180, 210]
fig, ax = plt.subplots()
ax.plot(months, sales, marker="o")
ax.annotate(
"Highest sales",
xy=("May", 210),
xytext=("Mar", 220),
arrowprops={"arrowstyle": "->"}
)
ax.set_title("Monthly Sales")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
plt.show()
The xy argument identifies the point being annotated, while xytext specifies where the annotation text should appear.
The arrowprops dictionary controls the arrow. The "->" arrow style creates an arrow pointing toward the selected data point.
04. Move the Annotation Text
The annotation text does not have to be directly next to the data point. You can move it to a clearer position using xytext.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
sales = [100, 120, 115, 145, 180, 210]
fig, ax = plt.subplots()
ax.plot(months, sales, marker="o")
ax.annotate(
"Strong growth",
xy=("Jun", 210),
xytext=("Apr", 190),
arrowprops={"arrowstyle": "->"}
)
ax.set_title("Sales Growth")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
plt.show()Moving the text away from the point can prevent the annotation from covering the data or other chart elements.
05. Annotate a Specific Point
Annotations are particularly useful when you want to explain a specific value in a dataset.
import matplotlib.pyplot as plt
days = ["Mon", "Tue", "Wed", "Thu", "Fri"]
temperatures = [24, 27, 25, 32, 29]
fig, ax = plt.subplots()
ax.plot(days, temperatures, marker="o")
ax.annotate(
"Peak temperature",
xy=("Thu", 32),
xytext=("Tue", 31),
arrowprops={"arrowstyle": "->"}
)
ax.set_title("Weekly Temperature")
ax.set_xlabel("Day")
ax.set_ylabel("Temperature")
plt.show()The annotation identifies Thursday as the point with the highest temperature in this dataset.
06. Add a Text Box
You can use the bbox argument to place the annotation inside a box. This can make important information stand out from the rest of the chart.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May"]
revenue = [100, 130, 125, 170, 220]
fig, ax = plt.subplots()
ax.plot(months, revenue, marker="o")
ax.annotate(
"Major increase",
xy=("May", 220),
xytext=("Mar", 200),
arrowprops={"arrowstyle": "->"},
bbox={"boxstyle": "round,pad=0.4"}
)
ax.set_title("Monthly Revenue")
ax.set_xlabel("Month")
ax.set_ylabel("Revenue")
plt.show()
The bbox argument creates a box around the annotation text. The boxstyle controls the shape and spacing of the box.
07. Annotate Multiple Points
You can add more than one annotation to the same chart. This is useful when several events or values need explanation.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
sales = [100, 125, 110, 150, 175, 160]
fig, ax = plt.subplots()
ax.plot(months, sales, marker="o")
ax.annotate(
"First peak",
xy=("Feb", 125),
xytext=("Jan", 145),
arrowprops={"arrowstyle": "->"}
)
ax.annotate(
"Highest value",
xy=("May", 175),
xytext=("Mar", 195),
arrowprops={"arrowstyle": "->"}
)
ax.set_title("Important Sales Points")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
plt.show()
Each call to ax.annotate() creates a separate annotation. Keep the number of annotations limited so the chart remains easy to read.
08. Add Text Without an Arrow
Sometimes you only need to place explanatory text on the chart. In that case, ax.text() can be simpler than ax.annotate().
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr"]
sales = [100, 140, 130, 180]
fig, ax = plt.subplots()
ax.plot(months, sales, marker="o")
ax.text(
"Mar",
150,
"Sales recovered",
)
ax.set_title("Sales Trend")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
plt.show()
ax.text() places text at a specified coordinate but does not automatically create an arrow pointing to another coordinate.
09. Choose Between text() and annotate()
Both methods place text on a chart, but they are designed for slightly different purposes.
ax.text()is useful for placing standalone text at a specific position.ax.annotate()is useful when text needs to explain or point toward a particular location.- Use an arrow when the relationship between the text and the data point needs to be obvious.
10. Use Annotations Carefully
Annotations should add information rather than create unnecessary clutter. A chart with too many labels and arrows can become harder to understand.
Good annotations usually identify something meaningful, such as a peak, sudden change, unusual value, important event, or significant observation.
- An annotation adds explanatory information directly to a chart.
ax.annotate()is used for annotations.xyspecifies the point being explained.xytextspecifies where the annotation text is placed.arrowpropscontrols the arrow connecting the text to the point.bboxcan place the annotation inside a text box.ax.text()is useful for placing text without an annotation arrow.- Annotations should highlight meaningful information without overcrowding the chart.
Create a line chart containing six months of sales data. Find the month with the highest sales and annotate that point with the text "Highest Sales". Add an arrow pointing to the data point and place the text away from the point so that it does not cover the line. Then add a second annotation explaining another interesting point in your dataset.
Save and Export Your Matplotlib Charts
Learn how to save Matplotlib charts as image files and choose the right format, resolution, and settings for different uses.
01. Understand Saving a Chart
Creating a chart with Matplotlib displays it on the screen, but you may also want to save it as a file.
Matplotlib uses plt.savefig() or fig.savefig() to export a chart.
Saving a chart is useful when you want to use it in a website, document, presentation, report, or social media post.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
months = ["Jan", "Feb", "Mar", "Apr"]
sales = [120, 150, 180, 160]
ax.plot(months, sales)
ax.set_title("Monthly Sales")
fig.savefig("sales_chart.png")
plt.show()
The chart is saved as sales_chart.png in the current working directory.
02. Save as a PNG Image
PNG is one of the most useful formats for charts. It works well for websites, applications, documents, and general image sharing.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
days = ["Mon", "Tue", "Wed", "Thu", "Fri"]
visitors = [120, 180, 150, 220, 260]
ax.plot(days, visitors, marker="o")
ax.set_title("Website Visitors")
ax.set_xlabel("Day")
ax.set_ylabel("Visitors")
fig.savefig("visitors.png")
plt.show()
The file extension tells Matplotlib which format to use. Here, .png creates a PNG image.
03. Save as a JPG Image
Matplotlib can also export charts as JPEG images. JPEG can produce smaller files, although PNG is often a better choice for charts because it preserves sharp lines and text.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
products = ["A", "B", "C", "D"]
sales = [45, 70, 55, 90]
ax.bar(products, sales)
ax.set_title("Product Sales")
fig.savefig("product_sales.jpg")
plt.show()
The .jpg extension tells Matplotlib to save the chart as a JPEG image.
04. Save as PDF or SVG
Matplotlib also supports vector formats such as PDF and SVG. Vector graphics can be scaled to different sizes without becoming pixelated.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
scores = [52, 68, 75, 83, 91]
ax.plot(scores, marker="o")
ax.set_title("Student Scores")
fig.savefig("scores.pdf")
fig.savefig("scores.svg")
plt.show()PDF is useful for reports and documents, while SVG is especially useful for websites and applications that support scalable graphics.
05. Control the Image Resolution
When saving raster images such as PNG, you can control the resolution using dpi.
DPI means dots per inch.
A higher DPI can produce a sharper image, especially when the image will be printed.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
months = ["Jan", "Feb", "Mar", "Apr", "May"]
revenue = [200, 240, 280, 260, 320]
ax.plot(months, revenue, marker="o")
ax.set_title("Monthly Revenue")
fig.savefig("revenue.png", dpi=300)
plt.show()
A value such as dpi=300 is commonly useful when a chart needs to be exported at high quality.
06. Remove Extra White Space
Sometimes a saved chart contains more empty space around the edges than you want.
Use bbox_inches="tight" to make the saved output fit more closely around the figure contents.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
categories = ["Python", "Java", "C++", "JavaScript"]
students = [85, 72, 64, 78]
ax.bar(categories, students)
ax.set_title("Programming Languages")
ax.set_ylabel("Students")
fig.savefig(
"languages.png",
dpi=300,
bbox_inches="tight"
)
plt.show()This is particularly useful when exporting charts that contain labels, legends, or annotations close to the edges.
07. Choose the Correct Format
Different file formats are useful for different purposes.
- PNG โ Good for websites, applications, documents, and general image use.
- JPG โ Useful when a smaller raster image is preferred.
- SVG โ Excellent for scalable graphics and many web applications.
- PDF โ Useful for reports, documents, and high-quality printable output.
For charts containing lots of text, lines, and simple shapes, PNG, SVG, and PDF are often preferable to JPEG.
08. Save the Figure Before Showing It
A good habit is to save the figure before calling plt.show().
This makes the order of operations clear and works well when you are creating files automatically.
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(8, 5))
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
sales = [120, 145, 170, 155, 190, 220]
ax.plot(months, sales, marker="o")
ax.set_title("Sales Performance")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
ax.grid(True)
fig.savefig(
"sales_report.png",
dpi=300,
bbox_inches="tight"
)
plt.show()The figure is created, formatted, exported, and then displayed.
09. Save Charts to a Specific Folder
You can provide a folder path when saving a chart. The folder must already exist unless your Python program creates it.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
years = [2021, 2022, 2023, 2024, 2025]
users = [120, 180, 250, 330, 450]
ax.plot(years, users, marker="o")
ax.set_title("Users Over Time")
fig.savefig("charts/users.png", dpi=300)
plt.show()
Here, Matplotlib attempts to save the file inside a folder named charts.
If the folder does not exist, the save operation will fail.
10. Create a Professional Export
A good exported chart should have readable text, an appropriate figure size, suitable resolution, and enough space around its contents.
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10, 6))
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
sales = [120, 150, 175, 160, 210, 240]
ax.plot(months, sales, marker="o", linewidth=2)
ax.set_title("Monthly Sales")
ax.set_xlabel("Month")
ax.set_ylabel("Sales")
ax.grid(True)
fig.tight_layout()
fig.savefig(
"monthly_sales.png",
dpi=300,
bbox_inches="tight"
)
plt.show()- Use
fig.savefig()to save a Matplotlib figure. - The file extension determines the output format.
- PNG is a good general-purpose format for charts.
- SVG and PDF are vector formats that scale well.
- Use
dpito control raster image resolution. - Use
bbox_inches="tight"to reduce unnecessary surrounding space. - Use
figsizeto control the physical size of the figure. - Make sure the destination folder exists before saving to it.
Create a line chart showing the number of website visitors over six months.
Set the figure size to (10, 6), add a title and axis labels, and enable grid lines.
Save the chart as a PNG using dpi=300 and bbox_inches="tight".
Then save another copy as an SVG file.