Matplotlib Not Showing Plot: Fix It in VS Code, Jupyter or a Script

When Matplotlib is not showing a plot, there are only three real causes, and two lines of code tell you which one you have:

import matplotlib
print(matplotlib.get_backend())
  • Prints Agg — the backend cannot open windows. This is the usual answer.
  • Prints TkAgg, QtAgg or similar — the backend is fine, so you’re missing plt.show().
  • You are on a server, WSL or SSH — there is no display to draw on at all.

The screenshots on this page are real Command Prompt sessions on Python 3.12.5, Matplotlib 3.11.2.

Check your Matplotlib backend first

Don’t change any code until you know which backend is loaded. Run this on its own:

import matplotlib
import matplotlib.pyplot as plt

print("backend        :", matplotlib.get_backend())
print("interactive    :", plt.isinteractive())

# Anything ending in "Agg" on its own draws to a file, never to a window.
if matplotlib.get_backend().lower() == "agg":
    print("\n>>> This backend cannot open a window. That is your problem.")
else:
    print("\n>>> This backend can open a window.")

Output:

backend        : qtagg
interactive    : False

>>> This backend can open a window.
Command Prompt showing matplotlib get_backend printing qtagg and confirming the backend can open a window
On this machine the backend is qtagg, so windows work.

A backend whose name is exactly Agg is a file-only renderer. It has no window code in it at all.

Names like TkAgg and QtAgg also end in Agg, but the prefix is the part that matters. Those do open windows.

Why plt.show() does nothing and prints no error

This is what makes it so confusing. On Agg, plt.show() succeeds and draws nothing, so there’s nothing to search for:

import warnings
import matplotlib
matplotlib.use("Agg")              # force the file-only backend
import matplotlib.pyplot as plt

plt.plot([1, 2, 3])

with warnings.catch_warnings(record=True) as caught:
    warnings.simplefilter("always")
    plt.show()
    for w in caught:
        print("WARNING:", w.message)

print("\nplt.show() returned normally and drew nothing.")
print("open figures:", plt.get_fignums(), "<- the figure still exists")

Output:

WARNING: FigureCanvasAgg is non-interactive, and thus cannot be shown

plt.show() returned normally and drew nothing.
open figures: [1] <- the figure still exists
Command Prompt showing the UserWarning that FigureCanvasAgg is non-interactive and thus cannot be shown
The warning is the whole diagnosis: non-interactive, and thus cannot be shown.

Matplotlib does warn you. The trouble is that a UserWarning scrolls past in a wall of output, and plenty of setups suppress warnings entirely.

Note that the figure is still open afterwards. Nothing was destroyed, so you can call savefig and get a perfectly good image.

Matplotlib not showing plot in VS Code

VS Code is the most common place this bites, and the cause is almost always the interpreter rather than VS Code itself.

When you run a file with the play button, VS Code uses the interpreter shown in the status bar. If that environment has no GUI toolkit, Matplotlib silently falls back to Agg:

import importlib.util

# Matplotlib can only open a window if one of these is importable
for module in ("tkinter", "PyQt6", "PyQt5", "PySide6"):
    found = importlib.util.find_spec(module) is not None
    print(f"{module:<10} {'installed' if found else 'NOT installed'}")

import matplotlib
print("\nmatplotlib chose:", matplotlib.get_backend())

Output:

tkinter    installed
PyQt6      installed
PyQt5      NOT installed
PySide6    NOT installed

matplotlib chose: qtagg
Command Prompt listing which GUI toolkits are installed and which backend matplotlib selected as a result
Matplotlib needs at least one of these importable before it can open a window.
  1. Open the Command Palette and run Python: Select Interpreter, then pick the environment you installed Matplotlib into.
  2. Run the snippet above in that same interpreter to confirm a toolkit is present.
  3. If none is, install one: pip install PyQt6 works everywhere, and on Linux sudo apt install python3-tk restores tkinter.
  4. Restart the terminal so VS Code reloads the environment.

One more VS Code trap. Code run in the Interactive Window or a .ipynb renders plots inline instead of in a window, so a missing window there is expected behaviour.

plt.show() not working in a Python script

If the backend is fine, the script itself is usually the problem. A plot only appears when plt.show() runs:

import matplotlib.pyplot as plt

plt.figure(figsize=(7, 4))
plt.plot([1, 2, 3, 4], [1, 4, 2, 5], marker="o", lw=2, color="#0b6bcb")
plt.title("If you can see this window, your backend is fine")
plt.grid(alpha=.3)
plt.tight_layout()

