RuntimeError: Invalid DISPLAY variable - python

I am running my python script in another machine by using ssh command in linux. I have also run this command :
source ~/.bashrc
after logging in the other machine, in order to define the proper paths in the new machine. I was getting the error message for running the following python code lines even I have tried to follow the instruction in this question by defining the backend.
>>> import matplotlib
>>> import pylab as plt
>>> matplotlib.use('Agg')
>>> import numpy as np
>>> x=np.arange(0,2,0.001)
>>> y=np.sin(x)**2+4*np.cos(x)
>>> fig = plt.figure()
>>> plt.plot(x,y,'r.')
The error message
This probably means that Tcl wasn't installed properly.
Traceback (most recent call last):
File "Systematic_Optimised.py", line 513, in <module>
fig = plt.figure()
File "/vol/anaconda/lib/python2.7/site-packages/matplotlib/pyplot.py", line 435, in figure
**kwargs)
File "/vol/anaconda/lib/python2.7/site-packages/matplotlib/backends/backend_qt4agg.py", line 47, in new_figure_manager
return new_figure_manager_given_figure(num, thisFig)
File "/vol/anaconda/lib/python2.7/site-packages/matplotlib/backends/backend_qt4agg.py", line 54, in new_figure_manager_given_figure
canvas = FigureCanvasQTAgg(figure)
File "/vol/anaconda/lib/python2.7/site-packages/matplotlib/backends/backend_qt4agg.py", line 72, in __init__
FigureCanvasQT.__init__(self, figure)
File "/vol/aibn84/data2/zahra/anaconda/lib/python2.7/site-packages/matplotlib/backends/backend_qt4.py", line 68, in __init__
_create_qApp()
File "/vol/anaconda/lib/python2.7/site-packages/matplotlib/backends/backend_qt5.py", line 138, in _create_qApp
raise RuntimeError('Invalid DISPLAY variable')
RuntimeError: Invalid DISPLAY variable
any suggestion how to fix the problem

You must declare matplotlib.use('agg') before import pylab as plt.
Reference

Add
plt.switch_backend('agg')
after
import matplotlib.pyplot as plt

Related

pandas plot, vars() argument must have __dict__ attribute?

