Topic 14.9
Charts with Matplotlib
In one line
Matplotlib draws charts from NumPy and pandas data: line, bar, scatter and histogram, with titles and labels, saved as a PNG file. A chart answers questions that a table of numbers hides.
Think of it like this
A school report with a line of marks for each month. Looking at 12 numbers in a row, you might miss that marks fell for three months. A small line drawing shows it at once. A chart is a table translated into a shape your eyes read in a second.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- Matplotlib
- Python's main library for drawing charts.
- pyplot (plt)
- The module with the plotting functions, usually imported as plt.
- Figure
- The whole picture or canvas.
- Axes
- One plot area inside a figure, with its own x and y axes.
- Line / bar / scatter / histogram
- The four everyday chart types for trends, comparisons, relationships and distributions.
- Bin
- One range of values in a histogram. The bar height is how many values fall in it.
- Legend
- A key that says which line or colour is which series.
- dpi
- Dots per inch: the sharpness of a saved image.
Step by step
01Figure and axes
fig, ax = plt.subplots() makes an empty figure with one axes. You draw on ax, label it, then save or show the figure. Think of fig as the sheet of paper and ax as the frame you draw in.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot([1, 2, 3, 4], [10, 12, 9, 15])
ax.set_title("Marks by month")
ax.set_xlabel("Month")
ax.set_ylabel("Mark")
fig.savefig("marks.png", dpi=150)02What that chart looks like
A single line goes through four points: it starts at 10, rises to 12, dips to 9 and climbs to 15. The x-axis is titled Month with ticks 1 to 4, the y-axis is titled Mark, and the title Marks by month sits above the plot. The file marks.png is written to the current folder.
03Bar, scatter and histogram
A bar chart of revenue per city shows one bar for each city, the tallest being the best seller. A scatter plot of age against salary shows one dot per person; dots rising from left to right mean salary tends to grow with age. A histogram of 500 test scores shows a hill: most bars in the middle, short bars at the ends.
fig, axes = plt.subplots(1, 3, figsize=(12, 3))
axes[0].bar(["Pune", "Delhi", "Mumbai"], [76.0, 77.5, 10.0])
axes[1].scatter([23, 31, 27, 45], [52000, 71000, 64000, 90000])
axes[2].hist(scores, bins=20)
fig.tight_layout()
fig.savefig("three.png")04The numbers behind a histogram
The runnable example draws a histogram in text. It makes 500 values from a seeded normal distribution, then np.histogram gives 5 counts and 6 edges. The middle bin holds about half the values: the hill. The ASCII bars are the same picture a chart would show.
05pandas shortcuts and good habits
df["salary"].plot(kind="hist", bins=10) and df.plot.scatter(x="age", y="salary") draw straight from a DataFrame. Habits that make charts honest: start bar charts at zero, label units, avoid 3-D effects, use few colours, and say what the data is in the title.
Try it yourself
- 1
Run it on your computer
Install Matplotlib with
pip install matplotlib(oruv add matplotlib), copy the first example, run it and openmarks.png. Change the marks and run it again. - 2
Change the bins
In the runnable example try
bins=3,bins=10andbins=50. Which tells you most about the data? Too few bins hide the shape; too many make it noisy. - 3
Pick the right chart
For each question choose a chart type: how did daily visitors change this month; which of five products sells most; is price related to rating; how long do users stay on the page?
Code & diagrams
Needs matplotlib installed on your computer. The picture is a line with a round marker at each of the four points, rising overall from 10 to 15 with a dip at month 3.
import matplotlib.pyplot as plt
months = [1, 2, 3, 4]
marks = [10, 12, 9, 15]
fig, ax = plt.subplots()
ax.plot(months, marks, marker="o")
ax.set_title("Marks by month")
ax.set_xlabel("Month")
ax.set_ylabel("Mark")
fig.savefig("marks.png", dpi=150)
print("saved marks.png")Output
saved marks.pngThe left chart has three bars: Pune and Delhi nearly equal and tall, Mumbai short. The right chart is a bell-shaped hill centred near 50.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
rng = np.random.default_rng(3)
scores = pd.Series(rng.normal(50, 10, size=500))
revenue = pd.Series({"Pune": 76.0, "Delhi": 77.5, "Mumbai": 10.0})
fig, (left, right) = plt.subplots(1, 2, figsize=(9, 3))
revenue.plot.bar(ax=left, title="Revenue by city")
scores.plot.hist(ax=right, bins=20, title="Scores")
fig.tight_layout()
fig.savefig("charts.png")Change bins=5 to bins=10 and watch the bars split. The shape of a histogram depends on the bin choice.
Expected output
counts: [18, 122, 243, 106, 11]
edges : [19.4, 32.2, 44.9, 57.7, 70.5, 83.2]
total : 500
19.4 | #
32.2 | ############
44.9 | ########################
57.7 | ##########
70.5 | #Break it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
x and y of different lengths
Plot four x values against three y values (on your own computer).
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot([1, 2, 3, 4], [10, 12, 9])Myth vs fact
Myth
A chart is only decoration.
Fact
A good chart is analysis. It shows outliers (values far from the rest), trends and mistakes in the data that summary numbers hide.
Myth
More colours and effects make a chart better.
Fact
They add noise. One message, clear labels and few colours communicate best.
Myth
plt.show() is always needed.
Fact
It opens a window on a desktop. On servers and in scripts you save the figure with savefig.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
Prefer the object-oriented API (
fig, ax = plt.subplots()) over the statefulplt.plot(...)calls. The stateful version keeps hidden global state and gets confusing with more than one plot. - ▸
On a server without a display, Matplotlib needs a non-interactive backend; setting
matplotlib.use("Agg")before importing pyplot (or the environment variableMPLBACKEND=Agg) makes it draw to files only. - ▸
Matplotlib is the base layer. Seaborn adds statistical charts on top of it, and Plotly and Altair build interactive charts for the web. The same data skills carry over to all of them.
- ▸
Figures hold memory until they are closed. In a loop or a long-running service that makes many charts, call
plt.close(fig)aftersavefig, or Matplotlib keeps every figure alive and warns after a while. Also callsavefigbeforeshow, because on many backendsshowclears the figure. - ▸
Histogram bins are half-open: a value on an edge goes into the bin on its right, except the last bin, which includes its upper edge. That is why
np.histogram([1, 2, 2, 3, 3, 3, 4], bins=3)counts the 4 in the last bin. Bin width changes the story, so look at several, and for skewed data consider a log scale or thedensity=Trueoption to compare samples of different sizes.
Remember this
- 1
Matplotlib is Python's standard plotting library. You import its drawing module as
import matplotlib.pyplot as plt. A figure is the whole picture (the canvas), and an axes is one plot inside it, with its own x-axis, y-axis, title and data. The recommended style is the object-oriented one:fig, ax = plt.subplots()gives you both, and you then call methods onax. - 2
The four everyday charts: line (
ax.plot(x, y)) for a value over time or order; bar (ax.bar(labels, heights)) for comparing categories; scatter (ax.scatter(x, y)) for the relationship between two numbers; histogram (ax.hist(data, bins=20)) for how values are spread. The way values are spread out is called their distribution (Topic 14.4). Pick by the question: trend, comparison, relationship or distribution. - 3
Always label your chart:
ax.set_title(...),ax.set_xlabel(...),ax.set_ylabel(...), andax.legend()when several series share a plot. A chart without axis labels and units is a drawing, not a result. Keep one message per chart. - 4
To keep the picture, call
fig.savefig("chart.png", dpi=150), orplt.show()to open a window on a desktop. pandas can plot directly:df["salary"].plot(kind="hist")ordf.plot.bar(...)calls Matplotlib for you. - 5
These blocks do not run in the browser. Plotting needs a place to draw, and Hectal's runner has no display, so the examples in this topic are shown as code with a description of the chart you would get. Run them on your own computer after
pip install matplotlib. What you can run here is the numeric half of a chart: the counts that a histogram would draw. - 6
A histogram first splits the range of the data into bins and counts how many values fall into each.
np.histogram(data, bins=5)returns exactly those counts and the bin edges;ax.histcomputes the same thing and draws bars. If you understand the counts you understand the picture. - 7
In AI work charts are how you judge training. The loss is a number that says how wrong the model is (lower is better). An epoch is one full pass over the training data. So you plot: a loss curve falling over epochs (line), a comparison of model scores (bar), predictions against truth (scatter) and the spread of embedding similarities (histogram). Always plot your data before trusting a model trained on it.
Explain it without notes
What is the difference between a figure and an axes?
Which chart would you use for a trend, a comparison, a relationship and a distribution?
What does a histogram's bin count do to the picture?
Why do the plotting examples in this topic not run in the browser, and how do you run them?
Practice
Write the code (not run) for a bar chart of three subjects and their marks, with a title and axis labels, saved as marks.png.
Use np.histogram to count how many of [1, 2, 2, 3, 3, 3, 4] fall into 3 bins.
Say which chart you would use to show loss over 20 training epochs.
Trade-offs
- ↔
Quick pandas plots versus full Matplotlib control.
df.plotis one line; the full API lets you tune every detail. - ↔
Static images versus interactive charts. PNGs are simple and reproducible; Plotly or Altair let users hover and zoom but need a browser.
- ↔
Detail versus clarity. Showing everything hides the message. Pick what supports the point.
Done when you can
Done when you can create a figure and axes and draw a line, bar, scatter and histogram.
Done when you can label a chart with a title, axis labels and a legend.
Done when you can choose the right chart for a question.
Done when you can explain bins and read the counts behind a histogram.
Done when you can save a figure to a PNG file and say why plots do not run in the browser here.