Automatic detection of display availability with matplotlib
You can detect directly if you have a display with the OS module in python.
in my case it's
>>> import os
>>> os.environ["DISPLAY"]
':0.0'
Why does this solve the 'no $DISPLAY environment' issue with matplotlib?
X11 follows a client/server model, where the X server accepts requests for graphical output from client applications (e.g. interactive matplotlib sessions), and sends back user input from the keyboard, mouse etc. In order for this model to work, client applications need to know which X server to send their requests to. This is controlled by the $DISPLAY
environment variable. In the case where you are connecting to a remote X session (for example over an SSH connection), the $DISPLAY
variable in your remote session needs to point to your local X server.
The $DISPLAY
variable is structured like this:
hostname:displaynumber.screennumber
Not all parts may be present - the hostname is usually omitted for local sessions, and the screen number is also omitted if there is only one screen. In a local terminal session on laptop, my $DISPLAY
looks like this:
alistair@laptop:~$ echo $DISPLAY
:0
Provided that the remote server also supports X11, it's possible to open graphical windows on the remote machine and have them appear on your local machine using X11 forwarding. For an SSH connection you do this by passing the -X
(or -Y
) flag.
For example:
alistair@laptop:~$ ssh -X alistair@workstation.address.co.uk
alistair@workstation:~$ echo $DISPLAY
localhost:10.0
The remote SSH server should take care of setting the $DISPLAY
variable appropriately when you open the connection. In this particular case, localhost:10.0
is actually a 'proxy' X11 server running on the remote machine that listens on display 10 and relays commands to your local X server over the SSH connection (take a look at this if you're interested in the details).
Now you should be able to start a remote IPython session, import matplotlib using an interactive backend, and create plot windows which will then appear on your local machine. Since your keyboard/mouse input and the display output are now passing over an encrypted network connection, the plot windows will be less responsive than you're used to for a local session.
Another word of warning: if you have an IPython session open with an interactive matplotlib session running it is impossible to close the SSH connection without killing the IPython process. I also sometimes call matplotlib.use("Agg")
before I start a long-running process that imports matplotlib - that way I can disconnect from the remote server without killing the process.
Generating matplotlib graphs without a running X server
@Neil's answer is one (perfectly valid!) way of doing it, but you can also simply call matplotlib.use('Agg')
before importing matplotlib.pyplot
, and then continue as normal.
E.g.
import matplotlib as mpl
mpl.use('Agg')
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(range(10))
fig.savefig('temp.png')
You don't have to use the Agg backend, as well. The pdf, ps, svg, agg, cairo, and gdk backends can all be used without an X-server. However, only the Agg backend will be built by default (I think?), so there's a good chance that the other backends may not be enabled on your particular install.
Alternately, you can just set the backend parameter in your .matplotlibrc
file to automatically have matplotlib.pyplot
use the given renderer.
UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure. when plotting figure with pyplot on Pycharm
Solution 1: is to install the GUI backend tk
I found a solution to my problem (thanks to the help of ImportanceOfBeingErnest).
All I had to do was to install tkinter
through the Linux bash terminal using the following command:
sudo apt-get install python3-tk
instead of installing it with pip
or directly in the virtual environment in Pycharm.
Solution 2: install any of the matplotlib
supported GUI backends
- solution 1 works fine because you get a GUI backend... in this case the
TkAgg
- however you can also fix the issue by installing any of the matplolib GUI backends like
Qt5Agg
,GTKAgg
,Qt4Agg
, etc- for example
pip install pyqt5
will fix the issue also
- for example
NOTE:
- usually this error appears when you pip install matplotlib and you are trying to display a plot in a GUI window and you do not have a python module for GUI display.
- The authors of
matplotlib
made the pypi software deps not depend on any GUI backend because some people needmatplotlib
without any GUI backend.
In python, determine if display support only text or if graphics are available
I've put together a small function to detect if a graphic card exists on windows
or linux
, i.e.:
import subprocess, os
def gc_available():
if os.name == 'nt': # Windows
import wmi
try:
wmi.WMI().computer.Win32_VideoController()[0] # Tested on Windows 10
return 1
except:
pass
elif os.name == 'posix': # Linux
out = subprocess.getoutput('sudo lshw -c video | grep configuration') # Tested on CENTOS 7 and Ubuntu
if out:
return 1
Usage:
if gc_available():
print("VideoController available")
else:
print("VideoController Not available")
How do I check if I'm running on Windows in Python?
Python os module
Specifically for Python 3.6/3.7:
os.name
: The name of the operating
system dependent module imported. The
following names have currently been
registered: 'posix', 'nt', 'java'.
In your case, you want to check for 'nt' as os.name
output:
import os
if os.name == 'nt':
...
There is also a note on os.name
:
See also
sys.platform
has a finer granularity.os.uname()
gives
system-dependent version information.The platform module provides
detailed checks for the system’s identity.
How do I get monitor resolution in Python?
On Windows:
from win32api import GetSystemMetrics
print("Width =", GetSystemMetrics(0))
print("Height =", GetSystemMetrics(1))
If you are working with high resolution screen, make sure your python interpreter is HIGHDPIAWARE.
Based on this post.
Related Topics
Cannot Bind Numpad Minus Key on Linux with Tkinter
I Cant Init Google Cloud Sdk on Ubuntu
Where Does Python Tempfile Writes Its Files
"Valueerror: _Type_ 'V' Not Supported" Error After Installing Pyreadline
Finding the Command for a Specific Pid in Linux from Python
Python & Ms Word: Convert .Doc to .Docx
Need a Way to Determine If a File Is Done Being Written To
How to Call Wine Dll from Python on Linux
How to Get Apache to Serve Static Files on Flask Webapp
Trouble Importing Tabulate in Python 3.4
Pairing Bluetooth Devices with Passkey/Password in Python - Rfcomm (Linux)
What's the Advantage of Queues Over Pipes When Communicating Between Processes
Create Single Python Executable Module
Python Requests, How to Specify Port for Outgoing Traffic
Importerror: Libtk8.6.So: Cannot Open Shared Object File: No Such File or Directory
How to Get Each Dependent Command Execution Output Using Paramiko Exec_Command