PythonMastery
reference 6 min read · lesson 19 of 25 in Reference

Matplotlib Cheat Sheet

1 · The lesson

read

Matplotlib draws charts in Python: lines, bars, dots, histograms and pies. This page is a quick reference for people who have made a chart or two and want the common commands in one place. For the full tutorial, see Matplotlib.

On this site, each chart appears below the output when you press Run, so you do not need plt.show(). On your own computer, plt.show() opens a window with the chart. Install it there with pip install matplotlib.

1. The figure and the axes

A figure (fig) is the whole picture. An axes (ax) is one chart inside the figure, with its own x axis and y axis. You draw on ax, and you save or resize fig.

python
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
print(fig.get_size_inches().tolist())    # [6.4, 4.8]

x = [1, 2, 3, 4]
y = [20, 23, 21, 25]     # temperatures over four days
ax.plot(x, y)
print(len(ax.lines))     # 1

plt.subplots(figsize=(8, 4)) makes a figure 8 inches wide and 4 inches high. The default is 6.4 by 4.8.

2. Kinds of chart

python
fig, axs = plt.subplots(2, 2, figsize=(8, 6))

axs[0, 0].plot(x, y)                                   # a line chart
axs[0, 1].scatter([160, 172, 181], [55, 68, 80])       # one dot per pair of values
axs[1, 0].bar(["Mon", "Tue", "Wed"], [3, 5, 2])        # a bar chart; barh() draws the bars sideways
axs[1, 1].pie([30, 70], labels=["tea", "coffee"])      # a pie chart: the parts of a whole

fig.tight_layout()
+ setup added so this can run · re-runs 1 earlier block on this page first
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

x = _AutoMock('x')
y = _AutoMock('y')
plt = _AutoMock('plt')

# Earlier blocks on this page that this one builds on, re-run quietly first.
try:
    import matplotlib.pyplot as plt
except Exception:
    pass
_pm_earlier = [
    'import matplotlib.pyplot as plt\n\nfig, ax = plt.subplots()\nprint(fig.get_size_inches().tolist())    # [6.4, 4.8]\n\nx = [1, 2, 3, 4]\ny = [20, 23, 21, 25]     # temperatures over four days\nax.plot(x, y)\nprint(len(ax.lines))     # 1',
]
def _pm_run_earlier(_srcs, _g):
    import sys as _s, io as _io, warnings as _w
    for _src in _srcs:
        _o, _e = _s.stdout, _s.stderr
        _s.stdout = _s.stderr = _io.StringIO()
        try:
            with _w.catch_warnings():
                _w.simplefilter('ignore')
                exec(compile(_src, '<earlier block>', 'exec'), _g)
        except (Exception, SystemExit):
            pass
        finally:
            _s.stdout, _s.stderr = _o, _e
    if 'matplotlib.pyplot' in _s.modules:
        _s.modules['matplotlib.pyplot'].close('all')   # their plots belong to their own blocks
_pm_run_earlier(_pm_earlier, globals())
del _pm_earlier, _pm_run_earlier

A histogram shows how many values fall into each range (each "bin"):

python
ages = [21, 25, 33, 38, 41, 45, 52]
fig, ax = plt.subplots()
counts, edges, bars = ax.hist(ages, bins=3)
print(counts.tolist())    # [2.0, 3.0, 2.0]
+ setup added so this can run · re-runs 2 earlier blocks on this page first
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

plt = _AutoMock('plt')
x = _AutoMock('x')
y = _AutoMock('y')

# Earlier blocks on this page that this one builds on, re-run quietly first.
try:
    import matplotlib.pyplot as plt
except Exception:
    pass
_pm_earlier = [
    'import matplotlib.pyplot as plt\n\nfig, ax = plt.subplots()\nprint(fig.get_size_inches().tolist())    # [6.4, 4.8]\n\nx = [1, 2, 3, 4]\ny = [20, 23, 21, 25]     # temperatures over four days\nax.plot(x, y)\nprint(len(ax.lines))     # 1',
    'fig, axs = plt.subplots(2, 2, figsize=(8, 6))\n\naxs[0, 0].plot(x, y)                                   # a line chart\naxs[0, 1].scatter([160, 172, 181], [55, 68, 80])       # one dot per pair of values\naxs[1, 0].bar(["Mon", "Tue", "Wed"], [3, 5, 2])        # a bar chart; barh() draws the bars sideways\naxs[1, 1].pie([30, 70], labels=["tea", "coffee"])      # a pie chart: the parts of a whole\n\nfig.tight_layout()',
]
def _pm_run_earlier(_srcs, _g):
    import sys as _s, io as _io, warnings as _w
    for _src in _srcs:
        _o, _e = _s.stdout, _s.stderr
        _s.stdout = _s.stderr = _io.StringIO()
        try:
            with _w.catch_warnings():
                _w.simplefilter('ignore')
                exec(compile(_src, '<earlier block>', 'exec'), _g)
        except (Exception, SystemExit):
            pass
        finally:
            _s.stdout, _s.stderr = _o, _e
    if 'matplotlib.pyplot' in _s.modules:
        _s.modules['matplotlib.pyplot'].close('all')   # their plots belong to their own blocks
