Python Matplotlib pyplot

Learn Python Matplotlib pyplot with simple plot examples. Create line plots, scatter plots, bar charts, and make beautiful plots using labels, colors, markers, legends, grids, styles, and savefig().

Published

Updated

Read time 8 min read

Reviewed byDeepak Prasad

This page is for anyone who wants practical matplotlib.pyplot usage in Python: install and import, your first line chart, common plot types, styling, figures and subplots, and saving files. For figure sizing and subplots(), see pyplot figure with matplotlib; for vertical reference lines, see plt.vlines; for statistical scatter plots, Seaborn scatterplot wraps the same backend.

Tested on: Python 3.13.3; Matplotlib 3.8.3; kernel 6.14.0-37-generic; Ubuntu 25.04.


What is Matplotlib in Python?

Matplotlib is Python’s standard plotting library for static charts: line plots, scatter, bars, histograms, pie charts, images, and more. Plotting functions accept any sequence of numbers; NumPy arrays behave like lists here and are the usual choice in real analysis. Matplotlib turns data plus styling into a Figure you can display or write to PNG, PDF, SVG, and other formats.


What is pyplot and plt in Python?

The submodule matplotlib.pyplot exposes a MATLAB-like API: functions such as plot, scatter, and title operate on the “current” figure and axes. The community convention is:

python
import matplotlib.pyplot as plt
Output

Here plt is only an alias; it keeps notebooks and scripts short. Behind the scenes, pyplot tracks a default “current” Figure and Axes, so the order of calls matters. For larger programs, many teams prefer fig, ax = plt.subplots() and call methods on ax so each plot’s state is explicit and you avoid accidental reuse of the same axes.


Install and import Matplotlib

Install Matplotlib using pip

From a virtual environment or system Python:

text
pip install matplotlib

On this machine, pip show matplotlib reports something like the following (versions and paths will match your install):

text
Name: matplotlib
Version: 3.8.3
Summary: Python plotting package
Home-page: https://matplotlib.org
Requires: contourpy, cycler, fonttools, kiwisolver, numpy, packaging, pillow, pyparsing, python-dateutil

If you install packages from version control or private indexes, the same workflow applies as in install Python package from GitHub: activate your environment, then pip install.

With Anaconda, you can use conda install matplotlib instead; see install conda on Ubuntu for context on Conda environments.

Import pyplot as plt

Headless servers and CI jobs often have no display. Set a non-interactive backend before importing pyplot if you only save files:

python
import matplotlib

matplotlib.use("Agg")  # no GUI; safe for servers
import matplotlib.pyplot as plt

For local scripts with a screen, you can omit matplotlib.use and call plt.show() to open a window.


Create your first Matplotlib plot

Simple line plot example

python
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

x = [0, 1, 2, 3, 4]
y = [0, 1, 4, 9, 16]
plt.plot(x, y)
plt.savefig("first-line.png")

Running this in the current directory writes first-line.png with a curve through your (x, y) points.

Add title and axis labels

python
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

x = [0, 1, 2, 3, 4]
y = [0, 1, 4, 9, 16]
plt.plot(x, y)
plt.title("Squares")
plt.xlabel("x")
plt.ylabel("x squared")
plt.savefig("first-line-labeled.png")

Show the plot using plt.show()

plt.show() displays the current figure and blocks until you close the window on interactive backends (for example TkAgg on the desktop). In Jupyter Notebook, the classic %matplotlib inline magic still appears in older material; current practice is often the inline backend by default or ipympl for interaction. If you use Agg and only call savefig, you do not need show(), and nothing pops up on a headless server—which is usually what you want for batch jobs.


Matplotlib plot examples

The snippets below use Agg and savefig so you can run them without a display; adjust filenames as you like. Each block is a minimal script—run it once, open the image it writes, and add plt.close() after savefig when you generate many figures in a loop so memory stays bounded.

Line plot

python
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

x = [0, 1, 2, 3, 4]
y = [0, 1, 4, 9, 16]
plt.plot(x, y, marker="o")
plt.title("Line plot")
plt.savefig("line.png")

Scatter plot

python
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

