File: _scraper.py

package info (click to toggle)
python-mne 1.9.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 131,492 kB
  • sloc: python: 213,302; javascript: 12,910; sh: 447; makefile: 144
file content (102 lines) | stat: -rw-r--r-- 4,188 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.

import os
import os.path as op

from ._brain import Brain


class _BrainScraper:
    """Scrape Brain objects."""

    def __repr__(self):
        return "<BrainScraper>"

    def __call__(self, block, block_vars, gallery_conf):
        rst = ""
        for brain in list(block_vars["example_globals"].values()):
            # Only need to process if it's a brain with a time_viewer
            # with traces on and shown in the same window, otherwise
            # PyVista and matplotlib scrapers can just do the work
            if (not isinstance(brain, Brain)) or brain._closed:
                continue
            from matplotlib import animation
            from matplotlib import pyplot as plt
            from sphinx_gallery.scrapers import matplotlib_scraper

            img = brain.screenshot(time_viewer=True)
            dpi = 100.0
            figsize = (img.shape[1] / dpi, img.shape[0] / dpi)
            fig = plt.figure(figsize=figsize, dpi=dpi)
            ax = plt.Axes(fig, [0, 0, 1, 1])
            fig.add_axes(ax)
            img = ax.imshow(img)
            movie_key = "# brain.save_movie"
            if movie_key in block[1]:
                kwargs = dict()
                # Parse our parameters
                lines = block[1].splitlines()
                for li, line in enumerate(block[1].splitlines()):
                    if line.startswith(movie_key):
                        line = line[len(movie_key) :].replace("..., ", "")
                        for ni in range(1, 5):  # should be enough
                            if len(lines) > li + ni and lines[li + ni].startswith(
                                "#  "
                            ):
                                line = line + lines[li + ni][1:].strip()
                            else:
                                break
                        assert line.startswith("(") and line.endswith(")")
                        kwargs.update(eval(f"dict{line}"))  # nosec B307
                for key, default in [
                    ("time_dilation", 4),
                    ("framerate", 24),
                    ("tmin", None),
                    ("tmax", None),
                    ("interpolation", None),
                    ("time_viewer", False),
                ]:
                    if key not in kwargs:
                        kwargs[key] = default
                kwargs.pop("filename", None)  # always omit this one
                if brain.time_viewer:
                    assert kwargs["time_viewer"], "Must use time_viewer=True"
                frames = brain._make_movie_frames(callback=None, **kwargs)

                # Turn them into an animation
                def func(frame):
                    img.set_data(frame)
                    return [img]

                anim = animation.FuncAnimation(
                    fig,
                    func=func,
                    frames=frames,
                    blit=True,
                    interval=1000.0 / kwargs["framerate"],
                )

                # Out to sphinx-gallery:
                #
                # 1. A static image but hide it (useful for carousel)
                if animation.FFMpegWriter.isAvailable():
                    writer = "ffmpeg"
                elif animation.ImageMagickWriter.isAvailable():
                    writer = "imagemagick"
                else:
                    writer = None
                static_fname = next(block_vars["image_path_iterator"])
                static_fname = static_fname[:-4] + ".gif"
                anim.save(static_fname, writer=writer, dpi=dpi)
                rel_fname = op.relpath(static_fname, gallery_conf["src_dir"])
                rel_fname = rel_fname.replace(os.sep, "/").lstrip("/")
                rst += f"\n.. image:: /{rel_fname}\n    :class: hidden\n"

                # 2. An animation that will be embedded and visible
                block_vars["example_globals"]["_brain_anim_"] = anim

            brain.close()
            rst += matplotlib_scraper(block, block_vars, gallery_conf)
        return rst