_pm_run_earlier(_pm_earlier, globals())
del _pm_earlier, _pm_run_earlier

3. Labels, title and legend

Always say what each axis shows. To get a legend (the key that names each line), give each line a label and then call ax.legend().

python
fig, ax = plt.subplots()
ax.plot(x, y, label="Oslo")
ax.plot(x, [9, 8, 11, 10], label="Rome")
ax.set_title("Temperature")
ax.set_xlabel("Day")
ax.set_ylabel("°C")
ax.text(2, 23, "warmest in Oslo")     # text at the point x=2, y=23
leg = ax.legend()

print(ax.get_title())                           # Temperature
print([t.get_text() for t in leg.get_texts()])  # ['Oslo', 'Rome']
+ setup added so this can run · re-runs 3 earlier blocks on this page first
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

x = _AutoMock('x')
y = _AutoMock('y')
plt = _AutoMock('plt')

# Earlier blocks on this page that this one builds on, re-run quietly first.
try:
    import matplotlib.pyplot as plt
except Exception:
    pass
_pm_earlier = [
    'import matplotlib.pyplot as plt\n\nfig, ax = plt.subplots()\nprint(fig.get_size_inches().tolist())    # [6.4, 4.8]\n\nx = [1, 2, 3, 4]\ny = [20, 23, 21, 25]     # temperatures over four days\nax.plot(x, y)\nprint(len(ax.lines))     # 1',
    'fig, axs = plt.subplots(2, 2, figsize=(8, 6))\n\naxs[0, 0].plot(x, y)                                   # a line chart\naxs[0, 1].scatter([160, 172, 181], [55, 68, 80])       # one dot per pair of values\naxs[1, 0].bar(["Mon", "Tue", "Wed"], [3, 5, 2])        # a bar chart; barh() draws the bars sideways\naxs[1, 1].pie([30, 70], labels=["tea", "coffee"])      # a pie chart: the parts of a whole\n\nfig.tight_layout()',
    'ages = [21, 25, 33, 38, 41, 45, 52]\nfig, ax = plt.subplots()\ncounts, edges, bars = ax.hist(ages, bins=3)\nprint(counts.tolist())    # [2.0, 3.0, 2.0]',
]
def _pm_run_earlier(_srcs, _g):
    import sys as _s, io as _io, warnings as _w
    for _src in _srcs:
        _o, _e = _s.stdout, _s.stderr
        _s.stdout = _s.stderr = _io.StringIO()
        try:
            with _w.catch_warnings():
                _w.simplefilter('ignore')
                exec(compile(_src, '<earlier block>', 'exec'), _g)
        except (Exception, SystemExit):
            pass
        finally:
            _s.stdout, _s.stderr = _o, _e
    if 'matplotlib.pyplot' in _s.modules:
        _s.modules['matplotlib.pyplot'].close('all')   # their plots belong to their own blocks
_pm_run_earlier(_pm_earlier, globals())
del _pm_earlier, _pm_run_earlier

4. Colours and styles

python
fig, ax = plt.subplots()
line, = ax.plot(x, y, color="red", linestyle="--", marker="o")
print(line.get_linestyle())    # --

line2, = ax.plot(x, [22, 21, 24, 23], "g:s")
print(line2.get_color(), line2.get_marker())    # g s

ax.plot(x, [18, 19, 18, 20], linewidth=3, alpha=0.5)
+ setup added so this can run · re-runs 4 earlier blocks on this page first
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

x = _AutoMock('x')
y = _AutoMock('y')
plt = _AutoMock('plt')

# Earlier blocks on this page that this one builds on, re-run quietly first.
try:
    import matplotlib.pyplot as plt
except Exception:
    pass
_pm_earlier = [
    'import matplotlib.pyplot as plt\n\nfig, ax = plt.subplots()\nprint(fig.get_size_inches().tolist())    # [6.4, 4.8]\n\nx = [1, 2, 3, 4]\ny = [20, 23, 21, 25]     # temperatures over four days\nax.plot(x, y)\nprint(len(ax.lines))     # 1',
    'fig, axs = plt.subplots(2, 2, figsize=(8, 6))\n\naxs[0, 0].plot(x, y)                                   # a line chart\naxs[0, 1].scatter([160, 172, 181], [55, 68, 80])       # one dot per pair of values\naxs[1, 0].bar(["Mon", "Tue", "Wed"], [3, 5, 2])        # a bar chart; barh() draws the bars sideways\naxs[1, 1].pie([30, 70], labels=["tea", "coffee"])      # a pie chart: the parts of a whole\n\nfig.tight_layout()',
    'ages = [21, 25, 33, 38, 41, 45, 52]\nfig, ax = plt.subplots()\ncounts, edges, bars = ax.hist(ages, bins=3)\nprint(counts.tolist())    # [2.0, 3.0, 2.0]',
    'fig, ax = plt.subplots()\nax.plot(x, y, label="Oslo")\nax.plot(x, [9, 8, 11, 10], label="Rome")\nax.set_title("Temperature")\nax.set_xlabel("Day")\nax.set_ylabel("°C")\nax.text(2, 23, "warmest in Oslo")     # text at the point x=2, y=23\nleg = ax.legend()\n\nprint(ax.get_title())                           # Temperature\nprint([t.get_text() for t in leg.get_texts()])  # [\'Oslo\', \'Rome\']',
]
def _pm_run_earlier(_srcs, _g):
    import sys as _s, io as _io, warnings as _w
    for _src in _srcs:
        _o, _e = _s.stdout, _s.stderr
        _s.stdout = _s.stderr = _io.StringIO()
        try:
            with _w.catch_warnings():
                _w.simplefilter('ignore')
                exec(compile(_src, '<earlier block>', 'exec'), _g)
        except (Exception, SystemExit):
            pass
        finally:
            _s.stdout, _s.stderr = _o, _e
    if 'matplotlib.pyplot' in _s.modules:
        _s.modules['matplotlib.pyplot'].close('all')   # their plots belong to their own blocks
