Repository: Qiskit/qiskit

Issue:
Terra incompatible with `matplotlib==3.5.0`
### Environment

- **Qiskit Terra version**:  0.19.0.dev @ 7e118e8
- **Python version**: 3.7+
- **Operating system**: any


### What is happening?

CI is currently failing on all docs and Linux 3.7 builds (only this one because the image tests are in it).

The docs failure is:
```python
Extension error:
Cell raised uncaught exception:
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
~/work/1/s/.tox/docs/lib/python3.7/site-packages/IPython/core/formatters.py in __call__(self, obj)
    339                 pass
    340             else:
--> 341                 return printer(obj)
    342             # Finally look for special method names
    343             method = get_real_method(obj, self.print_method)

~/work/1/s/.tox/docs/lib/python3.7/site-packages/IPython/core/pylabtools.py in <lambda>(fig)
    437 
    438             collections_and_patches = (

AttributeError: 'Arrow3D' object has no attribute 'do_3d_projection'
```

and the Linux py3.7 failure is:
```python
ERROR: test_plot_state_qsphere (mpl.graph.test_graph_matplotlib_drawer.TestGraphMatplotlibDrawer)
test for plot_state_qsphere
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/vsts/work/1/s/test/ipynb/mpl/graph/test_graph_matplotlib_drawer.py", line 139, in test_plot_state_qsphere
    self.graph_state_drawer(state=state, output="qsphere", filename="qsphere.png")
  File "/home/vsts/work/1/s/test/ipynb/mpl/graph/test_graph_matplotlib_drawer.py", line 84, in wrapper
    results = func(*args, **kwargs)
  File "/home/vsts/work/1/s/qiskit/visualization/state_visualization.py", line 1433, in state_drawer
    return draw_func(state, **drawer_args)
  File "/home/vsts/work/1/s/qiskit/utils/deprecation.py", line 27, in wrapper
    return func(*args, **kwargs)
  File "/home/vsts/work/1/s/qiskit/visualization/state_visualization.py", line 961, in plot_state_qsphere
    return fig.savefig(filename)
  File "/home/vsts/work/1/s/image_tests/lib/python3.7/site-packages/matplotlib/figure.py", line 3012, in savefig
    self.canvas.print_figure(fname, **kwargs)
  File "/home/vsts/work/1/s/image_tests/lib/python3.7/site-packages/matplotlib/_api/__init__.py", line 299, in warn_external
    warnings.warn(message, category, stacklevel)
matplotlib._api.deprecation.MatplotlibDeprecationWarning: The 'renderer' parameter of do_3d_projection() was deprecated in Matplotlib 3.4 and will be removed two minor releases later.
```

### How can we reproduce the issue?

Check a recent CI run.

### What should happen?

No error.

### Any suggestions?

Immediately, pin `matplotlib<3.5` to get CI rolling, then work on fixing compatibility.


Discussion:
The py3.7 failure is related to [this message in the MPL deprecations](https://matplotlib.org/devdocs/api/prev_api_changes/api_changes_3.4.0.html#renderer-argument-of-do-3d-projection-method-for-collection3d-patch3d), though that's from 3.4, so not certain why it's just appearing now.
I'm tagging this as 0.19.0 because we should try to come up with a fix for this before we release. Shipping packages with upper caps on requirements (even optional ones) is potentially problematic for users

Resolving patch:
diff --git a/qiskit/visualization/bloch.py b/qiskit/visualization/bloch.py
--- a/qiskit/visualization/bloch.py
+++ b/qiskit/visualization/bloch.py
@@ -54,19 +54,36 @@
 import matplotlib.pyplot as plt
 from matplotlib.patches import FancyArrowPatch
 from mpl_toolkits.mplot3d import Axes3D, proj3d
+from mpl_toolkits.mplot3d.art3d import Patch3D
 
 from .utils import matplotlib_close_if_inline
 
 
-class Arrow3D(FancyArrowPatch):
+class Arrow3D(Patch3D, FancyArrowPatch):
     """Makes a fancy arrow"""
 
-    def __init__(self, xs, ys, zs, *args, **kwargs):
-        FancyArrowPatch.__init__(self, (0, 0), (0, 0), *args, **kwargs)
-        self._verts3d = xs, ys, zs
+    # Nasty hack around a poorly implemented deprecation warning in Matplotlib 3.5 that issues two
+    # deprecation warnings if an artist's module does not claim to be part of the below module.
+    # This revolves around the method `Patch3D.do_3d_projection(self, renderer=None)`.  The
+    # `renderer` argument has been deprecated since Matplotlib 3.4, but in 3.5 some internal calls
+    # during `Axes3D` display started calling the method.  If an artist does not have this module,
+    # then it issues a deprecation warning, and calls it by passing the `renderer` parameter as
+    # well, which consequently triggers another deprecation warning.  We should be able to remove
+    # this once 3.6 is the minimum supported version, because the deprecation period ends then.
+    __module__ = "mpl_toolkits.mplot3d.art3d"
+
+    def __init__(self, xs, ys, zs, zdir="z", **kwargs):
+        # The Patch3D.__init__() method just calls its own super() method and then
+        # self.set_3d_properties, but its __init__ signature is actually pretty incompatible with
+        # how it goes on to call set_3d_properties, so we just have to do things ourselves.  The
+        # parent of Patch3D is Patch, which is also a parent of FancyArrowPatch, so its __init__ is
+        # still getting suitably called.
+        # pylint: disable=super-init-not-called
+        FancyArrowPatch.__init__(self, (0, 0), (0, 0), **kwargs)
+        self.set_3d_properties(tuple(zip(xs, ys)), zs, zdir)
 
     def draw(self, renderer):
-        xs3d, ys3d, zs3d = self._verts3d
+        xs3d, ys3d, zs3d = zip(*self._segment3d)
         x_s, y_s, _ = proj3d.proj_transform(xs3d, ys3d, zs3d, self.axes.M)
         self.set_positions((x_s[0], y_s[0]), (x_s[1], y_s[1]))
         FancyArrowPatch.draw(self, renderer)
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -79,7 +79,7 @@
 
 
 visualization_extras = [
-    "matplotlib>=3.3,<3.5",
+    "matplotlib>=3.3",
     "ipywidgets>=7.3.0",
     "pydot",
     "pillow>=4.2.1",


Test patch: