def get_source(self, source_num=0): """Returns the volume rendering source indexed by ``source_num``""" return list(itervalues(self.sources))[source_num]
def save(self, fname=None, sigma_clip=None): r"""Saves the most recently rendered image of the Scene to disk. Once you have created a scene and rendered that scene to an image array, this saves that image array to disk with an optional filename. If an image has not yet been rendered for the current scene object, it forces one and writes it out. Parameters ---------- fname: string, optional If specified, save the rendering as to the file "fname". If unspecified, it creates a default based on the dataset filename. The file format is inferred from the filename's suffix. Supported fomats are png, pdf, eps, and ps. Default: None sigma_clip: float, optional Image values greater than this number times the standard deviation plus the mean of the image will be clipped before saving. Useful for enhancing images as it gets rid of rare high pixel values. Default: None floor(vals > std_dev*sigma_clip + mean) Returns ------- Nothing Examples -------- >>> import yt >>> ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030') >>> >>> sc = yt.create_scene(ds) >>> # Modify camera, sources, etc... >>> sc.render() >>> sc.save('test.png', sigma_clip=4) Or alternatively: >>> import yt >>> ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030') >>> >>> sc = yt.create_scene(ds) >>> # save with different sigma clipping values >>> sc.save('raw.png') >>> sc.save('clipped_2.png', sigma_clip=2) >>> sc.save('clipped_4.png', sigma_clip=4) """ if fname is None: sources = list(itervalues(self.sources)) rensources = [s for s in sources if isinstance(s, RenderSource)] # if a volume source present, use its affiliated ds for fname if len(rensources) > 0: rs = rensources[0] basename = rs.data_source.ds.basename if isinstance(rs.field, string_types): field = rs.field else: field = rs.field[-1] fname = "%s_Render_%s.png" % (basename, field) # if no volume source present, use a default filename else: fname = "Render_opaque.png" suffix = get_image_suffix(fname) if suffix == '': suffix = '.png' fname = '%s%s' % (fname, suffix) self.render() mylog.info("Saving render %s", fname) # We can render pngs natively but for other formats we defer to # matplotlib. if suffix == '.png': self._last_render.write_png(fname, sigma_clip=sigma_clip) else: from matplotlib.figure import Figure from matplotlib.backends.backend_pdf import \ FigureCanvasPdf from matplotlib.backends.backend_ps import \ FigureCanvasPS shape = self._last_render.shape fig = Figure((shape[0] / 100., shape[1] / 100.)) if suffix == '.pdf': canvas = FigureCanvasPdf(fig) elif suffix in ('.eps', '.ps'): canvas = FigureCanvasPS(fig) else: raise NotImplementedError( "Unknown file suffix '{}'".format(suffix)) ax = fig.add_axes([0, 0, 1, 1]) ax.set_axis_off() out = self._last_render nz = out[:, :, :3][out[:, :, :3].nonzero()] max_val = nz.mean() + sigma_clip * nz.std() alpha = 255 * out[:, :, 3].astype('uint8') out = np.clip(out[:, :, :3] / max_val, 0.0, 1.0) * 255 out = np.concatenate([out.astype('uint8'), alpha[..., None]], axis=-1) # not sure why we need rot90, but this makes the orientation # match the png writer ax.imshow(np.rot90(out), origin='lower') canvas.print_figure(fname, dpi=100)
def save_annotated(self, fname=None, label_fmt=None, text_annotate=None, dpi=100, sigma_clip=None): r"""Saves the most recently rendered image of the Scene to disk, including an image of the transfer function and and user-defined text. Once you have created a scene and rendered that scene to an image array, this saves that image array to disk with an optional filename. If an image has not yet been rendered for the current scene object, it forces one and writes it out. Parameters ---------- fname: string, optional If specified, save the rendering as a bitmap to the file "fname". If unspecified, it creates a default based on the dataset filename. Default: None sigma_clip: float, optional Image values greater than this number times the standard deviation plus the mean of the image will be clipped before saving. Useful for enhancing images as it gets rid of rare high pixel values. Default: None floor(vals > std_dev*sigma_clip + mean) dpi: integer, optional By default, the resulting image will be the same size as the camera parameters. If you supply a dpi, then the image will be scaled accordingly (from the default 100 dpi) label_fmt : str, optional A format specifier (e.g., label_fmt="%.2g") to use in formatting the data values that label the transfer function colorbar. text_annotate : list of iterables Any text that you wish to display on the image. This should be an list containing a tuple of coordinates (in normalized figure coordinates), the text to display, and, optionally, a dictionary of keyword/value pairs to pass through to the matplotlib text() function. Each item in the main list is a separate string to write. Returns ------- Nothing Examples -------- >>> sc.save_annotated("fig.png", ... text_annotate=[[(0.05, 0.05), ... "t = {}".format(ds.current_time.d), ... dict(horizontalalignment="left")], ... [(0.5,0.95), ... "simulation title", ... dict(color="y", fontsize="24", ... horizontalalignment="center")]]) """ from yt.visualization._mpl_imports import \ FigureCanvasAgg, FigureCanvasPdf, FigureCanvasPS sources = list(itervalues(self.sources)) rensources = [s for s in sources if isinstance(s, RenderSource)] if fname is None: # if a volume source present, use its affiliated ds for fname if len(rensources) > 0: rs = rensources[0] basename = rs.data_source.ds.basename if isinstance(rs.field, string_types): field = rs.field else: field = rs.field[-1] fname = "%s_Render_%s.png" % (basename, field) # if no volume source present, use a default filename else: fname = "Render_opaque.png" suffix = get_image_suffix(fname) if suffix == '': suffix = '.png' fname = '%s%s' % (fname, suffix) self.render() # which transfer function? rs = rensources[0] tf = rs.transfer_function label = rs.data_source.ds._get_field_info(rs.field).get_label() ax = self._show_mpl(self._last_render.swapaxes(0, 1), sigma_clip=sigma_clip, dpi=dpi) self._annotate(ax.axes, tf, rs, label=label, label_fmt=label_fmt) # any text? if text_annotate is not None: f = self._render_figure for t in text_annotate: xy = t[0] string = t[1] if len(t) == 3: opt = t[2] else: opt = dict() # sane default if "color" not in opt: opt["color"] = "w" ax.axes.text(xy[0], xy[1], string, transform=f.transFigure, **opt) suffix = get_image_suffix(fname) if suffix == ".png": canvas = FigureCanvasAgg(self._render_figure) elif suffix == ".pdf": canvas = FigureCanvasPdf(self._render_figure) elif suffix in (".eps", ".ps"): canvas = FigureCanvasPS(self._render_figure) else: mylog.warning("Unknown suffix %s, defaulting to Agg", suffix) canvas = self.canvas self._render_figure.canvas = canvas self._render_figure.tight_layout() self._render_figure.savefig(fname, facecolor='black', pad_inches=0)
def save(self, fname=None, sigma_clip=None): r"""Saves the most recently rendered image of the Scene to disk. Once you have created a scene and rendered that scene to an image array, this saves that image array to disk with an optional filename. If an image has not yet been rendered for the current scene object, it forces one and writes it out. Parameters ---------- fname: string, optional If specified, save the rendering as a bitmap to the file "fname". If unspecified, it creates a default based on the dataset filename. Default: None sigma_clip: float, optional Image values greater than this number times the standard deviation plus the mean of the image will be clipped before saving. Useful for enhancing images as it gets rid of rare high pixel values. Default: None floor(vals > std_dev*sigma_clip + mean) Returns ------- Nothing Examples -------- >>> import yt >>> ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030') >>> >>> sc = yt.create_scene(ds) >>> # Modify camera, sources, etc... >>> sc.render() >>> sc.save('test.png', sigma_clip=4) Or alternatively: >>> import yt >>> ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030') >>> >>> sc = yt.create_scene(ds) >>> # save with different sigma clipping values >>> sc.save('raw.png') >>> sc.save('clipped_2.png', sigma_clip=2) >>> sc.save('clipped_4.png', sigma_clip=4) """ if fname is None: sources = list(itervalues(self.sources)) rensources = [s for s in sources if isinstance(s, RenderSource)] # if a volume source present, use its affiliated ds for fname if len(rensources) > 0: rs = rensources[0] basename = rs.data_source.ds.basename if isinstance(rs.field, string_types): field = rs.field else: field = rs.field[-1] fname = "%s_Render_%s.png" % (basename, field) # if no volume source present, use a default filename else: fname = "Render_opaque.png" suffix = get_image_suffix(fname) if suffix == '': suffix = '.png' fname = '%s%s' % (fname, suffix) self.render() mylog.info("Saving render %s", fname) self._last_render.write_png(fname, sigma_clip=sigma_clip)