_pm_run_earlier(_pm_earlier, globals())
del _pm_earlier, _pm_run_earlier

ax.plot() returns a list of lines, so line, = takes the one line out of that list. The short form "g:s" means green (g), a dotted line (:) and square markers (s). linewidth makes the line thicker, and alpha=0.5 makes it half see-through. A colour can also be a hex code such as "#D9412B".

plt.style.use("ggplot") gives a ready-made look to every chart you make after it. print(plt.style.available) lists the styles.

5. Several charts in one figure

plt.subplots(rows, columns) gives a figure and an array of axes. With one row, use axs[0], axs[1]. With a grid, use axs[row, col].

python
fig, axs = plt.subplots(1, 2, figsize=(8, 3))
print(axs.shape)      # (2,)
axs[0].plot(x, y)
axs[0].set_title("Temperature")
axs[1].bar(["Ada", "Hedy"], [90, 96])
axs[1].set_title("Scores")
fig.tight_layout()    # moves the charts apart so the labels don't overlap
+ setup added so this can run · re-runs 5 earlier blocks on this page first
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

x = _AutoMock('x')
y = _AutoMock('y')
plt = _AutoMock('plt')

# Earlier blocks on this page that this one builds on, re-run quietly first.
try:
    import matplotlib.pyplot as plt
except Exception:
    pass
_pm_earlier = [
    'import matplotlib.pyplot as plt\n\nfig, ax = plt.subplots()\nprint(fig.get_size_inches().tolist())    # [6.4, 4.8]\n\nx = [1, 2, 3, 4]\ny = [20, 23, 21, 25]     # temperatures over four days\nax.plot(x, y)\nprint(len(ax.lines))     # 1',
    'fig, axs = plt.subplots(2, 2, figsize=(8, 6))\n\naxs[0, 0].plot(x, y)                                   # a line chart\naxs[0, 1].scatter([160, 172, 181], [55, 68, 80])       # one dot per pair of values\naxs[1, 0].bar(["Mon", "Tue", "Wed"], [3, 5, 2])        # a bar chart; barh() draws the bars sideways\naxs[1, 1].pie([30, 70], labels=["tea", "coffee"])      # a pie chart: the parts of a whole\n\nfig.tight_layout()',
    'ages = [21, 25, 33, 38, 41, 45, 52]\nfig, ax = plt.subplots()\ncounts, edges, bars = ax.hist(ages, bins=3)\nprint(counts.tolist())    # [2.0, 3.0, 2.0]',
    'fig, ax = plt.subplots()\nax.plot(x, y, label="Oslo")\nax.plot(x, [9, 8, 11, 10], label="Rome")\nax.set_title("Temperature")\nax.set_xlabel("Day")\nax.set_ylabel("°C")\nax.text(2, 23, "warmest in Oslo")     # text at the point x=2, y=23\nleg = ax.legend()\n\nprint(ax.get_title())                           # Temperature\nprint([t.get_text() for t in leg.get_texts()])  # [\'Oslo\', \'Rome\']',
    'fig, ax = plt.subplots()\nline, = ax.plot(x, y, color="red", linestyle="--", marker="o")\nprint(line.get_linestyle())    # --\n\nline2, = ax.plot(x, [22, 21, 24, 23], "g:s")\nprint(line2.get_color(), line2.get_marker())    # g s\n\nax.plot(x, [18, 19, 18, 20], linewidth=3, alpha=0.5)',
]
def _pm_run_earlier(_srcs, _g):
    import sys as _s, io as _io, warnings as _w
    for _src in _srcs:
        _o, _e = _s.stdout, _s.stderr
        _s.stdout = _s.stderr = _io.StringIO()
        try:
            with _w.catch_warnings():
                _w.simplefilter('ignore')
                exec(compile(_src, '<earlier block>', 'exec'), _g)
        except (Exception, SystemExit):
            pass
        finally:
            _s.stdout, _s.stderr = _o, _e
    if 'matplotlib.pyplot' in _s.modules:
        _s.modules['matplotlib.pyplot'].close('all')   # their plots belong to their own blocks
_pm_run_earlier(_pm_earlier, globals())
del _pm_earlier, _pm_run_earlier

6. Axis limits and ticks

Ticks are the small marks along an axis, with their labels.

python
fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_xlim(0, 5)          # x goes from 0 to 5
ax.set_ylim(bottom=0)      # y starts at 0
ax.set_xticks([1, 2, 3, 4], ["Mon", "Tue", "Wed", "Thu"])
ax.grid(True)