plt.show()          # blocks until you close the window
print("this line runs only after the window is closed")

Output:

this line runs only after the window is closed
A Matplotlib plot window opened successfully from a Python script showing a blue line with markers
A real window. The script pauses on show() until you close it.
What you wroteWhat happens
No plt.show()The script ends and the figure is discarded
plt.show()Blocks until you close the window
plt.show(block=False)Returns at once, so the script exits and the window vanishes
plt.close() before show()There is no figure left to display

The block=False case catches people out. The window flashes up for a fraction of a second, which looks identical to nothing happening at all.

If a window does open but comes out empty, that is a different fault. See blank Matplotlib images for that one.

Matplotlib plot not showing in Jupyter Notebook

Notebooks render plots inline, so plt.show() is not what is missing. Work through these instead:

  • Put the plotting code and plt.show() in the same cell. A figure does not survive to the next one.
  • Add %matplotlib inline at the top if an older notebook or a custom kernel has changed the default.
  • Use %matplotlib widget for zoomable plots, which needs ipympl installed.
  • Check the kernel in the top right is the environment you installed Matplotlib into.

A cell that ends in plt.plot(...) without plt.show() also prints a line of object repr above the chart. Adding plt.show() or a trailing semicolon removes it.

Why does plt.show() do nothing on a server or in WSL?

Because there is no display for a window to open on. A headless Linux box, a Docker container and a plain SSH session all have this in common.

Don’t fight it. Draw to a file instead, which is what Agg is built for:

import matplotlib
matplotlib.use("Agg")           # no display available: draw to a file instead
import matplotlib.pyplot as plt
import os

plt.figure(figsize=(6, 3.5))
plt.plot([1, 2, 3], [4, 1, 5], marker="o")
plt.title("Saved, not shown")
plt.tight_layout()

plt.savefig("plot.png", dpi=120)
print("written:", os.path.abspath("plot.png"))
print("size   :", os.path.getsize("plot.png"), "bytes")

Output:

written: C:\pyguides\runs\notshowing\plot.png
size   : 28879 bytes
Command Prompt showing matplotlib writing a plot to a PNG file with the Agg backend on a headless machine
matplotlib.use("Agg") before importing pyplot, then savefig.

Set the backend before import matplotlib.pyplot. Once pyplot has loaded, switching isn’t reliable.

If you genuinely need a window over SSH, enable X11 forwarding with ssh -X and install a toolkit on the remote machine. On WSL, WSLg handles this on Windows 11 without extra setup.

pandas .plot() not showing a chart

DataFrame.plot() is Matplotlib underneath, so it inherits every cause above. It adds one of its own:

df.plot(kind="line")
plt.show()          # pandas returns an Axes, it does not call show() for you

In a script, df.plot() builds the figure and hands back an Axes. Nothing appears until you call plt.show() yourself. The same applies when you draw a scatter plot from a DataFrame.

Matplotlib not showing plot: every fix at a glance

SymptomCauseFix
get_backend() says AggNo GUI toolkit in this environmentpip install PyQt6
Nothing happens, no errorMissing plt.show()Add it at the end
Window flashes and closesblock=FalseDrop the argument
Works in terminal, not VS CodeWrong interpreter selectedPython: Select Interpreter
Nothing in a notebookPlot split across cellsKeep it in one cell
Nothing over SSH or DockerNo display availableUse savefig

More Matplotlib troubleshooting guides:

Frequently asked questions

Why is Matplotlib not showing my plot?

Nearly always because the backend is Agg, which draws to files and cannot open windows. Check it with matplotlib.get_backend(). The backends are listed in the Matplotlib backend documentation.

Why does plt.show() do nothing?

On a non-interactive backend it returns without drawing, and only emits a UserWarning saying FigureCanvasAgg is non-interactive, and thus cannot be shown.

Why is Matplotlib not showing plots in VS Code?

The selected interpreter usually has no GUI toolkit installed, so Matplotlib falls back to Agg. Run Python: Select Interpreter, then install PyQt6 in that environment.

How do I change the Matplotlib backend?

Call matplotlib.use("QtAgg") before you import matplotlib.pyplot. Switching afterwards is unreliable.

Why does my plot window open and close instantly?

You called plt.show(block=False) and the script then ended. Remove the argument so the call blocks.

How do I show a plot on a headless server?

You cannot. Use matplotlib.use("Agg") and plt.savefig("plot.png"), then copy the file off the machine.

Why is my pandas plot not showing?

DataFrame.plot() returns an Axes and does not display anything by itself. Call plt.show() after it.