def test_figure_rst(ext): """Testing rst of images""" figure_list = ['sphx_glr_plot_1.' + ext] image_rst = figure_rst(figure_list, '.') single_image = """ .. image:: /sphx_glr_plot_1.{ext} :class: sphx-glr-single-img """.format(ext=ext) assert image_rst == single_image image_rst = figure_rst(figure_list + ['second.' + ext], '.') image_list_rst = """ .. rst-class:: sphx-glr-horizontal * .. image:: /sphx_glr_plot_1.{ext} :class: sphx-glr-multi-img * .. image:: /second.{ext} :class: sphx-glr-multi-img """.format(ext=ext) assert image_rst == image_list_rst # test issue #229 local_img = [os.path.join(os.getcwd(), 'third.' + ext)] image_rst = figure_rst(local_img, '.') single_image = SINGLE_IMAGE % ("third." + ext) assert image_rst == single_image
def test_figure_rst(ext): """Testing rst of images""" figure_list = ['sphx_glr_plot_1.' + ext] image_rst = figure_rst(figure_list, '.') single_image = """ .. image:: /sphx_glr_plot_1.{ext} :class: sphx-glr-single-img """.format(ext=ext) assert image_rst == single_image image_rst = figure_rst(figure_list + ['second.' + ext], '.') image_list_rst = """ .. rst-class:: sphx-glr-horizontal * .. image:: /sphx_glr_plot_1.{ext} :class: sphx-glr-multi-img * .. image:: /second.{ext} :class: sphx-glr-multi-img """.format(ext=ext) assert image_rst == image_list_rst # test issue #229 local_img = [os.path.join(os.getcwd(), 'third.' + ext)] image_rst = figure_rst(local_img, '.') single_image = SINGLE_IMAGE % ("third." + ext) assert image_rst == single_image
def __call__(self, block, block_vars, gallery_conf): # Find all image files in the current directory. path_example = os.path.dirname(block_vars['src_file']) image_files = _find_images(path_example) # Iterate through files, copy them to the SG output directory image_names = [] image_path_iterator = block_vars['image_path_iterator'] for path_orig in image_files: # If we already know about this image and it hasn't been modified # since starting, then skip it mod_time = os.stat(path_orig).st_mtime already_embedded = (path_orig in self.embedded_images and mod_time <= self.embedded_images[path_orig]) existed_before_build = mod_time <= self.start_time if already_embedded or existed_before_build: continue # Else, we assume the image has just been modified and is displayed path_new = next(image_path_iterator) self.embedded_images[path_orig] = mod_time image_names.append(path_new) shutil.copyfile(path_orig, path_new) if len(image_names) == 0: return '' else: return figure_rst(image_names, gallery_conf['src_dir'])
def qtscraper(block, block_vars, gallery_conf): """Basic implementation of a Qt window scraper. Looks for any non-hidden windows in the current application instance and uses ``grab`` to render an image of the window. The window is closed afterward, so you have to call ``show()`` again to render it in a subsequent cell. ``processEvents`` is called twice with a delay between in case events still need to propagate. Intended for use in ``image_scrappers`` in the sphinx-gallery configuration. """ imgpath_iter = block_vars['image_path_iterator'] app = QApplication.instance() if app is None: app = QApplication([]) app.processEvents() # get top-level widgets that aren't hidden widgets = [w for w in app.topLevelWidgets() if not w.isHidden()] rendered_imgs = [] for widg, imgpath in zip(widgets, imgpath_iter): pixmap = widg.grab() pixmap.save(imgpath) rendered_imgs.append(imgpath) widg.close() return scrapers.figure_rst(rendered_imgs, gallery_conf['src_dir'])
def static_image_scraper(block, block_vars, gallery_conf): script_path = os.path.dirname(block_vars["src_file"]) image_sources = [] # Search for comment line containing 'biotite_static_image' _, code, _ = block lines = code.split("\n") for line in lines: line = line.strip() if line.startswith("#"): line = line[1:].strip() if line.startswith("biotite_static_image"): # Get the image name after the '=' character image_name = line.split("=")[1].strip() image_sources.append(os.path.join(script_path, image_name)) # Copy the images into the 'gallery' directory under a canonical # sphinx-gallery name image_destinations = [] image_path_iterator = block_vars['image_path_iterator'] for image in image_sources: image_destination = image_path_iterator.next() image_destinations.append(image_destination) shutil.copy(image, image_destination) # Generate rST for detected image files return figure_rst(image_destinations, gallery_conf['src_dir'])
def __call__(self, block, block_vars, gallery_conf): from ._ieeg_locate_gui import IntracranialElectrodeLocator from sphinx_gallery.scrapers import figure_rst from PyQt5 import QtGui for gui in block_vars['example_globals'].values(): if (isinstance(gui, IntracranialElectrodeLocator) and not getattr(gui, '_scraped', False) and gallery_conf['builder_name'] == 'html'): gui._scraped = True # monkey-patch but it's easy enough img_fname = next(block_vars['image_path_iterator']) # gui is QWindow # https://doc.qt.io/qt-5/qwidget.html#grab pixmap = gui.grab() # Now the tricky part: we need to get the 3D renderer, extract # the image from it, and put it in the correct place in the # pixmap. The easiest way to do this is actually to save the # 3D image first, then load it using QPixmap and Qt geometry. plotter = gui._renderer.plotter plotter.screenshot(img_fname) sub_pixmap = QtGui.QPixmap(img_fname) # https://doc.qt.io/qt-5/qwidget.html#mapTo # https://doc.qt.io/qt-5/qpainter.html#drawPixmap-1 QtGui.QPainter(pixmap).drawPixmap( plotter.mapTo(gui, plotter.rect().topLeft()), sub_pixmap) # https://doc.qt.io/qt-5/qpixmap.html#save pixmap.save(img_fname) gui._renderer.close() # TODO should be triggered by close... gui.close() return figure_rst( [img_fname], gallery_conf['src_dir'], 'iEEG GUI') return ''
def __call__(self, block, block_vars, gallery_conf): """ Called by sphinx-gallery to save the figures generated after running example code. """ try: from sphinx_gallery.scrapers import figure_rst except ImportError: raise ImportError('You must install `sphinx_gallery`') image_names = list() image_path_iterator = block_vars["image_path_iterator"] for _, p in Plotter.DICT_PLOTTERS.items(): fname = next(image_path_iterator) for _, lren in p.renderers.items(): for r in lren: for i in range(r.actors2D.n_items): a = r.actors2D[i] if not isinstance(a, BSScalarBarActor): continue a.labelTextProperty.fontsize = a.labelTextProperty.fontsize * 3 p.screenshot(fname, scale=3) # p.screenshot(fname) image_names.append(fname) Plotter.close_all() # close and clear all plotters return figure_rst(image_names, gallery_conf["src_dir"])
def static_image_scraper(block, block_vars, gallery_conf): script_dir = dirname(block_vars["src_file"]) image_sources = [] # Search for comment line containing 'biotite_static_image' _, code, _ = block for line in code.splitlines(): line = line.strip() if line.startswith("#"): line = line[1:].strip() if line.startswith("biotite_static_image"): # Get the image name after the '=' character image_name = line.split("=")[1].strip() image_sources.append(join(script_dir, image_name)) # Copy the images into the 'gallery' directory under a canonical # sphinx-gallery name image_destinations = [] image_path_iterator = block_vars['image_path_iterator'] for image in image_sources: suffix = splitext(image)[1] image_destination = image_path_iterator.next() # Replace destination file suffix with the suffix from the input # file, e.g. '.png' with '.gif' for animated images image_destination = splitext(image_destination)[0] + suffix image_destinations.append(image_destination) shutil.copy(image, image_destination) # Generate rST for detected image files return figure_rst(image_destinations, gallery_conf['src_dir'])
def pymol_scraper(block, block_vars, gallery_conf): block_type, _, _ = block if block_type == "code": globals = block_vars["example_globals"] # Look for replaced show() output: # a string representing a file name # Since this output is not assigned to any variable, it is # internally assigned to the '___' variable if NO_ASSIGN in globals and isinstance(globals[NO_ASSIGN], str): image_path = globals[NO_ASSIGN] # Copy the images into the 'gallery' directory under a canonical # sphinx-gallery name image_path_iterator = block_vars['image_path_iterator'] image_destination = image_path_iterator.next() shutil.copy(image_path, image_destination) return figure_rst([image_destination], gallery_conf['src_dir']) return figure_rst([], gallery_conf['src_dir'])
def test_figure_rst_srcset(ext): """Testing rst of images""" figure_list = ['sphx_glr_plot_1.' + ext] hipaths = [{0: 'sphx_glr_plot_1.png', 2.0: 'sphx_glr_plot_1_2_0.png'}] image_rst = figure_rst(figure_list, '.', srcsetpaths=hipaths) single_image = f""" .. image-sg:: /sphx_glr_plot_1.{ext} :alt: pl :srcset: /sphx_glr_plot_1.{ext}, /sphx_glr_plot_1_2_0.{ext} 2.0x :class: sphx-glr-single-img """ assert image_rst == single_image hipaths += [{0: 'second.png', 2.0: 'second_2_0.png'}] image_rst = figure_rst(figure_list + ['second.' + ext], '.', srcsetpaths=hipaths + []) image_list_rst = f""" .. rst-class:: sphx-glr-horizontal * .. image-sg:: /sphx_glr_plot_1.{ext} :alt: pl :srcset: /sphx_glr_plot_1.png, /sphx_glr_plot_1_2_0.png 2.0x :class: sphx-glr-multi-img * .. image-sg:: /second.{ext} :alt: pl :srcset: /second.{ext}, /second_2_0.{ext} 2.0x :class: sphx-glr-multi-img """ assert image_rst == image_list_rst # test issue #229 local_img = [os.path.join(os.getcwd(), 'third.' + ext)] image_rst = figure_rst(local_img, '.') single_image = SG_IMAGE % ("third." + ext, '', "/third." + ext) assert image_rst == single_image
def __call__(self, block, block_vars, gallery_conf, **kwargs): """Scrape Matplotlib images. Parameters ---------- block : tuple A tuple containing the (label, content, line_number) of the block. block_vars : dict Dict of block variables. gallery_conf : dict Contains the configuration of Sphinx-Gallery **kwargs : dict Additional keyword arguments to pass to :meth:`~matplotlib.figure.Figure.savefig`, e.g. ``format='svg'``. The ``format`` kwarg in particular is used to set the file extension of the output file (currently only 'png', 'jpg', and 'svg' are supported). Returns ------- rst : str The ReSTructuredText that will be rendered to HTML containing the images. This is often produced by :func:`figure_rst`. """ from matplotlib.figure import Figure image_path_iterator = block_vars['image_path_iterator'] image_paths = list() new_figures = set(plt.get_fignums()) - self.plotted_figures last_line = block[1].strip().split('\n')[-1] output = block_vars['example_globals'].get(last_line) if isinstance(output, Figure): new_figures.add(output.number) for fig_num, image_path in zip(new_figures, image_path_iterator): if 'format' in kwargs: image_path = '%s.%s' % (os.path.splitext(image_path)[0], kwargs['format']) # Set the fig_num figure as the current figure as we can't # save a figure that's not the current figure. fig = plt.figure(fig_num) self.plotted_figures.add(fig_num) to_rgba = matplotlib.colors.colorConverter.to_rgba # shallow copy should be fine here, just want to avoid changing # "kwargs" for subsequent figures processed by the loop these_kwargs = kwargs.copy() for attr in ['facecolor', 'edgecolor']: fig_attr = getattr(fig, 'get_' + attr)() default_attr = matplotlib.rcParams['figure.' + attr] if to_rgba(fig_attr) != to_rgba(default_attr) and \ attr not in kwargs: these_kwargs[attr] = fig_attr fig.savefig(image_path, **these_kwargs) image_paths.append(image_path) return figure_rst(image_paths, gallery_conf['src_dir'])
def _alpha_mpl_scraper(block, block_vars, gallery_conf): import matplotlib.pyplot as plt image_path_iterator = block_vars['image_path_iterator'] image_paths = list() for fig_num, image_path in zip(plt.get_fignums(), image_path_iterator): fig = plt.figure(fig_num) assert image_path.endswith('.png') # use format that does not support alpha image_path = image_path[:-3] + 'jpg' fig.savefig(image_path) image_paths.append(image_path) plt.close('all') return figure_rst(image_paths, gallery_conf['src_dir'])
def __call__(self, block, block_vars, gallery_conf): """ Called by sphinx-gallery to save the figures generated after running code. """ image_names = list() image_path_iterator = block_vars["image_path_iterator"] figures = SHOWED_FIGURES while figures: fname = next(image_path_iterator) fig = figures.pop(0) fig.savefig(fname, transparent=True, dpi=200) image_names.append(fname) return figure_rst(image_names, gallery_conf["src_dir"])
def __call__(self, block, block_vars, gallery_conf): rst = '' for brain in 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.image import imsave from sphinx_gallery.scrapers import figure_rst img_fname = next(block_vars['image_path_iterator']) img = brain.screenshot() assert img.size > 0 if getattr(brain, 'time_viewer', None) is not None and \ brain.time_viewer.show_traces and \ not brain.time_viewer.separate_canvas: canvas = brain.time_viewer.mpl_canvas.fig.canvas canvas.draw_idle() # In theory, one of these should work: # # trace_img = np.frombuffer( # canvas.tostring_rgb(), dtype=np.uint8) # trace_img.shape = canvas.get_width_height()[::-1] + (3,) # # or # # trace_img = np.frombuffer( # canvas.tostring_rgb(), dtype=np.uint8) # size = time_viewer.mpl_canvas.getSize() # trace_img.shape = (size.height(), size.width(), 3) # # But in practice, sometimes the sizes does not match the # renderer tostring_rgb() size. So let's directly use what # matplotlib does in lib/matplotlib/backends/backend_agg.py # before calling tobytes(): trace_img = np.asarray(canvas.renderer._renderer).take( [0, 1, 2], axis=2) # need to slice into trace_img because generally it's a bit # smaller delta = trace_img.shape[1] - img.shape[1] if delta > 0: start = delta // 2 trace_img = trace_img[:, start:start + img.shape[1]] img = np.concatenate([img, trace_img], axis=0) imsave(img_fname, img) assert op.isfile(img_fname) rst += figure_rst([img_fname], gallery_conf['src_dir'], brain._title) brain.close() return rst
def __call__(self, block, block_vars, gallery_conf): """Scrape VisPy Canvases and applications. Parameters ---------- block : tuple A tuple containing the (label, content, line_number) of the block. block_vars : dict Dict of block variables. gallery_conf : dict Contains the configuration of Sphinx-Gallery Returns ------- rst : str The ReSTructuredText that will be rendered to HTML containing the images. This is often produced by :func:`sphinx_gallery.scrapers.figure_rst`. """ example_fn = block_vars["src_file"] frame_num_list = self._get_frame_list_from_source(example_fn) image_path_iterator = block_vars['image_path_iterator'] canvas_or_widget = self._get_canvaslike_from_globals( block_vars["example_globals"]) if not frame_num_list: image_paths = [] elif isinstance(frame_num_list[0], str): # example produces an image/animation as output image_paths = [] for frame_image, image_path in zip(frame_num_list, image_path_iterator): image_path = os.path.splitext( image_path)[0] + os.path.splitext(frame_image)[1] shutil.move(frame_image, image_path) image_paths.append(image_path) else: image_paths = self._save_example_to_files(canvas_or_widget, frame_num_list, gallery_conf, image_path_iterator) fig_titles = "" # alt text # FUTURE: Handle non-images (ex. MP4s) with raw HTML return figure_rst(image_paths, gallery_conf['src_dir'], fig_titles)
def __call__(self, block, block_vars, gallery_conf): """ Called by sphinx-gallery to save the figures generated after running example code. """ try: from sphinx_gallery.scrapers import figure_rst except ImportError: raise ImportError('You must install `sphinx_gallery`') image_names = list() image_path_iterator = block_vars["image_path_iterator"] for k, p in BasePlotter.DICT_PLOTTERS.items(): fname = next(image_path_iterator) p.screenshot(fname) image_names.append(fname) BasePlotter.close_all() # close and clear all plotters return figure_rst(image_names, gallery_conf["src_dir"])
def __call__(self, block, block_vars, gallery_conf): """ Called by sphinx-gallery to save the figures generated after running example code. """ image_names = list() image_path_iterator = block_vars["image_path_iterator"] figures = vtki.plotting._ALL_PLOTTERS for address, plotter in figures.items(): 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) vtki.close_all() # close and clear all plotters return figure_rst(image_names, gallery_conf["src_dir"])
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"])
def __call__(self, block, block_vars, gallery_conf): # Find all PNG files in the directory of this example. pngs = sorted( glob.glob( os.path.join(os.path.dirname(__file__), '_static/img/sphx_glr_*.png'))) # Iterate through PNGs, copy them to the sphinx-gallery output directory image_names = list() image_path_iterator = block_vars['image_path_iterator'] for png in pngs: if png not in self.seen: self.seen |= set(png) this_image_path = image_path_iterator.next() image_names.append(this_image_path) shutil.copy(png, this_image_path) # Use the `figure_rst` helper function to generate rST for image files images_rst = figure_rst(image_names, gallery_conf['src_dir']) return images_rst
def __call__(self, block, block_vars, gallery_conf): """ Scrape .png images created by pygraphviz examples. Invoked by sphinx-gallery. Parameters ---------- block : tuple A tuple containing the (label, content, line_number of the block. block_vars : dict Dict of block variables gallery_conf : dict Mapping of sphinx-gallery configuration values Returns ------- str : rST-formatted string containing the generated images. This will be rendered to HTML during the ``sphinx-build`` process. """ try: from sphinx_gallery.scrapers import figure_rst except ImportError as e: raise ImportError("You must install `sphinx_gallery`") from e # Find all PNG files in the directory of this example path_current_example = os.path.dirname(block_vars["src_file"]) pngs = sorted(glob(os.path.join(path_current_example, "*.png"))) # Iterate through PNGs and copy them to sphinx-gallery output dir image_names = [] image_path_iterator = block_vars["image_path_iterator"] for png in pngs: if png not in self.seen: self.seen |= set(png) this_image_path = next(image_path_iterator) image_names.append(this_image_path) shutil.move(png, this_image_path) # Use figure_rst to generate rST for image files return figure_rst(image_names, gallery_conf["src_dir"])
def __call__(self, block, block_vars, gallery_conf): """Save the figures generated after running example code. Called by sphinx-gallery. """ try: from sphinx_gallery.scrapers import figure_rst except ImportError: raise ImportError("You must install `sphinx_gallery`") image_names = list() image_path_iterator = block_vars["image_path_iterator"] figures = model_visualisation._OPEN_VIEWERS for address, plotter in figures.items(): plotter.lv["background"] = "white" fname = next(image_path_iterator) plotter.save(fname) image_names.append(fname) model_visualisation.close_all() # close and clear all plotters return figure_rst(image_names, gallery_conf["src_dir"])
def __call__(self, block, block_vars, gallery_conf): from ._ieeg_locate_gui import IntracranialElectrodeLocator from ._coreg import CoregistrationUI from sphinx_gallery.scrapers import figure_rst from qtpy import QtGui for gui in block_vars['example_globals'].values(): if (isinstance(gui, (IntracranialElectrodeLocator, CoregistrationUI)) and not getattr(gui, '_scraped', False) and gallery_conf['builder_name'] == 'html'): gui._scraped = True # monkey-patch but it's easy enough img_fname = next(block_vars['image_path_iterator']) # TODO fix in window refactor window = gui if hasattr(gui, 'grab') else gui._renderer._window # window is QWindow # https://doc.qt.io/qt-5/qwidget.html#grab pixmap = window.grab() if hasattr(gui, '_renderer'): # if no renderer, no need # Now the tricky part: we need to get the 3D renderer, # extract the image from it, and put it in the correct # place in the pixmap. The easiest way to do this is # actually to save the 3D image first, then load it # using QPixmap and Qt geometry. plotter = gui._renderer.plotter plotter.screenshot(img_fname) sub_pixmap = QtGui.QPixmap(img_fname) # https://doc.qt.io/qt-5/qwidget.html#mapTo # https://doc.qt.io/qt-5/qpainter.html#drawPixmap-1 QtGui.QPainter(pixmap).drawPixmap( plotter.mapTo(window, plotter.rect().topLeft()), sub_pixmap) # https://doc.qt.io/qt-5/qpixmap.html#save pixmap.save(img_fname) try: # for compatibility with both GUIs, will be refactored gui._renderer.close() # TODO should be triggered by close except Exception: pass gui.close() return figure_rst([img_fname], gallery_conf['src_dir'], 'GUI') return ''
def alt_matplotlib_scraper(block, block_vars, gallery_conf, **kwargs): """Patched matplotlib scraper which won't close figures. Parameters ---------- block : tuple A tuple containing the (label, content, line_number) of the block. block_vars : dict Dict of block variables. gallery_conf : dict Contains the configuration of Sphinx-Gallery **kwargs : dict Additional keyword arguments to pass to :meth:`~matplotlib.figure.Figure.savefig`, e.g. ``format='svg'``. The ``format`` kwarg in particular is used to set the file extension of the output file (currently only 'png' and 'svg' are supported). Returns ------- rst : str The ReSTructuredText that will be rendered to HTML containing the images. This is often produced by :func:`~sphinx_galleryscrapers.figure_rst`. """ lbl, cnt, ln = block image_path_iterator = block_vars["image_path_iterator"] image_paths = [] figs = [m.canvas.figure for m in _pylab_helpers.Gcf.get_all_fig_managers()] fltr = "[^a-zA-Z0-9]+fig,\s??|[^a-zA-Z0-9]+fig\s??|[^a-zA-Z0-9]+figure\s?|plt.show()|plt.gcf()" if figs and re.search(fltr, cnt): # where figure or plt.show is called for fig, image_path in zip([figs[-1]], image_path_iterator): to_rgba = matplotlib.colors.colorConverter.to_rgba save_figure(fig, save_at=Path(image_path).parent, name=Path(image_path).stem, save_fmts=["png"], **kwargs.copy()) image_paths.append(image_path) return scrapers.figure_rst(image_paths, gallery_conf["src_dir"])
def __call__(self, block, block_vars, gallery_conf): """ Called by sphinx-gallery to save the figures generated after running example code. """ try: from sphinx_gallery.scrapers import figure_rst except ImportError: raise ImportError('You must install `sphinx_gallery`') image_names = list() image_path_iterator = block_vars["image_path_iterator"] figures = pyvista.plotting._ALL_PLOTTERS for address, plotter in figures.items(): 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"])
def __call__(self, block, block_vars, gallery_conf, **kwargs): """Scrape Open3D images. Parameters ---------- block : tuple A tuple containing the (label, content, line_number) of the block. block_vars : dict Dict of block variables. gallery_conf : dict Contains the configuration of Sphinx-Gallery **kwargs : dict Additional keyword arguments to pass to :meth:`~matplotlib.figure.Figure.savefig`, e.g. ``format='svg'``. The ``format`` kwarg in particular is used to set the file extension of the output file (currently only 'png', 'jpg', and 'svg' are supported). Returns ------- rst : str The ReSTructuredText that will be rendered to HTML containing the images. """ path_current_example = os.path.dirname(block_vars['src_file']) jpgs = sorted( glob.glob( os.path.join(path_current_example, "__open3d_rendered_image.jpg"))) image_names = list() image_path_iterator = block_vars["image_path_iterator"] for jpg in jpgs: this_image_path = image_path_iterator.next() image_names.append(this_image_path) shutil.move(jpg, this_image_path) return figure_rst(image_names, gallery_conf["src_dir"])
def __call__(self, block, block_vars, gallery_conf): import mne_qt_browser from sphinx_gallery.scrapers import figure_rst if gallery_conf['builder_name'] != 'html': return '' img_fnames = list() inst = None n_plot = 0 for gui in list(mne_qt_browser._browser_instances): try: scraped = getattr(gui, '_scraped', False) except Exception: # super __init__ not called, perhaps stale? scraped = True if scraped: continue gui._scraped = True # monkey-patch but it's easy enough n_plot += 1 img_fnames.append(next(block_vars['image_path_iterator'])) pixmap, inst = _mne_qt_browser_screenshot(gui, inst) pixmap.save(img_fnames[-1]) # child figures for fig in gui.mne.child_figs: # For now we only support Selection if not hasattr(fig, 'channel_fig'): continue fig = fig.channel_fig img_fnames.append(next(block_vars['image_path_iterator'])) fig.savefig(img_fnames[-1]) gui.close() del gui, pixmap if not len(img_fnames): return '' for _ in range(2): inst.processEvents() return figure_rst(img_fnames, gallery_conf['src_dir'], f'Raw plot{_pl(n_plot)}')
def pymol_scraper(block, block_vars, gallery_conf): # Search for comment line containing 'Visualization with PyMOL...' _, code, _ = block if any([ line.strip() == "# Visualization with PyMOL..." for line in code.splitlines() ]): pymol_script_path = splitext(block_vars["src_file"])[0] + "_pymol.py" # The rendered image will be created in the same directory as # the example script # -> the image will be included in version control # -> Rendering with PyMOL is not necessary for building the docs pymol_image_path = splitext(block_vars["src_file"])[0] + ".png" if not isfile(pymol_script_path): raise ExtensionError( f"'{block_vars['src_file']}' has no corresponding " f"'{pymol_script_path}' file") # If PyMOL image is already created, do not run PyMOL script, # as this should not be required for building the documentation if not isfile(pymol_image_path): # Create a shallow copy, # to avoid ading new variables to example script script_globals = copy.copy(block_vars["example_globals"]) script_globals["__image_destination__"] = pymol_image_path try: import pymol except ImportError: raise ExtensionError("PyMOL is not installed") try: import ammolite except ImportError: raise ExtensionError("Ammolite is not installed") with open(pymol_script_path, "r") as script: # Prevent PyMOL from writing stuff (splash screen, etc.) # to STDOUT or STDERR # -> Save original STDOUT/STDERR and point them # temporarily to DEVNULL dev_null = open(os.devnull, 'w') orig_stdout = sys.stdout orig_stderr = sys.stderr sys.stdout = dev_null sys.stderr = dev_null try: exec(script.read(), script_globals) except Exception as e: raise ExtensionError( f"PyMOL script raised a {type(e).__name__}: {str(e)}") finally: # Restore STDOUT/STDERR sys.stdout = orig_stdout sys.stderr = orig_stderr dev_null.close() if not isfile(pymol_image_path): raise ExtensionError("PyMOL script did not create an image " "(at expected location)") # Copy the images into the 'gallery' directory under a canonical # sphinx-gallery name image_path_iterator = block_vars['image_path_iterator'] image_destination = image_path_iterator.next() shutil.copy(pymol_image_path, image_destination) return figure_rst([image_destination], gallery_conf['src_dir']) else: return figure_rst([], gallery_conf['src_dir'])
def __call__(self, block, block_vars, gallery_conf, **kwargs): """Scrape Matplotlib images. Parameters ---------- block : tuple A tuple containing the (label, content, line_number) of the block. block_vars : dict Dict of block variables. gallery_conf : dict Contains the configuration of Sphinx-Gallery **kwargs : dict Additional keyword arguments to pass to :meth:`~matplotlib.figure.Figure.savefig`, e.g. ``format='svg'``. The ``format`` kwarg in particular is used to set the file extension of the output file (currently only 'png', 'jpg', and 'svg' are supported). Returns ------- rst : str The ReSTructuredText that will be rendered to HTML containing the images. This is often produced by :func:`figure_rst`. """ from matplotlib.animation import Animation from matplotlib.figure import Figure image_path_iterator = block_vars['image_path_iterator'] image_rsts = [] # Check for animations anims = list() if gallery_conf.get('matplotlib_animations', False): for ani in block_vars['example_globals'].values(): if isinstance(ani, Animation): anims.append(ani) # Then standard images new_figures = set(plt.get_fignums()) - self.plotted_figures last_line = block[1].strip().split('\n')[-1] output = block_vars['example_globals'].get(last_line) if isinstance(output, Figure): new_figures.add(output.number) for fig_num, image_path in zip(new_figures, image_path_iterator): if 'format' in kwargs: image_path = '%s.%s' % (os.path.splitext(image_path)[0], kwargs['format']) # Set the fig_num figure as the current figure as we can't # save a figure that's not the current figure. fig = plt.figure(fig_num) self.plotted_figures.add(fig_num) # Deal with animations cont = False for anim in anims: if anim._fig is fig: image_rsts.append(_anim_rst(anim, image_path, gallery_conf)) cont = True break if cont: continue # get fig titles fig_titles = _matplotlib_fig_titles(fig) to_rgba = matplotlib.colors.colorConverter.to_rgba # shallow copy should be fine here, just want to avoid changing # "kwargs" for subsequent figures processed by the loop these_kwargs = kwargs.copy() for attr in ['facecolor', 'edgecolor']: fig_attr = getattr(fig, 'get_' + attr)() default_attr = matplotlib.rcParams['figure.' + attr] if to_rgba(fig_attr) != to_rgba(default_attr) and \ attr not in kwargs: these_kwargs[attr] = fig_attr these_kwargs['bbox_inches'] = "tight" fig.savefig(image_path, **these_kwargs) image_rsts.append( figure_rst([image_path], gallery_conf['src_dir'], fig_titles)) rst = '' if len(image_rsts) == 1: rst = image_rsts[0] elif len(image_rsts) > 1: image_rsts = [re.sub(r':class: sphx-glr-single-img', ':class: sphx-glr-multi-img', image) for image in image_rsts] image_rsts = [HLIST_IMAGE_MATPLOTLIB + indent(image, u' ' * 6) for image in image_rsts] rst = HLIST_HEADER + ''.join(image_rsts) return rst