print(ax.get_xticks().tolist())                          # [1, 2, 3, 4]
print([t.get_text() for t in ax.get_xticklabels()])      # ['Mon', 'Tue', 'Wed', 'Thu']
+ setup added so this can run · re-runs 6 earlier blocks on this page first
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

x = _AutoMock('x')
y = _AutoMock('y')
plt = _AutoMock('plt')

# Earlier blocks on this page that this one builds on, re-run quietly first.
try:
    import matplotlib.pyplot as plt
except Exception:
    pass
_pm_earlier = [
    'import matplotlib.pyplot as plt\n\nfig, ax = plt.subplots()\nprint(fig.get_size_inches().tolist())    # [6.4, 4.8]\n\nx = [1, 2, 3, 4]\ny = [20, 23, 21, 25]     # temperatures over four days\nax.plot(x, y)\nprint(len(ax.lines))     # 1',
    'fig, axs = plt.subplots(2, 2, figsize=(8, 6))\n\naxs[0, 0].plot(x, y)                                   # a line chart\naxs[0, 1].scatter([160, 172, 181], [55, 68, 80])       # one dot per pair of values\naxs[1, 0].bar(["Mon", "Tue", "Wed"], [3, 5, 2])        # a bar chart; barh() draws the bars sideways\naxs[1, 1].pie([30, 70], labels=["tea", "coffee"])      # a pie chart: the parts of a whole\n\nfig.tight_layout()',
    'ages = [21, 25, 33, 38, 41, 45, 52]\nfig, ax = plt.subplots()\ncounts, edges, bars = ax.hist(ages, bins=3)\nprint(counts.tolist())    # [2.0, 3.0, 2.0]',
    'fig, ax = plt.subplots()\nax.plot(x, y, label="Oslo")\nax.plot(x, [9, 8, 11, 10], label="Rome")\nax.set_title("Temperature")\nax.set_xlabel("Day")\nax.set_ylabel("°C")\nax.text(2, 23, "warmest in Oslo")     # text at the point x=2, y=23\nleg = ax.legend()\n\nprint(ax.get_title())                           # Temperature\nprint([t.get_text() for t in leg.get_texts()])  # [\'Oslo\', \'Rome\']',
    'fig, ax = plt.subplots()\nline, = ax.plot(x, y, color="red", linestyle="--", marker="o")\nprint(line.get_linestyle())    # --\n\nline2, = ax.plot(x, [22, 21, 24, 23], "g:s")\nprint(line2.get_color(), line2.get_marker())    # g s\n\nax.plot(x, [18, 19, 18, 20], linewidth=3, alpha=0.5)',
    'fig, axs = plt.subplots(1, 2, figsize=(8, 3))\nprint(axs.shape)      # (2,)\naxs[0].plot(x, y)\naxs[0].set_title("Temperature")\naxs[1].bar(["Ada", "Hedy"], [90, 96])\naxs[1].set_title("Scores")\nfig.tight_layout()    # moves the charts apart so the labels don\'t overlap',
]
def _pm_run_earlier(_srcs, _g):
    import sys as _s, io as _io, warnings as _w
    for _src in _srcs:
        _o, _e = _s.stdout, _s.stderr
        _s.stdout = _s.stderr = _io.StringIO()
        try:
            with _w.catch_warnings():
                _w.simplefilter('ignore')
                exec(compile(_src, '<earlier block>', 'exec'), _g)
        except (Exception, SystemExit):
            pass
        finally:
            _s.stdout, _s.stderr = _o, _e
    if 'matplotlib.pyplot' in _s.modules:
        _s.modules['matplotlib.pyplot'].close('all')   # their plots belong to their own blocks
_pm_run_earlier(_pm_earlier, globals())
del _pm_earlier, _pm_run_earlier

Starting the y axis at 0 matters for bar charts: a bar that starts higher up makes small differences look big.

7. Extra marks

python
fig, ax = plt.subplots()
bars = ax.bar(["Mon", "Tue", "Wed"], [3, 5, 2])
labels = ax.bar_label(bars)                 # write each bar's value on top of the bar
ax.axhline(3.33, color="grey", linestyle="--")   # a horizontal line at the average, 3.33
ax.annotate("best day", xy=(1, 5), xytext=(1.6, 4.6),
            arrowprops={"arrowstyle": "->"})
print([t.get_text() for t in labels])       # ['3', '5', '2']
+ setup added so this can run · re-runs 7 earlier blocks on this page first
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

plt = _AutoMock('plt')
x = _AutoMock('x')
y = _AutoMock('y')

# Earlier blocks on this page that this one builds on, re-run quietly first.
try:
    import matplotlib.pyplot as plt
except Exception:
    pass