x = [0, 1, 2, 3, 4]
y = [0, 1, 4, 9, 16]
plt.scatter(x, y, color="C0")
plt.title("Scatter plot")
plt.savefig("scatter.png")

Bar chart

python
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

labels = ["A", "B", "C"]
values = [4, 7, 1]
plt.bar(labels, values)
plt.title("Bar chart")
plt.savefig("bar.png")

Histogram

python
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

values = [1, 2, 2, 3, 3, 3, 4, 4, 5]
plt.hist(values, bins=5, edgecolor="black")
plt.title("Histogram")
plt.savefig("hist.png")

Pie chart

python
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

labels = ["Apple", "Banana", "Cherry"]
sizes = [15, 30, 45]
plt.pie(sizes, labels=labels, autopct="%1.1f%%")
plt.title("Pie chart")
plt.savefig("pie.png")

Make beautiful plots in Matplotlib

Small layout and style choices add up: readable figure size, grid, color and marker choices, legends, tight margins, and built-in style sheets.

Use figure size

python
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

plt.figure(figsize=(9, 4))
plt.plot([0, 1, 2], [0, 1, 4], marker="s")
plt.title("Wide figure")
plt.savefig("wide.png")

figsize is in inches; pair with dpi in savefig when you care about pixel dimensions.

Add grid lines

python
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

plt.plot([0, 1, 2, 3], [0, 1, 4, 9])
plt.grid(True, linestyle=":", alpha=0.7)
plt.savefig("grid.png")

Use colors and markers

plot accepts color, marker, and linestyle; see optional arguments in Python for the general idea—here they map to Matplotlib keyword parameters.

python
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

plt.plot(
    [0, 1, 2, 3],
    [0, 1, 4, 9],
    color="tab:green",
    marker="o",
    linestyle="--",
    linewidth=2,
    markersize=8,
)
plt.savefig("styled-line.png")

Add legend

python
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

x = [0, 1, 2, 3]
plt.plot(x, [0, 1, 4, 9], label="n^2")
plt.plot(x, [0, 1, 2, 3], label="n")
plt.legend()
plt.savefig("legend.png")

Use tight layout

plt.tight_layout() adjusts padding so titles and axis labels are less likely to overlap panel edges—especially useful before savefig.

python
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

plt.plot([0, 1, 2], [0, 1, 4])
plt.title("Title that needs room")
plt.xlabel("x axis")
plt.ylabel("y axis")
plt.tight_layout()
plt.savefig("tight.png")

Use Matplotlib styles

python
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

plt.style.use("ggplot")
plt.plot([0, 1, 2], [1, 3, 2])
plt.savefig("style-ggplot.png")
plt.close()

plt.style.use("default")

Try print(plt.style.available) for names on your install. Switch back to "default" when you want the stock look in the same session.


Figure and Axes in Matplotlib

Figure vs Axes

A Figure is the top-level container: overall size in inches, optional suptitle, and one or more plotting regions. An Axes (singular name, plural often written “axes”) is one of those regions: it owns the x/y (or polar) spines, tick locators, labels, and the line or patch artists you draw. fig.savefig(...) saves the whole figure; ax.set_title(...) only affects one panel. One figure can hold many axes—for example a row of charts that share a theme or color cycle.

When to use plt.subplots()

Call fig, ax = plt.subplots() (or plt.subplots(nrows, ncols)) when you want a clear handle to pass around, multiple subplots in one layout, or code that mirrors the Matplotlib object-oriented API. Use bare plt.plot for quick one-off charts.

python
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(5, 3))
ax.plot([0, 1, 2], [0, 1, 4])
ax.set_title("OO style")
fig.savefig("oo-line.png")

Create multiple plots with subplots

Create two plots side by side

python
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))
ax1.plot([0, 1, 2], [0, 1, 4])
ax1.set_title("Line")
ax2.scatter([0, 1, 2], [0, 1, 4])
ax2.set_title("Scatter")
fig.tight_layout()
fig.savefig("side-by-side.png")

Create a 2x2 subplot layout

python
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

