Data Visualization with matplotlib
Visualization is a way to gain insight into data and into different aspects of an analysis.
Why Plot Data at All
Numbers in a table can hide the shape of a pattern. Visualization is a way to gain insight into data and into different aspects of an analysis. A picture of the values often shows a trend, a repeating cycle, or a sudden change faster than a list of numbers does. This article uses matplotlib, the primary scientific plotting library in Python, for every visualization. It provides functions for publication-quality charts such as line charts, histograms, and scatter plots. The line plot is the chart type this article focuses on.
What do you think happens?
The x values run evenly from -10 to 10, and each y value is the sine of the matching x value. Before running anything, what do you expect the plot to look like, and where would the x markers fall along the curve?
Reveal answer
The plot is a wave. The sine curve rises and falls repeatedly between -1 and 1 across the interval from -10 to 10, and the x markers sit at evenly spaced points along that wave.
A line plot connects points in order. Because the inputs are evenly spaced and the outputs are sine values, the connected points trace the oscillating shape of the sine function. The markers show exactly where each sampled input landed on that shape.
What a Line Plot Pairs Together
The central idea is that the plot function makes a line chart of one array against another. The first argument supplies the horizontal positions, and the second supplies the vertical values. Each pair of matching positions becomes one point on the line, and the points are connected in order. This means the two arrays must pair up position by position. The first element of the x array goes with the first element of the y array, the second with the second, and so on.
The diagram uses five samples so that the pairing is easy to see. Position 0 holds x = -10 and its sine value, position 1 holds x = -5 and its sine value, and so on. The plot does not know anything about the sine function. It only receives two sequences and places a point at each matched position. The shape of the wave comes from the y values you supplied, and the spacing along the horizontal axis comes from the x values.
Arrays are the containers that hold these sample values. In the sine example, np.linspace creates the x values and np.sin computes the y values from them. Because both results are arrays with matching positions, plt.plot can read them in order from start to end.
The Sine Example, Line by Line
Before explaining how matplotlib works, start with a working example. The code below reconstructs the sine plot described in the source. Read it once from top to bottom, and for each line, say what it contributes to the final picture. Then run it.
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-10, 10, 5)
y = np.sin(x)
plt.plot(x, y, marker="x")- 1Line 1 loads numpy so its array functions are available under the short name np.
- 2Line 2 loads the pyplot module under the short name plt. This is the part of matplotlib that holds the plotting functions.
- 3Line 3 creates the x array.
linspace(-10, 10, 5)produces five evenly spaced values from -10 to 10 inclusive. - 4Line 4 creates the y array by applying sine to every element of x, so y[i] is the sine of x[i].
- 5Line 5 draws the chart. The first argument supplies horizontal positions, the second supplies vertical values, and marker="x" places an x symbol at each sampled point.
- numpy is imported under the alias np and provides linspace and sin
- pyplot is imported under the alias plt and provides plot
- linspace creates evenly spaced x values from -10 to 10 with 5 samples
- sin computes the sine of every x value, producing a matching y array
- plot takes x first and y second, and marker="x" draws an x at each sample
A line chart showing a wave of five connected points with x markers, starting near 0.54 at x = -10, rising to about 0.96 at x = -5, crossing 0 at x = 0, dipping to about -0.96 at x = 5, and ending near -0.54 at x = 10.The source describes the same structure: np.linspace creates the x values, np.sin computes the y values, and plt.plot(x, y, marker="x") draws the line with markers at each sample. The code above uses only five samples so each step can be checked by hand. In practice, a larger sample count gives a smoother curve.
Tracing the Lines to Find a Bug
Suppose a plot comes out wrong or fails to appear. The fastest way to find the cause is to trace the lines in the order they run, and to track what each name refers to at each step. A line that uses a name before that name has been created is the place where the problem begins.
Locating the first line that goes wrong
A student moves the y line above the x line, so the script now reads: import numpy as np, import matplotlib.pyplot as plt, y = np.sin(x), x = np.linspace(-10, 10, 5), plt.plot(x, y, marker="x"). Where does the trace first go wrong?
- 1Trace the imports
Both imports run without trouble, so np and plt exist before any plotting code starts.
- 2Reach the first computation of y
The line y =
np.sin(x)runs next. It needs a value named x, but x has not been created yet, because its assignment comes on the following line. - 3Identify the failing line
The error begins at y =
np.sin(x). This is the first line where the output departs from the prediction, since no y array is produced at all. - 4Confirm the fix
Restoring the original order, with the x line before the y line, lets each name exist before it is used. The plot then matches the predicted wave.
The unexpected result begins at the line y = np.sin(x), because it reads x before x has been created. Moving the x assignment above it fixes the trace.
Changing the Marker and the Sample Count
The marker argument controls the symbol drawn at each sample point. In the source example it is marker="x". The number of samples is set by the third argument to np.linspace. Changing either one alters the picture in a predictable way. The marker changes only how each point looks. The sample count changes how many points exist along the same curve.
A smoother wave of forty points connected in order, with a round circle at each point instead of an x.- Changing the third argument of linspace from 5 to 40 gives 40 samples instead of 5
- Changing marker from "x" to "o" changes only the symbol drawn at each point
Notice that the curve itself is the same mathematical shape in both versions. With more samples, the connecting segments are shorter and the wave looks smoother. With fewer samples, the same wave is drawn from fewer points, so its corners look sharper. Keeping x and y the same length is essential, because each position must still pair with a matching y value.
Change the sample count in the sine example to 10 and change the marker to a different symbol of your choice. Before running the code, predict how many points will appear and how the shape will differ from the five-sample version. Then run it and compare.
Hints
- The number of points equals the number passed to
np.linspaceas its third argument. - The marker argument accepts a different symbol name, such as "o" or "x".
Where the Figure Appears in a Notebook
When you run plotting code inside a Jupyter Notebook, the figure needs to be shown somewhere. Two magic commands control this behavior in the source: %matplotlib inline and %matplotlib notebook. Both are used to show figures directly in the browser while you work. They differ in the kind of environment they set up.
| Magic command | What the source says | Main purpose |
|---|---|---|
| %matplotlib inline | Shows figures in the browser inside a Jupyter Notebook. The material itself was produced with it. | Displaying figures as part of the notebook |
| %matplotlib notebook | Shows figures in the browser inside a Jupyter Notebook. The source recommends it because it provides an interactive environment. | Displaying figures in an interactive environment |
The two magic commands as described in the source
Common Mistakes with Plotting Lines
Common mistake Passing x and y arrays of different lengths
What it looks likex = np.linspace(-10, 10, 5) with y = np.sin(np.linspace(-10, 10, 40))Why it failsThe arrays must pair up position by position, so every x value needs exactly one matching y value.
Do this insteadBuild both arrays from the same sample count, or confirm the lengths match before plotting.
Common mistake Expecting the marker to change the curve's shape
What it looks likeSwitching marker="x" to marker="o" and expecting a different wave
Why it failsThe marker only changes the symbol drawn at each point. The curve comes from the y values.
Do this insteadTo change the shape, change the x and y values or the number of samples.
Common mistake Using a name before it has been created
What it looks likePutting y = np.sin(x) above x = np.linspace(-10, 10, 5)Why it failsLines run from top to bottom, so x does not exist yet when the sine line runs.
Do this insteadTrace the script in order and make sure each name is assigned above the line that uses it.
Common mistake Thinking the magic command changes the plotted data
What it looks likeBelieving %matplotlib notebook alters the values drawn on the chart
Why it failsThe magic command only controls how the figure is shown in the notebook.
Do this insteadCheck the x and y arrays and the plt.plot call to understand the data. Use the magic command only to control display.
Key Takeaways
- A matplotlib line plot pairs x and y arrays position by position, places a point at each pair, and connects the points in order.
- Tracing a script line by line, while tracking which names exist at each step, locates the first line where the output departs from the prediction.
- The marker argument changes only the symbol drawn at each point, while the sample count controls how many points sample the same curve.
- In a Jupyter Notebook, %matplotlib inline and %matplotlib notebook both show figures in the browser, and the notebook version provides an interactive environment.