Repository: mne-tools/mne-python

Issue:
BUG: Bug with multi-view screen capture
See this example that uses `hemi='split'`, all captured PyVista images are duplicated:

https://mne.tools/dev/auto_examples/visualization/plot_publication_figure.html#sphx-glr-auto-examples-visualization-plot-publication-figure-py

Moreover, once `brain.close()` is called, it should make sure no figures are generated (as they have been closed for that snippet). Compare the above to what used to be produced with `mayavi` produced (one pair of images rather than four pairs):

https://mne.tools/stable/auto_examples/visualization/plot_publication_figure.html#sphx-glr-auto-examples-visualization-plot-publication-figure-py

cc @GuillaumeFavelier can you look into it?


Discussion:
Yep, I'll take care of it.
I reported this behaviour upstream: https://github.com/pyvista/pyvista/pull/548
Unfortunately, I think this might take a while to fix, probably at the next release of PyVista
@GuillaumeFavelier it would be nice not to have our docs have this problem when they go to `stable`. So I think we either need this for 0.20, or we temporarily revert to using Mayavi to build docs during release...
@GuillaumeFavelier should we revert to `Mayavi` on `CircleCI` until this is fixed?
> should we revert to Mayavi on CircleCI until this is fixed?

+1 for this @larsoner, I'll open the PR

Resolving patch:
diff --git a/doc/conf.py b/doc/conf.py
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -369,8 +369,38 @@
 except Exception:
     pass
 else:
-    scrapers += ('pyvista',)
-if any(x in scrapers for x in ('pyvista', 'mayavi')):
+    # XXX hack, adapted from PyVista to work around
+    # https://github.com/mne-tools/mne-python/issues/7228
+    # https://github.com/pyvista/pyvista/pull/548
+    import shutil
+
+    class Scraper(object):  # noqa:D101
+
+        def __repr__(self):  # noqa:D101
+            return 'PyVista Scraper'
+
+        def __call__(self, block, block_vars, gallery_conf):  # noqa:D101
+            from sphinx_gallery.scrapers import figure_rst
+            image_names = list()
+            image_path_iterator = block_vars["image_path_iterator"]
+            figures = pyvista.plotting._ALL_PLOTTERS
+            seen_plotters = list()
+            for address, plotter in figures.items():
+                if plotter in seen_plotters:
+                    continue
+                seen_plotters += [plotter]
+                fname = next(image_path_iterator)
+                if hasattr(plotter, '_gif_filename'):
+                    # move gif to fname
+                    shutil.move(plotter._gif_filename, fname)
+                else:
+                    plotter.screenshot(fname)
+                image_names.append(fname)
+            pyvista.close_all()  # close and clear all plotters
+            return figure_rst(image_names, gallery_conf["src_dir"])
+    scrapers += (Scraper(),)  # eventually just ('pyvista',)
+if any(x in scrapers for x in ('pyvista', 'mayavi')) or \
+        any('PyVista' in repr(s) for s in scrapers):  # just for our hack
     from traits.api import push_exception_handler
     push_exception_handler(reraise_exceptions=True)
     report_scraper = mne.report._ReportScraper()
@@ -464,6 +494,7 @@ def reset_warnings(gallery_conf, fname):
                 r"joblib is deprecated in 0\.21",  # nilearn
                 'The usage of `cmp` is deprecated and will',  # sklearn/pytest
                 'scipy.* is deprecated and will be removed in',  # dipy
+                r'Converting `np\.character` to a dtype is deprecated',  # vtk
                 ):
         warnings.filterwarnings(  # deal with other modules having bad imports
             'ignore', message=".*%s.*" % key, category=DeprecationWarning)


Test patch: