2

I'm pretty new to Python. I have a simple script that shows a simple plot on the console. It works perfectly when I execute the script in VSCode, and the plots shows up as expected. However, when running the same script in Python in WSL, the plot doesn't show up, and I also don't get any error messages.

I'm on Windows 10.

Here is my code snippet that I typed directly in Python under WSL:

import matplotlib.pyplot as plt
x = [1,2,3,4,5]
y = [x**2 for x in x]
plt.plot(x,y)
[<matplotlib.lines.Line2D object at 0x7f57445be700>] # I get this message and I don't know what this means.
plt.show() # No error message, but the plot doesn't show up in my console.

Again, the plot shows up when I execute the script in VSCode.

How can I display the plot under WSL?

NotTheDr01ds
  • 15,620
  • 5
  • 44
  • 70
Max_CA
  • 21
  • 2
  • When I run your code in my terminal (on Mac), the plot appears in another window but not in the console itself. Is it possible that the plot _is_ opening, but is opening somewhere you are not looking? – jhschwartz Nov 05 '22 at 19:08
  • Add `plt.show()` statement at the end. And read Matplotlib docs, – Yuri Ginsburg Nov 05 '22 at 19:20
  • If you are running Bash inside WSL, it probably doesn't know how to talk to the Windows GUI. Or are you on Linux or a Mac? – tripleee Nov 05 '22 at 20:00
  • @jhschwartz that's my initial thought as well, but I don't see it anywhere. It's interesting because when I run the same code in regular command prompt (not bash), the plot shows up. – Max_CA Nov 05 '22 at 20:01
  • @tripleee that's exactly what i'm doing, I'm running Bash in WSL. I'm on Windows10. First time user of WSL/Bash too. Any other prompts to the WSL environment to show the plot? I tried adding plt.ion() but it didn't work – Max_CA Nov 05 '22 at 20:04
  • 1
    Thanks for the clarification. Going forward, please [edit] your question rather than respond in comments. – tripleee Nov 05 '22 at 20:09
  • I have little to no experience using WSL so I can't help with that unfortunately. What I can do, though, is *strongly* recommend that you use jupyter notebooks for plotting instead of trying to do it right from the command line. Or, download the ubuntu app on Windows--maybe that will make things easier. But if you must use WSL I wish you luck! – jhschwartz Nov 05 '22 at 22:53
  • @YuriGinsburg You know, it's odd that I missed it my first several read-throughs as well, but the original post *does* already have `plt.show()` at the end ;-). – NotTheDr01ds Nov 06 '22 at 17:20
  • @jhschwartz *"Or, download the ubuntu app on Windows"* -- The Ubuntu "app" (found in the Store) actually *is* running on WSL, unless you are referring to something else? – NotTheDr01ds Nov 06 '22 at 17:26

1 Answers1

1

Since you say that your MRE works in Visual Studio Code, I'm guessing:

  • You are using the Windows version of Python in VSCode
  • Or you are using Jupyter Notebooks there.

Edit: I just noticed your comment:

It's interesting because when I run the same code in regular command prompt (not bash), the plot shows up

So yes, it appears that you are also running the Windows version of Python. You can use WSL inside of VSCode, but that's not what you doing in this case, it seems.


Under WSL, there may be several things you need to do, depending on your Windows version:

  • First, Windows 11 is recommended here, since it includes built-in support for displaying Linux GUI applications.

    Older versions of WSL on Windows 10 do not support this directly. On Windows 10, you'll need to either install a third-party X server or use XRDP. The easiest way to do this (other than Windows 11) is with Xfce4 + XRDP, but it's definitely the slowest method as well. Also see my answer on What's the easiest way to run GUI apps on Windows Subsystem for Linux?.

    Since you are on Windows 10, you'll have to get GUI support working first on WSL. Test with something like xterm to make sure you have it working) and then come back here.


[<matplotlib.lines.Line2D object at 0x7f57445be700>]

I get this message and I don't know what this means.

That's an easy one. When you are entering code directly into the Python REPL, it will always show the value/return-result for each line. All of the other lines that you typed up to that point either had no return result or you stored the return value in a variable. In the doc, you'll notice that the return value from plot is a "list of Line2D" objects.

You could suppress the message by simply storing the result in a variable, but there's no need for this in the REPL.


plt.show()

No error message, but the plot doesn't show up in my console.

Hmmm. When I try that in a base Ubuntu 22.04 distribution under WSL, I do get an error message:

<stdin>:1: UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure.

Since you aren't receiving an error, it appears (from the doc) that Matplotlib is detecting some GUI environment and auto-selecting a higher-precedent backend because of this:

Without a backend explicitly set, Matplotlib automatically detects a usable backend based on what is available on your system and on whether a GUI event loop is already running. The first usable backend in the following list is selected: MacOSX, QtAgg, GTK4Agg, Gtk3Agg, TkAgg, WxAgg, Agg. The last, Agg, is a non-interactive backend that can only write to files. It is used on Linux, if Matplotlib cannot connect to either an X display or a Wayland display.

But I don't know why you aren't getting an error (but also no display) on that backend. It might be useful to run plt.get_backend() to see which backend Matplotlib has auto-selected. For me, on a freshly installed Ubuntu, that's agg, but it sounds like that's going to be different for you.


Regardless, that brings us to the next likely step -- Make sure that all dependencies for a Matplotlib GUI backend are enabled. This includes:

  • The Linux libraries needed for the selected backend.
  • The Python modules needed for the selected backend.

On a typical Ubuntu installation, the Linux libraries would already be installed, since Linux desktop installations are running GUI's. However, the Ubuntu/WSL distributions are based on Ubuntu Server, and don't include any graphical apps out-of-the-box.

Assuming you want to use the Qt5 backend, which is the highest priority other than Mac in the Matplotlib auto-select list, we'll need to install those libraries:

sudo apt install libqt5gui5

Then, as per this answer, you'll need the Python support for Qt5:

# Don't do this yet.  Read next step.
pip install pyqt5

Note: It's recommended that you do this in a virtual environment (venv) so that you don't "pollute" your system Python installation with unnecessary libraries. Since you are new to Python, I'm going to recommend that you read-up on Python virtual environments, but here's the summary to get started:

sudo apt install python3-venv
cd <project_dir>
python3 -m venv .venv
source .venv/bin/activate

Your prompt should change to include (.venv) to show that the environment is active.

Then, anything you pip install will be in that virtual environment rather than your system environment:

# Now we can do this "safely"
pip install pyqt5
python3

With this in place, try your code again. Hopefully, you should now see that plt.get_backend() returns qtAgg. If not, then there's additional troubleshooting to do.

And with that in place, plt.plot() should (it does for me) display the plot directly on the screen.

NotTheDr01ds
  • 15,620
  • 5
  • 44
  • 70