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,QtAggor similar — the backend is fine, so you’re missingplt.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.
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
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
- Open the Command Palette and run Python: Select Interpreter, then pick the environment you installed Matplotlib into.
- Run the snippet above in that same interpreter to confirm a toolkit is present.
- If none is, install one:
pip install PyQt6works everywhere, and on Linuxsudo apt install python3-tkrestores tkinter. - 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
show() until you close it.| What you wrote | What 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 inlineat the top if an older notebook or a custom kernel has changed the default. - Use
%matplotlib widgetfor zoomable plots, which needsipymplinstalled. - 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
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
| Symptom | Cause | Fix |
|---|---|---|
get_backend() says Agg | No GUI toolkit in this environment | pip install PyQt6 |
| Nothing happens, no error | Missing plt.show() | Add it at the end |
| Window flashes and closes | block=False | Drop the argument |
| Works in terminal, not VS Code | Wrong interpreter selected | Python: Select Interpreter |
| Nothing in a notebook | Plot split across cells | Keep it in one cell |
| Nothing over SSH or Docker | No display available | Use savefig |
More Matplotlib troubleshooting guides:
- No module named matplotlib
- Install Matplotlib properly
- Matplotlib savefig produces a blank image
- matplotlib.pyplot could not be resolved
- Scatter marker shape, size and colour
- Scatter plots from a pandas DataFrame
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.
Bijay Kumar is a 13-time Microsoft MVP with more than 18 years in software development, and the founder of Python Guides and TSinfo Technologies. He started out building .NET and SharePoint solutions at HP, TCS and KPIT before moving into Python, machine learning and AI, and he also builds web apps with TypeScript and React. He writes the tutorials here himself, and every example is run before publishing so you see the real output. More about Bijay · Microsoft MVP profile · LinkedIn