It was working perfectly earlier but for some reason now I am getting strange errors.
pandas version: 1.2.3
matplotlib version: 3.7.0
sample dataframe:
df
cap Date
0 1 2022-01-04
1 2 2022-01-06
2 3 2022-01-07
3 4 2022-01-08
df.plot(x='cap', y='Date')
plt.show()
df.dtypes
cap int64
Date datetime64[ns]
dtype: object
I get a traceback:
Traceback (most recent call last):
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/code.py", line 90, in runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
File "/Volumes/coding/venv/lib/python3.8/site-packages/pandas/plotting/_core.py", line 955, in __call__
return plot_backend.plot(data, kind=kind, **kwargs)
File "/Volumes/coding/venv/lib/python3.8/site-packages/pandas/plotting/_matplotlib/__init__.py", line 61, in plot
plot_obj.generate()
File "/Volumes/coding/venv/lib/python3.8/site-packages/pandas/plotting/_matplotlib/core.py", line 279, in generate
self._setup_subplots()
File "/Volumes/coding/venv/lib/python3.8/site-packages/pandas/plotting/_matplotlib/core.py", line 337, in _setup_subplots
fig = self.plt.figure(figsize=self.figsize)
File "/Volumes/coding/venv/lib/python3.8/site-packages/matplotlib/_api/deprecation.py", line 454, in wrapper
return func(*args, **kwargs)
File "/Volumes/coding/venv/lib/python3.8/site-packages/matplotlib/pyplot.py", line 813, in figure
manager = new_figure_manager(
File "/Volumes/coding/venv/lib/python3.8/site-packages/matplotlib/pyplot.py", line 382, in new_figure_manager
_warn_if_gui_out_of_main_thread()
File "/Volumes/coding/venv/lib/python3.8/site-packages/matplotlib/pyplot.py", line 360, in _warn_if_gui_out_of_main_thread
if _get_required_interactive_framework(_get_backend_mod()):
File "/Volumes/coding/venv/lib/python3.8/site-packages/matplotlib/pyplot.py", line 208, in _get_backend_mod
switch_backend(rcParams._get("backend"))
File "/Volumes/coding/venv/lib/python3.8/site-packages/matplotlib/pyplot.py", line 331, in switch_backend
manager_pyplot_show = vars(manager_class).get("pyplot_show")
TypeError: vars() argument must have __dict__ attribute
In fact, this problem may cause if you running your code like default script (or in PyCharm interactive console), not in Jupyter.
If it is true, you can fix this error by setting up backend directly in your file with use function:
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.use('TkAgg') # !IMPORTANT
fig, ax = plt.subplots()
res = ax.plot([1, 2, 3, 4], [1, 4, 2, 3]) # Plt some data on the axes.o
# plt.show() # optionally show the result.
In some cases TkAgg may not be available. When firstly check, which backend you use. for this, run this simple code:
import matplotlib as mpl
print(mpl.get_backend())
BUT! this must be runned just by your hands in default terminal, outside of PyCharm. (e.g create simple test.py file, paste code, and run python test.py)
Why? Because PyCharm (at least in scientific projects) runs all files with interactive console, where backend module://backend_interagg is used. And this backend causes same error as you have.
So. add mpl.use('TkAgg') in head of your file, or checkout which backend you can use and past those name in this function.

Prevent mocked definition from bleeding over to external library in python

Suppose I have some third-party code main.py:
import matplotlib.pyplot as plt
import tkinter
tk = tkinter.Tk()
fig = plt.figure()
ax = plt.gca()
ax.plot([1,2,3])
plt.savefig('test.png')
Suppose that, in order to test this code, I need to creat a mock Tk class and replace the definition in main with it in a file called mock_main.py:
import tkinter
class Tk:
pass
tkinter.Tk = Tk
import main
Now, if I run python mock_main.py, I get an error:
Traceback (most recent call last):
File "C:\Users\user\desktop\temp\compare_mpl_backends\mock_main.py", line 8, in <module>
import main
File "C:\Users\user\desktop\temp\compare_mpl_backends\main.py", line 6, in <module>
fig = plt.figure()
File "C:\Users\user\Miniconda3\envs\temp\lib\site-packages\matplotlib\pyplot.py", line 787, in figure
manager = new_figure_manager(
File "C:\Users\user\Miniconda3\envs\temp\lib\site-packages\matplotlib\pyplot.py", line 306, in new_figure_manager
return _backend_mod.new_figure_manager(*args, **kwargs)
File "C:\Users\user\Miniconda3\envs\temp\lib\site-packages\matplotlib\backend_bases.py", line 3494, in new_figure_manager
return cls.new_figure_manager_given_figure(num, fig)
File "C:\Users\user\Miniconda3\envs\temp\lib\site-packages\matplotlib\backends\_backend_tk.py", line 925, in new_figure_manager_given_figure
window = tk.Tk(className="matplotlib")
TypeError: Tk() takes no arguments
I understand why this error occurs. matplotlib also depends on tkinter.Tk, so when I override it in mock_main.py, it basically breaks the matplotlib code.
I want to leave matplotlib alone, namely allowing it to use the true definition of Tk. However, for the third party code main.py, I want to use my (mock) definition.
Is there any elegant way to achieve this in python without modifying the contents of main.py?

Add world street map to basemap

I am having problems with basemap - arcgisimage function. Sample code below
...
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from PIL import Image
m = Basemap(
llcrnrlat=40.361369, llcrnrlon=-80.0955278,
urcrnrlat=40.501368, urcrnrlon=-79.865723,
epsg = 2272
)
#m.arcgisimage(service='ESRI_StreetMap_World_2D'
, xpixels=7000, verbose=True)
m.arcgisimage(service='World_Physical_Map', xpixels=7000, ypixels=None, dpi=96,verbose=True)
#m.arcgisimage(service='ESRI_Imagery_World_2D', xpixels=7000, verbose=True)
plt.show()
...
when I run this the arcgisimage() function crashes in PIL with error message
Traceback (most recent call last):
File "C:\Machine Learning\Geospatial\pittsburgh_map.py", line 11, in <module>
m.arcgisimage(service='World_Physical_Map', xpixels=7000, ypixels=None, dpi=96,verbose=True)
File "C:\Users\peter\AppData\Local\Programs\Python\Python38\lib\site-packages\mpl_toolkits\basemap\__init__.py", line 4263, in arcgisimage
return self.imshow(imread(urlopen(basemap_url)),ax=ax,
File "C:\Users\peter\AppData\Local\Programs\Python\Python38\lib\site-packages\matplotlib\image.py", line 1490, in imread
with img_open(fname) as image:
File "C:\Users\peter\AppData\Local\Programs\Python\Python38\lib\site-packages\PIL\ImageFile.py", line 121, in __init__
self._open()
File "C:\Users\peter\AppData\Local\Programs\Python\Python38\lib\site-packages\PIL\PngImagePlugin.py", line 692, in _open
cid, pos, length = self.png.read()
File "C:\Users\peter\AppData\Local\Programs\Python\Python38\lib\site-packages\PIL\PngImagePlugin.py", line 162, in read
pos = self.fp.tell()
io.UnsupportedOperation: seek
I had the same problem, most probably you have installed it using conda. I deinstalled the basemap module and reinstalled it with pip. then everything worked normally
If you followed the basemap installation instructions, then any issues you have with running basemap will probably remain unfixed as it is is deprecated in favor of cartopy https://github.com/matplotlib/basemap.

Can't use pyplot due to _tkinter.TclError: unknown color name

I've got a simple code:
from matplotlib import pyplot as plt
plt.plot([1,2,5])
plt.show()
It works fine in jupyter notebook, however when I try to run it using command line:
$ python3 main.py
It throws an error:
_tkinter.TclError: unknown color name "[97]#282a36"
The whole trackeback:
Traceback (most recent call last):
File "main.py", line 2, in <module>
plt.plot([1,2,5])
File "/home/user/.local/lib/python3.6/site-packages/matplotlib/pyplot.py", line 2811, in plot
return gca().plot(
File "/home/user/.local/lib/python3.6/site-packages/matplotlib/pyplot.py", line 935, in gca
return gcf().gca(**kwargs)
File "/home/user/.local/lib/python3.6/site-packages/matplotlib/pyplot.py", line 578, in gcf
return figure()
File "/home/user/.local/lib/python3.6/site-packages/matplotlib/pyplot.py", line 525, in figure
**kwargs)
File "/home/user/.local/lib/python3.6/site-packages/matplotlib/backend_bases.py", line 3218, in new_figure_manager
return cls.new_figure_manager_given_figure(num, fig)
File "/home/user/.local/lib/python3.6/site-packages/matplotlib/backends/_backend_tk.py", line 1008, in new_figure_manager_given_figure
window = Tk.Tk(className="matplotlib")
File "/usr/lib/python3.6/tkinter/__init__.py", line 2023, in __init__
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: unknown color name "[97]#282a36"
I already tried changing matplotlib's backend:
import matplotlib
matplotlib.use('pdf') # Or using other arguments matplotlib.use('Agg')
import matplotlib.pyplot as plt
plt.plot([1,2,5])
plt.show()
It gives me the same error message.
I also tried installing matplotlib using pip and my distribution package manager, both giving me the same error.
tkinter has been installed from my distribution repositories.
Any suggest would be helpful, I couldn't find any solution on similar questions.
After reading this issue on matplotlib's Github page, I emptied out my .Xresources and it fixed the issue.
So I looked a little bit more into the .Xresources file and I found out a line:
*background: [97]#282a36
Which was the cause of matplotlib complaining about a color nameed: [97]#282a36:
_tkinter.TclError: unknown color name "[97]#282a36"
Removing [97] from the line fixed the issue. remember that you have to run:
xrdb -merge .Xresources
To make the changes take place.

Running a python script with cron, matplotlib error

I am trying to run a python script using cron. The script runs without issue from the command line but has problems with matplotlib when run from cron. The error is below.
Traceback (most recent call last):
File "/home/ubuntu/python/spread.py", line 154, in <module>
plot_spread(lat, lon, vals, mean, maxs, mins, stdp, stdm, ens_members)
File "/home/ubuntu/python/spread.py", line 81, in plot_spread
plt.fill_between(x, maxs, stdp, color='r', alpha=0.2)
File "/usr/lib/python2.7/dist-packages/matplotlib-1.5.0_818.gfd83789-py2.7-linux-x86_64.egg/matplotlib/pyplot.py", line 2785, in fill_between
ax = gca()
File "/usr/lib/python2.7/dist-packages/matplotlib-1.5.0_818.gfd83789-py2.7-linux-x86_64.egg/matplotlib/pyplot.py", line 928, in gca
return gcf().gca(**kwargs)
File "/usr/lib/python2.7/dist-packages/matplotlib-1.5.0_818.gfd83789-py2.7-linux-x86_64.egg/matplotlib/pyplot.py", line 578, in gcf
return figure()
File "/usr/lib/python2.7/dist-packages/matplotlib-1.5.0_818.gfd83789-py2.7-linux-x86_64.egg/matplotlib/pyplot.py", line 527, in figure
**kwargs)
File "/usr/lib/python2.7/dist-packages/matplotlib-1.5.0_818.gfd83789-py2.7-linux-x86_64.egg/matplotlib/backends/backend_qt4agg.py", line 46, in new_figure_manager
return new_figure_manager_given_figure(num, thisFig)
File "/usr/lib/python2.7/dist-packages/matplotlib-1.5.0_818.gfd83789-py2.7-linux-x86_64.egg/matplotlib/backends/backend_qt4agg.py", line 53, in new_figure_manager_given_figure
canvas = FigureCanvasQTAgg(figure)
File "/usr/lib/python2.7/dist-packages/matplotlib-1.5.0_818.gfd83789-py2.7-linux-x86_64.egg/matplotlib/backends/backend_qt4agg.py", line 76, in __init__
FigureCanvasQT.__init__(self, figure)
File "/usr/lib/python2.7/dist-packages/matplotlib-1.5.0_818.gfd83789-py2.7-linux-x86_64.egg/matplotlib/backends/backend_qt4.py", line 68, in __init__
_create_qApp()
File "/usr/lib/python2.7/dist-packages/matplotlib-1.5.0_818.gfd83789-py2.7-linux-x86_64.egg/matplotlib/backends/backend_qt5.py", line 138, in _create_qApp
raise RuntimeError('Invalid DISPLAY variable')
RuntimeError: Invalid DISPLAY variable
I got a similar error when I tried to import matplotlib.pyplot in python using cron. You can force matplotlib to not use any Xwindows backend. Do this:
import matplotlib as mpl
mpl.use('Agg')
import matplotlib.pyplot as plt
These links might be also helpful:
Generating a PNG with matplotlib when DISPLAY is undefined
Generating matplotlib graphs without a running X server
Hope this is helpful!

Categories

Resources