_pm_earlier = [
    'import matplotlib.pyplot as plt\n\nfig, ax = plt.subplots()\nprint(fig.get_size_inches().tolist())    # [6.4, 4.8]\n\nx = [1, 2, 3, 4]\ny = [20, 23, 21, 25]     # temperatures over four days\nax.plot(x, y)\nprint(len(ax.lines))     # 1',
    'fig, axs = plt.subplots(2, 2, figsize=(8, 6))\n\naxs[0, 0].plot(x, y)                                   # a line chart\naxs[0, 1].scatter([160, 172, 181], [55, 68, 80])       # one dot per pair of values\naxs[1, 0].bar(["Mon", "Tue", "Wed"], [3, 5, 2])        # a bar chart; barh() draws the bars sideways\naxs[1, 1].pie([30, 70], labels=["tea", "coffee"])      # a pie chart: the parts of a whole\n\nfig.tight_layout()',
    'ages = [21, 25, 33, 38, 41, 45, 52]\nfig, ax = plt.subplots()\ncounts, edges, bars = ax.hist(ages, bins=3)\nprint(counts.tolist())    # [2.0, 3.0, 2.0]',
    'fig, ax = plt.subplots()\nax.plot(x, y, label="Oslo")\nax.plot(x, [9, 8, 11, 10], label="Rome")\nax.set_title("Temperature")\nax.set_xlabel("Day")\nax.set_ylabel("°C")\nax.text(2, 23, "warmest in Oslo")     # text at the point x=2, y=23\nleg = ax.legend()\n\nprint(ax.get_title())                           # Temperature\nprint([t.get_text() for t in leg.get_texts()])  # [\'Oslo\', \'Rome\']',
    'fig, ax = plt.subplots()\nline, = ax.plot(x, y, color="red", linestyle="--", marker="o")\nprint(line.get_linestyle())    # --\n\nline2, = ax.plot(x, [22, 21, 24, 23], "g:s")\nprint(line2.get_color(), line2.get_marker())    # g s\n\nax.plot(x, [18, 19, 18, 20], linewidth=3, alpha=0.5)',
    'fig, axs = plt.subplots(1, 2, figsize=(8, 3))\nprint(axs.shape)      # (2,)\naxs[0].plot(x, y)\naxs[0].set_title("Temperature")\naxs[1].bar(["Ada", "Hedy"], [90, 96])\naxs[1].set_title("Scores")\nfig.tight_layout()    # moves the charts apart so the labels don\'t overlap',
    'fig, ax = plt.subplots()\nax.plot(x, y)\nax.set_xlim(0, 5)          # x goes from 0 to 5\nax.set_ylim(bottom=0)      # y starts at 0\nax.set_xticks([1, 2, 3, 4], ["Mon", "Tue", "Wed", "Thu"])\nax.grid(True)\n\nprint(ax.get_xticks().tolist())                          # [1, 2, 3, 4]\nprint([t.get_text() for t in ax.get_xticklabels()])      # [\'Mon\', \'Tue\', \'Wed\', \'Thu\']',
]
def _pm_run_earlier(_srcs, _g):
    import sys as _s, io as _io, warnings as _w
    for _src in _srcs:
        _o, _e = _s.stdout, _s.stderr
        _s.stdout = _s.stderr = _io.StringIO()
        try:
            with _w.catch_warnings():
                _w.simplefilter('ignore')
                exec(compile(_src, '<earlier block>', 'exec'), _g)
        except (Exception, SystemExit):
            pass
        finally:
            _s.stdout, _s.stderr = _o, _e
    if 'matplotlib.pyplot' in _s.modules:
        _s.modules['matplotlib.pyplot'].close('all')   # their plots belong to their own blocks
_pm_run_earlier(_pm_earlier, globals())
del _pm_earlier, _pm_run_earlier

ax.fill_between(x, y, alpha=0.3) shades the area under a line. ax2 = ax.twinx() adds a second y axis on the right, for a value with a different unit.

8. Charts from pandas

A pandas table can draw itself. Pass ax=ax so it draws on your chart.

python
import pandas as pd

df = pd.DataFrame({"day": ["Mon", "Tue", "Wed", "Thu"], "temp": [20, 23, 21, 25]})
fig, ax = plt.subplots()
df.plot(x="day", y="temp", ax=ax)
print(len(ax.lines))    # 1
+ setup added so this can run · re-runs 8 earlier blocks on this page first
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

plt = _AutoMock('plt')
x = _AutoMock('x')
y = _AutoMock('y')

# Earlier blocks on this page that this one builds on, re-run quietly first.
try:
    import matplotlib.pyplot as plt
except Exception:
    pass
