I have a python code doing some calculation on a remote machine, named A. I connect on A via ssh
from a machine named B.
Is there a way to display the figure on machine B?

- 14,898
- 17
- 60
- 85
-
Related: http://stackoverflow.com/questions/2801882/generating-a-png-with-matplotlib-when-display-is-undefined?lq=1 – 0 _ Feb 28 '14 at 05:48
11 Answers
Sure, you can enable X11 forwarding. Usually this is done by passing the -X
or -Y
option to ssh
when you connect to the remote computer
ssh -X computerA
Note that the SSH daemon on computer A will also have to be configured to enable X11 forwarding. This is done by putting
X11Forwarding yes
in computer A's sshd_config
configuration file.
If computer A's SSH daemon does not have X11 forwarding enabled, you can always have Python write the result of the calculation to a text file, download it to computer B, and use Matplotlib locally.

- 128,184
- 27
- 255
- 279
-
2
-
If you edit `/etc/ssh/sshd_config`, then make sure to restart the sshd and/or ssh service. Stupid simple way is to restart your computer, but (at least on linux) you can also restart the service using something like `sudo service sshd restart` as described here: https://www.cyberciti.biz/faq/howto-start-stop-ssh-server/ – wronk Oct 12 '17 at 16:42
-
There is additional helpful advice on this topic from Gilles, [here](https://unix.stackexchange.com/questions/12755/how-to-forward-x-over-ssh-to-run-graphics-applications-remotely). – Mike O'Connor Oct 05 '18 at 08:16
If you use matplotlib on Mac OS X on the remote machine (B), you must first make sure that you use one of the X11-based display back-ends, since the native Mac OS X back-end cannot export its plots to another display. Selecting a back-end can be achieved with
import matplotlib
matplotlib.use('GTK') # Or any other X11 back-end
The list of supported back-ends can be obtained by giving use()
an incorrect back-end name: matplotlib then prints an error message listing the possible back-ends.
ssh X11 forwarding can then be used to display matplotlib plots.

- 91,433
- 48
- 218
- 260
-
5It'll make you instal `pygtk` to do that, and it seems it's either impossible or a total pain to do that with Python 3. – sudo Jul 20 '17 at 23:26
-
1This definitely depend on your platform and package manager. On macOS, MacPorts has a py27-pygtk package that should make the install smooth for Python 2. – Eric O. Lebigot Jul 22 '17 at 13:17
-
4@sudo I checked all the supported back-ends. In my case, `TkAgg` and `GTK3Cairo` back-ends worked for Python 3. `TkAgg` seems to be faster. – epokhe Sep 09 '17 at 01:11
-
The following worked for me using Mac OS X on the local machine (machine B) and ubuntu on the remote (machine A).
You need X11 server installed on your local machine to do this.
If you're running a recent version of Mac OSX (OS X Mountain Lion or newer), it would NOT have come with X11 pre-installed (see http://support.apple.com/kb/ht5293). Check if you have X11 by opening up Mac terminal, and run command xterm
.
If an X11 window opens up, you're all set. If it says command not found, then go to http://xquartz.macosforge.org/landing/ and install X11 server. Then logout and log back in to your mac.
After you log back in, try to run xterm
command again. It should open up X11 window.
At this point your $DISPLAY variable should also be set correctly. If it's not set, make sure you've logged in/out since installing X11 from XQuartz.
echo $DISPLAY
/tmp/launch-I9I3aI/org.macosforge.xquartz:0
Then from your local machine, use ssh -X to remote into remote machine A:
ssh -X user@machineA
Then on the remote machine:
python
>>> import matplotlib
>>> matplotlib.use('GTKAgg') #I had to use GTKAgg for this to work, GTK threw errors
>>> import matplotlib.pyplot as plt #... and now do whatever you need...
Make sure you call matplotlib.use
BEFORE importing anything else from matplotlib
(e.g. matplotlib.pyplot
)
Other useful troubleshooting tips on using ssh -X : http://oroborosx.sourceforge.net/remotex.html#usessh

- 1,099
- 2
- 9
- 20
GTK seems impossible to get working on Ubuntu with Python3. Instead, I used tkagg (from this answer):
import matplotlib
matplotlib.use('tkagg')
import matplotlib.pyplot as plt
Test that it's working with this:
import matplotlib
matplotlib.use('tkagg')
import matplotlib.pyplot as plt
plt.plot([1, 2, 3])
plt.show()

- 13,746
- 5
- 87
- 117
-
I had lots of trouble with both gtk and qt, but this worked great! – Thomas Ahle Feb 04 '20 at 11:48
-
2That gives me: `TclError: no display name and no $DISPLAY environment variable`. Any ideas? – Cleb May 06 '20 at 09:38
-
Definitely it solved my problem using python 3.6. Unfortunately displaying the images works really slow, any ideas of how improve the speed. I used ssh -Y -C to access to my remote machine. – Mauricio Arboleda-Zapata May 15 '20 at 14:22
I have used IPython to solve the related problem. The steps are as follows:
Step 1: Install IPython and Jupyter in the remote machine (A) locally (assuming no root privilege) using the following commands:
pip install --user ipython
pip install --user jupyter
Update matplotlib:
pip install --user -U matplotlib
Step 2:
Run Jupyter with no browser from the code directory in the remote machine (A):
cd PATH/TO/THE/CODE
jupyter notebook --no-browser --port=8080
After this command, a URL will be given something similar to below:
http://localhost:8080/?token=5528ab1eeb3f621b90b63420f8bbfc510edf71f21437c4e2
Step 3:
Now open another terminal in the local machine (B) and connect to the remote machine (A) using ssh:
ssh -N -L 8080:localhost:8080 user_id@remote.host
The port number has to be same in step 2 and step 3. In this example, the port number is 8080.
Step 4:
Copy and paste the URL in the step 3 to a browser in your local machine (B).
Now, the notebook in the remote machine can be used through the browser and plot can be generated using the data in the remote machine.

- 149
- 1
- 7
-
1This isn't really a direct answer to the original question, but it's a hugely advantageous workaround. If you save figures on the remote machine, you can even open them in the notebook viewer! imo it's even better with jupyter lab. – vanPelt2 Jul 07 '20 at 02:36
export MPLBACKEND="agg"
this worked for me.
obviously you can set it via code as well.

- 1,692
- 17
- 16
if that doesn't work you could also try:
import matplotlib.pyplot as plt
plt.switch_backend('agg')
or
import matplotlib.pyplot as plt
plt.switch_backend('TkAgg')
this seemed to work for me
Yet, if you are trying to get a GUI working I suggest you look at this link: http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/

- 11
- 1
-
Welcome to [so].While adding link may answer the question, it is better to include the essential parts of the link here and provide the link for reference. – Morse Jul 09 '18 at 21:26
Just wanted to add - if you're on Windows as the local machine, make sure you've set up Xming (an X Windows server) and Putty so you can see the remote Linux graphical applications.
I followed the instructions from here: http://laptops.eng.uci.edu/software-installation/using-linux/how-to-configure-xming-putty to do this. It also sets your display environment and variable so you don't get an error when using tkagg
as the backend.

- 1,220
- 3
- 21
- 25
You can use the library I created to solve this problem https://pypi.org/project/remote-plot/.
It uses the exact same API as matplotlib, but it renders the plots in a web browser which you can view from your machine B.
Install by:
pip install remote_plot
And then run in python like this:
from remote_plot import plt
plt.plot([1, 2, 3], [4, 5, 6])
By default it opens the rendering on port 8000 but you can modify this easily. If you are connecting via ssh, don't forget to forward the port by adding the following flag to your ssh command:
ssh YOUR_USER_NAME@YOUR_MACHINE_IP -L 8000:localhost:8000

- 39
- 1
- 9
If you're using a mac as a client machine, try this.
You basically need to make sure two things are working properly.
- Using GTK or Cairo as
matplotlib
's backend. - Forwarding the display.
Using GTK or Cairo as matplotlib
's backend
If you're using python3
, you must install cairocffi
.
pip install cairocffi
Then use the GTK3Agg as a backend of matplotlib.
import matplotlib
matplotlib.use('GTK3Agg')
import matplotlib.pyplot as plt
See following description from matplotlib document for more detail.
Both GTK2 and GTK3 have implicit dependencies on PyCairo regardless of the specific Matplotlib backend used. Unfortunatly the latest release of PyCairo for Python3 does not implement the Python wrappers needed for the GTK3Agg backend. Cairocffi can be used as a replacement which implements the correct wrapper.
Forwarding the display
- Install launch the latest version of XQuartz.
- Connect to the remote server using
ssh -X
. ex)ssh username@ipaddress -X

- 195
- 1
- 1
- 10
This is what I did with MacOS and a Linux remote machine.
- In ~/.ssh/config I added the following. I add this since it's possible that your machine might not be taking the xauth location properly.
XAuthLocation /opt/X11/bin/xauth
- ssh -Y machine_name
- Ran the following dummy program:
import matplotlib.pyplot as plt
x = [1,2,3]
y = [2,4,1]
plt.plot(x, y)
plt.show()

- 147
- 4