Repository: spyder-ide/spyder

Issue:
Matplotlib no longer supports qt4 nor gtk backends
<!--- **PLEASE READ:** When submitting here, please ensure you've completed the following checklist and checked the boxes to confirm. Issue reports without it may be closed. Thanks! --->

### Issue Report Checklist

* [x] Searched the [issues page](https://github.com/spyder-ide/spyder/issues?q=is%3Aissue) for similar reports
* [x] Read the relevant sections of the [Spyder Troubleshooting Guide](https://github.com/spyder-ide/spyder/wiki/Troubleshooting-Guide-and-FAQ) and followed its advice
* [x] Reproduced the issue after updating with ``conda update spyder`` (or ``pip``, if not using Anaconda)
* [ ] Could not reproduce inside ``jupyter qtconsole`` (if console-related)
* [x] Tried basic troubleshooting (if a bug/error)
    * [x] Restarted Spyder
    * [x] Reset preferences with ``spyder --reset``
    * [x] Reinstalled the latest version of [Anaconda](https://www.anaconda.com/download/)
    * [x] Tried the other applicable steps from the Troubleshooting Guide
* [x] Completed the **Problem Description**, **Steps to Reproduce** and **Version** sections below


## Problem Description

With version 3.5.0 the qt4 support is completely dropped in matplotlib (qt6 is supported though).

This is what happens when starting a console with qt4 set:
```
Output from spyder call 'show_mpl_backend_errors':

=========================================================================
NOTE: The following error appeared when setting your Matplotlib backend!!
=========================================================================

Traceback (most recent call last):
  File "/usr/lib/python3.10/site-packages/spyder_kernels/console/kernel.py", line 723, in _set_mpl_backend
    get_ipython().run_line_magic(magic, backend)
  File "/usr/lib/python3.10/site-packages/IPython/core/interactiveshell.py", line 2364, in run_line_magic
    result = fn(*args, **kwargs)
  File "/usr/lib/python3.10/site-packages/decorator.py", line 232, in fun
    return caller(func, *(extras + args), **kw)
  File "/usr/lib/python3.10/site-packages/IPython/core/magic.py", line 187, in <lambda>
    call = lambda f, *a, **k: f(*a, **k)
  File "/usr/lib/python3.10/site-packages/IPython/core/magics/pylab.py", line 99, in matplotlib
    gui, backend = self.shell.enable_matplotlib(args.gui.lower() if isinstance(args.gui, str) else args.gui)
  File "/usr/lib/python3.10/site-packages/IPython/core/interactiveshell.py", line 3546, in enable_matplotlib
    pt.activate_matplotlib(backend)
  File "/usr/lib/python3.10/site-packages/IPython/core/pylabtools.py", line 352, in activate_matplotlib
    matplotlib.rcParams['backend'] = backend
  File "/home/oscar/dev/matplotlib/lib/matplotlib/__init__.py", line 644, in __setitem__
    raise ValueError(f"Key {key}: {ve}") from None
ValueError: Key backend: 'qt4agg' is not a valid value for backend; supported values are ['GTK3Agg', 'GTK3Cairo', 'GTK4Agg', 'GTK4Cairo', 'MacOSX', 'nbAgg', 'QtAgg', 'QtCairo', 'Qt5Agg', 'Qt5Cairo', 'TkAgg', 'TkCairo', 'WebAgg', 'WX', 'WXAgg', 'WXCairo', 'agg', 'cairo', 'pdf', 'pgf', 'ps', 'svg', 'template']
```

Similar error message with gtk.

I may be tempted to go for a PR, but how should one deal with different versions etc? If a user has a pre 3.5.0-version it will still work, so just removing them may not be the obvious solution?

### What steps reproduce the problem?

1. Open preferences
2. Change IPython/Graphics to qt4 or gtk
3. Start a new console

### What is the expected output? What do you see instead?

No error messages = remove gtk and qt4 options.


### Paste Traceback/Error Below (if applicable)
<!--- Copy from error dialog or View > Panes > Internal Console --->

```python-traceback

PASTE TRACEBACK HERE

```

## Versions
<!--- You can get this information from Help > About Spyder...
or (if Spyder won't launch) the "conda list" command
from the Anaconda Prompt/Terminal/command line. --->

* Spyder version: 5.2.0 None
* Python version: 3.10.1 64-bit
* Qt version: 5.15.2
* PyQt5 version: 5.15.6
* Operating System: Linux 5.12.9-arch1-1
 
### Dependencies
<!--- Please go to the menu entry Help > Dependencies,
press the Copy to clipboard button and paste below --->

```

# Mandatory:
atomicwrites >=1.2.0          :  1.4.0 (OK)
chardet >=2.0.0               :  4.0.0 (OK)
cloudpickle >=0.5.0           :  2.0.0 (OK)
cookiecutter >=1.6.0          :  1.7.3 (OK)
diff_match_patch >=20181111   :  20200713 (OK)
intervaltree >=3.0.2          :  3.1.0 (OK)
IPython >=7.6.0               :  7.31.0 (OK)
jedi >=0.17.2;<0.19.0         :  0.18.1 (OK)
jellyfish >=0.7               :  0.9.0 (OK)
jsonschema >=3.2.0            :  3.2.0 (OK)
keyring >=17.0.0              :  23.4.0 (OK)
nbconvert >=4.0               :  6.1.0 (OK)
numpydoc >=0.6.0              :  1.1.0 (OK)
parso >=0.7.0;<0.9.0          :  0.8.2 (OK)
pexpect >=4.4.0               :  4.8.0 (OK)
pickleshare >=0.4             :  0.7.5 (OK)
psutil >=5.3                  :  5.9.0 (OK)
pygments >=2.0                :  2.11.2 (OK)
pylint >=2.5.0                :  2.12.2 (OK)
pyls_spyder >=0.4.0           :  0.4.0 (OK)
pylsp >=1.3.1;<1.4.0          :  1.3.2 (OK)
pylsp_black >=1.0.0           :  None (OK)
qdarkstyle >=3.0.2            :  3.0.2 (OK)
qstylizer >=0.1.10            :  0.2.1 (OK)
qtawesome >=1.0.2             :  1.0.3 (OK)
qtconsole >=5.2.1;<5.3.0      :  5.2.1 (OK)
qtpy >=1.5.0                  :  1.11.2 (OK)
rtree >=0.9.7                 :  0.9.7 (OK)
setuptools >=49.6.0           :  59.1.0 (OK)
sphinx >=0.6.6                :  4.3.2 (OK)
spyder_kernels >=2.2.0;<2.3.0 :  2.2.0 (OK)
textdistance >=4.2.0          :  4.2.2 (OK)
three_merge >=0.1.1           :  0.1.1 (OK)
watchdog >=0.10.3             :  0.10.7 (OK)
xdg >=0.26                    :  0.27 (OK)
zmq >=17                      :  22.2.1 (OK)

# Optional:
cython >=0.21                 :  None (OK)
matplotlib >=2.0.0            :  3.6.0.dev1303+g8d7a2b9d2a.d20220111 (OK)
numpy >=1.7                   :  1.21.5 (OK)
pandas >=1.1.1                :  None (OK)
scipy >=0.17.0                :  1.7.3 (OK)
sympy >=0.7.3                 :  1.10.dev (OK)
```



Discussion:
I have now tried to sort things out and as a consequence of not sorting it out, read up a bit. I realize that it comes down to https://github.com/ipython/ipykernel/issues/775 (where @ccordoba12 has commented, so you are well aware of it).

Anyway, removing `qt4` and `gtk` (and always enabling `wx` since it is not PY2 only anymore) may be an option so far. Let me know if you want a PR for that part.
Hey @oscargus, thanks for reporting. I also noticed this problem recently and my plan is to fix it in Spyder 5.3.

> Let me know if you want a PR for that part.

Thanks for the offer! But since this also requires a synced PR on spyder-kernels, I prefer to do it myself.

Resolving patch:
diff --git a/external-deps/spyder-kernels/spyder_kernels/utils/mpl.py b/external-deps/spyder-kernels/spyder_kernels/utils/mpl.py
--- a/external-deps/spyder-kernels/spyder_kernels/utils/mpl.py
+++ b/external-deps/spyder-kernels/spyder_kernels/utils/mpl.py
@@ -29,12 +29,8 @@
 MPL_BACKENDS_TO_SPYDER = {
     inline_backend: 0,
     'Qt5Agg': 2,
-    'Qt4Agg': 3,
+    'TkAgg': 3,
     'MacOSX': 4,
-    'GTK3Agg': 5,
-    'GTKAgg': 6,
-    'WX': 7,
-    'TkAgg': 8
 }
 
 
@@ -42,8 +38,6 @@ def automatic_backend():
     """Get Matplolib automatic backend option."""
     if is_module_installed('PyQt5'):
         auto_backend = 'qt5'
-    elif is_module_installed('PyQt4'):
-        auto_backend = 'qt4'
     elif is_module_installed('_tkinter'):
         auto_backend = 'tk'
     else:
@@ -56,10 +50,6 @@ def automatic_backend():
     '0': 'inline',
     '1': automatic_backend(),
     '2': 'qt5',
-    '3': 'qt4',
-    '4': 'osx',
-    '5': 'gtk3',
-    '6': 'gtk',
-    '7': 'wx',
-    '8': 'tk'
+    '3': 'tk',
+    '4': 'osx'
 }
diff --git a/spyder/plugins/ipythonconsole/confpage.py b/spyder/plugins/ipythonconsole/confpage.py
--- a/spyder/plugins/ipythonconsole/confpage.py
+++ b/spyder/plugins/ipythonconsole/confpage.py
@@ -110,16 +110,10 @@ def setup_page(self):
                               "separate window.") % (inline, automatic))
         bend_label.setWordWrap(True)
 
-        backends = [(inline, 0), (automatic, 1), ("Qt5", 2), ("Qt4", 3)]
+        backends = [(inline, 0), (automatic, 1), ("Qt5", 2), ("Tkinter", 3)]
 
         if sys.platform == 'darwin':
-            backends.append(("OS X", 4))
-        if sys.platform.startswith('linux'):
-            backends.append(("Gtk3", 5))
-            backends.append(("Gtk", 6))
-        if PY2:
-            backends.append(("Wx", 7))
-        backends.append(("Tkinter", 8))
+            backends.append(("macOS", 4))
         backends = tuple(backends)
 
         backend_box = self.create_combobox(


Test patch:
diff --git a/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py b/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py
--- a/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py
+++ b/spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py
@@ -151,7 +151,7 @@ def __getattr__(self, attr):
     # Use the Tkinter backend if requested
     tk_backend = request.node.get_closest_marker('tk_backend')
     if tk_backend:
-        configuration.set('ipython_console', 'pylab/backend', 8)
+        configuration.set('ipython_console', 'pylab/backend', 3)
 
     # Start a Pylab client if requested
     pylab_client = request.node.get_closest_marker('pylab_client')