_pm_earlier = [
    'import matplotlib.pyplot as plt\n\nfig, ax = plt.subplots()\nprint(fig.get_size_inches().tolist())    # [6.4, 4.8]\n\nx = [1, 2, 3, 4]\ny = [20, 23, 21, 25]     # temperatures over four days\nax.plot(x, y)\nprint(len(ax.lines))     # 1',
    'fig, axs = plt.subplots(2, 2, figsize=(8, 6))\n\naxs[0, 0].plot(x, y)                                   # a line chart\naxs[0, 1].scatter([160, 172, 181], [55, 68, 80])       # one dot per pair of values\naxs[1, 0].bar(["Mon", "Tue", "Wed"], [3, 5, 2])        # a bar chart; barh() draws the bars sideways\naxs[1, 1].pie([30, 70], labels=["tea", "coffee"])      # a pie chart: the parts of a whole\n\nfig.tight_layout()',
    'ages = [21, 25, 33, 38, 41, 45, 52]\nfig, ax = plt.subplots()\ncounts, edges, bars = ax.hist(ages, bins=3)\nprint(counts.tolist())    # [2.0, 3.0, 2.0]',
    'fig, ax = plt.subplots()\nax.plot(x, y, label="Oslo")\nax.plot(x, [9, 8, 11, 10], label="Rome")\nax.set_title("Temperature")\nax.set_xlabel("Day")\nax.set_ylabel("°C")\nax.text(2, 23, "warmest in Oslo")     # text at the point x=2, y=23\nleg = ax.legend()\n\nprint(ax.get_title())                           # Temperature\nprint([t.get_text() for t in leg.get_texts()])  # [\'Oslo\', \'Rome\']',
    'fig, ax = plt.subplots()\nline, = ax.plot(x, y, color="red", linestyle="--", marker="o")\nprint(line.get_linestyle())    # --\n\nline2, = ax.plot(x, [22, 21, 24, 23], "g:s")\nprint(line2.get_color(), line2.get_marker())    # g s\n\nax.plot(x, [18, 19, 18, 20], linewidth=3, alpha=0.5)',
    'fig, axs = plt.subplots(1, 2, figsize=(8, 3))\nprint(axs.shape)      # (2,)\naxs[0].plot(x, y)\naxs[0].set_title("Temperature")\naxs[1].bar(["Ada", "Hedy"], [90, 96])\naxs[1].set_title("Scores")\nfig.tight_layout()    # moves the charts apart so the labels don\'t overlap',
    'fig, ax = plt.subplots()\nax.plot(x, y)\nax.set_xlim(0, 5)          # x goes from 0 to 5\nax.set_ylim(bottom=0)      # y starts at 0\nax.set_xticks([1, 2, 3, 4], ["Mon", "Tue", "Wed", "Thu"])\nax.grid(True)\n\nprint(ax.get_xticks().tolist())                          # [1, 2, 3, 4]\nprint([t.get_text() for t in ax.get_xticklabels()])      # [\'Mon\', \'Tue\', \'Wed\', \'Thu\']',
    'fig, ax = plt.subplots()\nbars = ax.bar(["Mon", "Tue", "Wed"], [3, 5, 2])\nlabels = ax.bar_label(bars)                 # write each bar\'s value on top of the bar\nax.axhline(3.33, color="grey", linestyle="--")   # a horizontal line at the average, 3.33\nax.annotate("best day", xy=(1, 5), xytext=(1.6, 4.6),\n            arrowprops={"arrowstyle": "->"})\nprint([t.get_text() for t in labels])       # [\'3\', \'5\', \'2\']',
]
def _pm_run_earlier(_srcs, _g):
    import sys as _s, io as _io, warnings as _w
    for _src in _srcs:
        _o, _e = _s.stdout, _s.stderr
        _s.stdout = _s.stderr = _io.StringIO()
        try:
            with _w.catch_warnings():
                _w.simplefilter('ignore')
                exec(compile(_src, '<earlier block>', 'exec'), _g)
        except (Exception, SystemExit):
            pass
        finally:
            _s.stdout, _s.stderr = _o, _e
    if 'matplotlib.pyplot' in _s.modules:
        _s.modules['matplotlib.pyplot'].close('all')   # their plots belong to their own blocks
_pm_run_earlier(_pm_earlier, globals())
del _pm_earlier, _pm_run_earlier

kind= picks the chart type: "line", "bar", "barh", "hist", "box", "pie" or "scatter".

9. Save and show

python
fig, ax = plt.subplots()
ax.plot(x, y)
fig.savefig("chart.png", dpi=200, bbox_inches="tight")
fig.savefig("chart.pdf")      # the file type comes from the name

import os
print(os.path.exists("chart.png"), os.path.exists("chart.pdf"))   # True True
+ setup added so this can run · re-runs 9 earlier blocks on this page first
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

x = _AutoMock('x')
y = _AutoMock('y')
plt = _AutoMock('plt')

# Earlier blocks on this page that this one builds on, re-run quietly first.
try:
    import matplotlib.pyplot as plt
    import pandas as pd
except Exception:
    pass