x = [0, 1, 2, 3]
y = [0, 1, 4, 9]
fig, ax = plt.subplots(2, 2, figsize=(8, 8))
ax[0, 0].plot(x, y)
ax[0, 0].set_title("Line")
ax[0, 1].scatter(x, y)
ax[0, 1].set_title("Scatter")
ax[1, 0].bar(["a", "b", "c"], [3, 5, 2])
ax[1, 0].set_title("Bar")
ax[1, 1].hist([1, 2, 2, 3, 3, 3], bins=4, edgecolor="black")
ax[1, 1].set_title("Histogram")
fig.tight_layout()
fig.savefig("grid-2x2.png")

Save Matplotlib plot as image

Save as PNG

python
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

plt.plot([0, 1, 2], [2, 3, 1])
plt.savefig("plot.png", format="png")

Save as SVG or PDF

Vector formats scale cleanly for print and slides:

python
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

plt.plot([0, 1, 2], [2, 3, 1])
plt.savefig("plot.svg")
plt.savefig("plot.pdf")

Use dpi and bbox_inches

Higher dpi increases raster resolution. bbox_inches="tight" trims extra margin so labels are not cut off.

python
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

plt.plot([0, 1, 2], [2, 3, 1])
plt.title("Export settings")
plt.savefig("plot-hidpi.png", dpi=200, bbox_inches="tight")

For web assets you sometimes want a transparent background: pass transparent=True to savefig. When a script creates many figures in a loop, call plt.close(fig) or plt.close("all") after each savefig so memory does not grow without bound.


Common mistakes with Matplotlib pyplot

  • Importing pyplot before calling matplotlib.use("Agg") on headless machines—set the backend first, then import pyplot.
  • Calling savefig after plt.close() or after the figure is discarded; save while the figure still exists.
  • Overlapping labels in multi-panel figures; use fig.tight_layout() or constrained_layout=True in subplots.
  • Mixing stateful plt.* calls with multiple figures without tracking which figure is “current”; prefer keeping a fig reference.
  • Expecting plt.show() to write files; use savefig for persistent output.
  • Creating hundreds of plots in one process without plt.close(); figures stay in memory until closed.
  • Re-running cells in Jupyter that call plt.plot repeatedly on the pyplot state machine; prefer fig, ax = plt.subplots() and reuse ax, or clear output between runs.

Matplotlib pyplot quick reference table

Task Typical call
Headless backend matplotlib.use("Agg") before import matplotlib.pyplot as plt
Import import matplotlib.pyplot as plt
Line plt.plot(x, y) or ax.plot(x, y)
Scatter plt.scatter(x, y)
Bars plt.bar(labels, values)
Histogram plt.hist(data, bins=...)
Pie plt.pie(sizes, labels=..., autopct=...)
Labels plt.title, plt.xlabel, plt.ylabel
Grid plt.grid(True)
Legend plt.legend() after labeling series
Layout plt.tight_layout() or fig.tight_layout()
Subplots fig, ax = plt.subplots(rows, cols)
Save plt.savefig("out.png", dpi=150, bbox_inches="tight")
Show (interactive) plt.show()
Free memory plt.close(fig) or plt.close("all")
Style plt.style.use("ggplot")

Summary

You can cover most day-to-day work with import matplotlib.pyplot as plt, a small amount of data as lists or arrays, and calls such as plot, scatter, bar, hist, and pie. Titles, labels, grids, legends, figure size, style sheets, and tight_layout make charts easier to read. When scripts grow, plt.subplots returns explicit Figure and Axes objects that stay maintainable. Finish with savefig (and dpi / bbox_inches as needed), set the Agg backend on servers without a display, and close figures when you generate many of them in one run.


References


Frequently Asked Questions

1. What is the difference between matplotlib and pyplot?

Matplotlib is the whole plotting library; pyplot (usually imported as plt) is a stateful interface that mirrors a MATLAB-style workflow—figure creation, plotting, labels, and show/save—while the underlying Figure and Axes objects are what actually hold artists and scales.

2. When should I use plt.subplots() instead of plt.plot() alone?

Use plt.subplots() when you want explicit Figure and Axes objects, multiple panels in one figure, or the object-oriented style (ax.plot) for larger scripts; bare plt.plot is fine for quick single-axis charts.

3. Why is my savefig() file blank or clipped?

Call savefig before closing the figure, use bbox_inches='tight' when labels are clipped, and on servers without a display set the Agg backend before importing pyplot.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …