Repository navigation
Closed
Labels
Milestone
Description
Bug summary
matplotlib using 'module://backend_interagg' as backend on Windows, causes the error below. Was not an issue prior to 3.7.0 version release. Fixed by using matplotlib.use("TkAgg").
Code for reproduction
import matplotlib.pyplot as plt
plt.clf()Actual outcome
..\ael_abaqus\access.py:119: in run
plotting_inst.plot_set("Reaction", y_data)
..\ael_abaqus\access_plotting.py:223: in plot_set
p = Plot2D()
..\ael_abaqus\access_plot2d.py:25: in _init_
plt.clf()
..\venv\lib\site-packages\matplotlib\pyplot.py:970: in clf
gcf().clear()
..\venv\lib\site-packages\matplotlib\pyplot.py:879: in gcf
return figure()
..\venv\lib\site-packages\matplotlib\_api\deprecation.py:454: in wrapper
return func(*args, **kwargs)
..\venv\lib\site-packages\matplotlib\pyplot.py:813: in figure
manager = new_figure_manager(
..\venv\lib\site-packages\matplotlib\pyplot.py:382: in new_figure_manager
_warn_if_gui_out_of_main_thread()
..\venv\lib\site-packages\matplotlib\pyplot.py:360: in _warn_if_gui_out_of_main_thread
if _get_required_interactive_framework(_get_backend_mod()):
..\venv\lib\site-packages\matplotlib\pyplot.py:208: in _get_backend_mod
switch_backend(rcParams._get("backend"))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
newbackend = 'module://backend_interagg'
def switch_backend(newbackend):
"""
Set the pyplot backend.
Switching to an interactive backend is possible only if no event loop for
another interactive backend has started. Switching to and from
non-interactive backends is always possible.
If the new backend is different than the current backend then all open
Figures will be closed via ``plt.close('all')``.
Parameters
----------
newbackend : str
The case-insensitive name of the backend to use.
"""
global _backend_mod
# make sure the init is pulled up so we can assign to it later
import matplotlib.backends
if newbackend is rcsetup._auto_backend_sentinel:
current_framework = cbook._get_running_interactive_framework()
mapping = {'qt': 'qtagg',
'gtk3': 'gtk3agg',
'gtk4': 'gtk4agg',
'wx': 'wxagg',
'tk': 'tkagg',
'macosx': 'macosx',
'headless': 'agg'}
best_guess = mapping.get(current_framework, None)
if best_guess is not None:
candidates = [best_guess]
else:
candidates = []
candidates += [
"macosx", "qtagg", "gtk4agg", "gtk3agg", "tkagg", "wxagg"]
# Don't try to fallback on the cairo-based backends as they each have
# an additional dependency (pycairo) over the agg-based backend, and
# are of worse quality.
for candidate in candidates:
try:
switch_backend(candidate)
except ImportError:
continue
else:
rcParamsOrig['backend'] = candidate
return
else:
# Switching to Agg should always succeed; if it doesn't, let the
# exception propagate out.
switch_backend("agg")
rcParamsOrig["backend"] = "agg"
return
# have to escape the switch on access logic
old_backend = dict._getitem_(rcParams, 'backend')
backend_mod = importlib.import_module(
cbook._backend_module_name(newbackend))
required_framework = _get_required_interactive_framework(backend_mod)
if required_framework is not None:
current_framework = cbook._get_running_interactive_framework()
if (current_framework and required_framework
and current_framework != required_framework):
raise ImportError(
"Cannot load backend {!r} which requires the {!r} interactive "
"framework, as {!r} is currently running".format(
newbackend, required_framework, current_framework))
# Load the new_figure_manager() and show() functions from the backend.
# Classically, backends can directly export these functions. This should
# keep working for backcompat.
new_figure_manager = getattr(backend_mod, "new_figure_manager", None)
show = getattr(backend_mod, "show", None)
# In that classical approach, backends are implemented as modules, but
# "inherit" default method implementations from backend_bases._Backend.
# This is achieved by creating a "class" that inherits from
# backend_bases._Backend and whose body is filled with the module globals.
class backend_mod(matplotlib.backend_bases._Backend):
locals().update(vars(backend_mod))
# However, the newer approach for defining new_figure_manager and
# show is to derive them from canvas methods. In that case, also
# update backend_mod accordingly; also, per-backend customization of
# draw_if_interactive is disabled.
if new_figure_manager is None:
# Only try to get the canvas class if have opted into the new scheme.
canvas_class = backend_mod.FigureCanvas
def new_figure_manager_given_figure(num, figure):
return canvas_class.new_manager(figure, num)
def new_figure_manager(num, *args, FigureClass=Figure, **kwargs):
fig = FigureClass(*args, **kwargs)
return new_figure_manager_given_figure(num, fig)
def draw_if_interactive():
if matplotlib.is_interactive():
manager = _pylab_helpers.Gcf.get_active()
if manager:
manager.canvas.draw_idle()
backend_mod.new_figure_manager_given_figure = \
new_figure_manager_given_figure
backend_mod.new_figure_manager = new_figure_manager
backend_mod.draw_if_interactive = draw_if_interactive
# If the manager explicitly overrides pyplot_show, use it even if a global
# show is already present, as the latter may be here for backcompat.
manager_class = getattr(getattr(backend_mod, "FigureCanvas", None),
"manager_class", None)
# We can't compare directly manager_class.pyplot_show and FMB.pyplot_show
# because pyplot_show is a classmethod so the above constructs are bound
# classmethods, & thus always different (being bound to different classes).
manager_pyplot_show = vars(manager_class).get("pyplot_show")
E TypeError: vars() argument must have _dict_ attribute
..\venv\lib\site-packages\matplotlib\pyplot.py:331: TypeError
Expected outcome
Ideally shouldn't have to include matplotlib.use("TkAgg") manually because it causes errors with the script when ran not on windows.
Additional information
Other person encountering the same error: https://stackoverflow.com/questions/75453995/pandas-plot-vars-argument-must-have-dict-attribute
Operating system
No response
Matplotlib Version
3.7.0
Matplotlib Backend
module://backend_interagg
Python version
3.8.10
Jupyter version
No response
Installation
pip
Activity
oscargus commentedon Feb 21, 2023
This was fixed in #25240 and will be included in 3.7.1.