_pm_earlier = [
    'import matplotlib.pyplot as plt\n\nfig, ax = plt.subplots()\nprint(fig.get_size_inches().tolist())    # [6.4, 4.8]\n\nx = [1, 2, 3, 4]\ny = [20, 23, 21, 25]     # temperatures over four days\nax.plot(x, y)\nprint(len(ax.lines))     # 1',
    'fig, axs = plt.subplots(2, 2, figsize=(8, 6))\n\naxs[0, 0].plot(x, y)                                   # a line chart\naxs[0, 1].scatter([160, 172, 181], [55, 68, 80])       # one dot per pair of values\naxs[1, 0].bar(["Mon", "Tue", "Wed"], [3, 5, 2])        # a bar chart; barh() draws the bars sideways\naxs[1, 1].pie([30, 70], labels=["tea", "coffee"])      # a pie chart: the parts of a whole\n\nfig.tight_layout()',
    'ages = [21, 25, 33, 38, 41, 45, 52]\nfig, ax = plt.subplots()\ncounts, edges, bars = ax.hist(ages, bins=3)\nprint(counts.tolist())    # [2.0, 3.0, 2.0]',
    'fig, ax = plt.subplots()\nax.plot(x, y, label="Oslo")\nax.plot(x, [9, 8, 11, 10], label="Rome")\nax.set_title("Temperature")\nax.set_xlabel("Day")\nax.set_ylabel("°C")\nax.text(2, 23, "warmest in Oslo")     # text at the point x=2, y=23\nleg = ax.legend()\n\nprint(ax.get_title())                           # Temperature\nprint([t.get_text() for t in leg.get_texts()])  # [\'Oslo\', \'Rome\']',
    'fig, ax = plt.subplots()\nline, = ax.plot(x, y, color="red", linestyle="--", marker="o")\nprint(line.get_linestyle())    # --\n\nline2, = ax.plot(x, [22, 21, 24, 23], "g:s")\nprint(line2.get_color(), line2.get_marker())    # g s\n\nax.plot(x, [18, 19, 18, 20], linewidth=3, alpha=0.5)',
    'fig, axs = plt.subplots(1, 2, figsize=(8, 3))\nprint(axs.shape)      # (2,)\naxs[0].plot(x, y)\naxs[0].set_title("Temperature")\naxs[1].bar(["Ada", "Hedy"], [90, 96])\naxs[1].set_title("Scores")\nfig.tight_layout()    # moves the charts apart so the labels don\'t overlap',
    'fig, ax = plt.subplots()\nax.plot(x, y)\nax.set_xlim(0, 5)          # x goes from 0 to 5\nax.set_ylim(bottom=0)      # y starts at 0\nax.set_xticks([1, 2, 3, 4], ["Mon", "Tue", "Wed", "Thu"])\nax.grid(True)\n\nprint(ax.get_xticks().tolist())                          # [1, 2, 3, 4]\nprint([t.get_text() for t in ax.get_xticklabels()])      # [\'Mon\', \'Tue\', \'Wed\', \'Thu\']',
    'fig, ax = plt.subplots()\nbars = ax.bar(["Mon", "Tue", "Wed"], [3, 5, 2])\nlabels = ax.bar_label(bars)                 # write each bar\'s value on top of the bar\nax.axhline(3.33, color="grey", linestyle="--")   # a horizontal line at the average, 3.33\nax.annotate("best day", xy=(1, 5), xytext=(1.6, 4.6),\n            arrowprops={"arrowstyle": "->"})\nprint([t.get_text() for t in labels])       # [\'3\', \'5\', \'2\']',
    'import pandas as pd\n\ndf = pd.DataFrame({"day": ["Mon", "Tue", "Wed", "Thu"], "temp": [20, 23, 21, 25]})\nfig, ax = plt.subplots()\ndf.plot(x="day", y="temp", ax=ax)\nprint(len(ax.lines))    # 1',
]
def _pm_run_earlier(_srcs, _g):
    import sys as _s, io as _io, warnings as _w
    for _src in _srcs:
        _o, _e = _s.stdout, _s.stderr
        _s.stdout = _s.stderr = _io.StringIO()
        try:
            with _w.catch_warnings():
                _w.simplefilter('ignore')
                exec(compile(_src, '<earlier block>', 'exec'), _g)
        except (Exception, SystemExit):
            pass
        finally:
            _s.stdout, _s.stderr = _o, _e
    if 'matplotlib.pyplot' in _s.modules:
        _s.modules['matplotlib.pyplot'].close('all')   # their plots belong to their own blocks
_pm_run_earlier(_pm_earlier, globals())
del _pm_earlier, _pm_run_earlier

dpi is dots per inch: a higher number gives a sharper image and a bigger file. bbox_inches="tight" cuts off the empty border. On your computer, finish a script like this:

python · run on your machine
fig.savefig("chart.png", dpi=200, bbox_inches="tight")
plt.show()        # opens a window; the script waits until you close it
plt.close(fig)    # frees the memory when you make many charts in a loop

Common mistakes

Mixing plt functions and ax methods. plt.title() draws on the "current" chart, which is the last one made. With several charts, that may not be the one you mean. Pick one style; ax.set_title() always says which chart it changes.

No window appears. In a .py file, nothing shows until you call plt.show(). Put it at the end of the script. (On this site, charts appear without it.)

A blank saved image. On your computer, plt.show() ends the figure when you close the window, so a plt.savefig() after it saves a new, empty figure. Save first, then show:

python · run on your machine
plt.savefig("chart.png")    # first
plt.show()                  # then

Labels that overlap. With several charts, titles and tick labels can run into each other. Call fig.tight_layout() before you save.

Calling .plot() on axs. With more than one chart, axs is an array of charts, not one chart, so axs.plot(x, y) raises an AttributeError. Draw on one of them:

python
fig, axs = plt.subplots(1, 2)
try:
    axs.plot(x, y)
except AttributeError:
    print("AttributeError: draw on axs[0] or axs[1]")
axs[0].plot(x, y)
+ setup added so this can run · re-runs 10 earlier blocks on this page first
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

x = _AutoMock('x')
y = _AutoMock('y')
plt = _AutoMock('plt')

# Earlier blocks on this page that this one builds on, re-run quietly first.
try:
    import matplotlib.pyplot as plt
    import pandas as pd
    import os
except Exception:
    pass
_pm_earlier = [
    'import matplotlib.pyplot as plt\n\nfig, ax = plt.subplots()\nprint(fig.get_size_inches().tolist())    # [6.4, 4.8]\n\nx = [1, 2, 3, 4]\ny = [20, 23, 21, 25]     # temperatures over four days\nax.plot(x, y)\nprint(len(ax.lines))     # 1',
    'fig, axs = plt.subplots(2, 2, figsize=(8, 6))\n\naxs[0, 0].plot(x, y)                                   # a line chart\naxs[0, 1].scatter([160, 172, 181], [55, 68, 80])       # one dot per pair of values\naxs[1, 0].bar(["Mon", "Tue", "Wed"], [3, 5, 2])        # a bar chart; barh() draws the bars sideways\naxs[1, 1].pie([30, 70], labels=["tea", "coffee"])      # a pie chart: the parts of a whole\n\nfig.tight_layout()',
    'ages = [21, 25, 33, 38, 41, 45, 52]\nfig, ax = plt.subplots()\ncounts, edges, bars = ax.hist(ages, bins=3)\nprint(counts.tolist())    # [2.0, 3.0, 2.0]',
    'fig, ax = plt.subplots()\nax.plot(x, y, label="Oslo")\nax.plot(x, [9, 8, 11, 10], label="Rome")\nax.set_title("Temperature")\nax.set_xlabel("Day")\nax.set_ylabel("°C")\nax.text(2, 23, "warmest in Oslo")     # text at the point x=2, y=23\nleg = ax.legend()\n\nprint(ax.get_title())                           # Temperature\nprint([t.get_text() for t in leg.get_texts()])  # [\'Oslo\', \'Rome\']',
    'fig, ax = plt.subplots()\nline, = ax.plot(x, y, color="red", linestyle="--", marker="o")\nprint(line.get_linestyle())    # --\n\nline2, = ax.plot(x, [22, 21, 24, 23], "g:s")\nprint(line2.get_color(), line2.get_marker())    # g s\n\nax.plot(x, [18, 19, 18, 20], linewidth=3, alpha=0.5)',
    'fig, axs = plt.subplots(1, 2, figsize=(8, 3))\nprint(axs.shape)      # (2,)\naxs[0].plot(x, y)\naxs[0].set_title("Temperature")\naxs[1].bar(["Ada", "Hedy"], [90, 96])\naxs[1].set_title("Scores")\nfig.tight_layout()    # moves the charts apart so the labels don\'t overlap',
    'fig, ax = plt.subplots()\nax.plot(x, y)\nax.set_xlim(0, 5)          # x goes from 0 to 5\nax.set_ylim(bottom=0)      # y starts at 0\nax.set_xticks([1, 2, 3, 4], ["Mon", "Tue", "Wed", "Thu"])\nax.grid(True)\n\nprint(ax.get_xticks().tolist())                          # [1, 2, 3, 4]\nprint([t.get_text() for t in ax.get_xticklabels()])      # [\'Mon\', \'Tue\', \'Wed\', \'Thu\']',
    'fig, ax = plt.subplots()\nbars = ax.bar(["Mon", "Tue", "Wed"], [3, 5, 2])\nlabels = ax.bar_label(bars)                 # write each bar\'s value on top of the bar\nax.axhline(3.33, color="grey", linestyle="--")   # a horizontal line at the average, 3.33\nax.annotate("best day", xy=(1, 5), xytext=(1.6, 4.6),\n            arrowprops={"arrowstyle": "->"})\nprint([t.get_text() for t in labels])       # [\'3\', \'5\', \'2\']',
    'import pandas as pd\n\ndf = pd.DataFrame({"day": ["Mon", "Tue", "Wed", "Thu"], "temp": [20, 23, 21, 25]})\nfig, ax = plt.subplots()\ndf.plot(x="day", y="temp", ax=ax)\nprint(len(ax.lines))    # 1',
    'fig, ax = plt.subplots()\nax.plot(x, y)\nfig.savefig("chart.png", dpi=200, bbox_inches="tight")\nfig.savefig("chart.pdf")      # the file type comes from the name\n\nimport os\nprint(os.path.exists("chart.png"), os.path.exists("chart.pdf"))   # True True',
]
def _pm_run_earlier(_srcs, _g):
    import sys as _s, io as _io, warnings as _w
    for _src in _srcs:
        _o, _e = _s.stdout, _s.stderr
        _s.stdout = _s.stderr = _io.StringIO()
        try:
            with _w.catch_warnings():
                _w.simplefilter('ignore')
                exec(compile(_src, '<earlier block>', 'exec'), _g)
        except (Exception, SystemExit):
            pass
        finally:
            _s.stdout, _s.stderr = _o, _e
    if 'matplotlib.pyplot' in _s.modules:
        _s.modules['matplotlib.pyplot'].close('all')   # their plots belong to their own blocks
_pm_run_earlier(_pm_earlier, globals())
del _pm_earlier, _pm_run_earlier

x and y of different lengths. ax.plot([1, 2, 3], [5, 6]) raises a ValueError. Each x value needs a y value.

Assigning to a method. ax.set_title = "Sales" does not set the title. It replaces the method with a string, and the next ax.set_title("Sales") raises a TypeError. Call it: ax.set_title("Sales").

Found this useful? Share it with a friend who’s learning Python.