def zdisplay(fig, **kwargs): """ Publishes a matplotlib figure to the notebook paragraph output. """ # kwargs can be width or height (in units supported by div tag) width = kwargs.pop('width', 'auto') height = kwargs.pop('height', 'auto') fmt = kwargs.get('format', mpl_config.get('format')) # Check if format is supported supported_formats = mpl_config.get('supported_formats') if fmt not in supported_formats: raise ValueError("Unsupported format %s" %fmt) # For SVG the data string has to be unicode, not bytes if fmt == 'svg': img = fig.canvas.get_svg(**kwargs) # This is needed to ensure the SVG image is the correct size. # We should find a better way to do this... width = '{}px'.format(mpl_config.get('width')) height = '{}px'.format(mpl_config.get('height')) else: # Express the image as bytes src = fig.canvas.manager.angular_bind(**kwargs) img = "<img src={src} style='width={width};height:{height}'>" img = img.format(src=src, width=width, height=height) # Print the image to the notebook paragraph via the %html magic html = "<div style='width:{width};height:{height}'>{img}<div>" print(html.format(width=width, height=height, img=img))
def zdisplay(fig, **kwargs): """ Publishes a matplotlib figure to the notebook paragraph output. """ # kwargs can be width or height (in units supported by div tag) width = kwargs.pop('width', 'auto') height = kwargs.pop('height', 'auto') fmt = kwargs.get('format', mpl_config.get('format')) # Check if format is supported supported_formats = mpl_config.get('supported_formats') if fmt not in supported_formats: raise ValueError("Unsupported format %s" % fmt) # For SVG the data string has to be unicode, not bytes if fmt == 'svg': img = fig.canvas.get_svg(**kwargs) # This is needed to ensure the SVG image is the correct size. # We should find a better way to do this... width = '{}px'.format(mpl_config.get('width')) height = '{}px'.format(mpl_config.get('height')) else: # Express the image as bytes src = fig.canvas.manager.angular_bind(**kwargs) img = "<img src={src} style='width={width};height:{height}'>" img = img.format(src=src, width=width, height=height) # Print the image to the notebook paragraph via the %html magic html = "<div style='width:{width};height:{height}'>{img}<div>" print(html.format(width=width, height=height, img=img))
def angular_unbind(self): """ Unbind figure from angular display system. """ context = mpl_config.get('context') if hasattr(context, 'angularUnbind'): context.angularUnbind(self.fig_id)
def get_bytes(self, **kwargs): """ Get the byte representation of the figure. Should only be used with jpg/png formats. """ # Make sure format is correct fmt = kwargs.get('format', mpl_config.get('format')) if fmt == 'svg': raise ValueError("get_bytes() does not support svg, use png or jpg") # Express the image as bytes buf = BytesIO() self.print_figure(buf, **kwargs) fmt = fmt.encode() if sys.version_info >= (3, 4) and sys.version_info < (3, 5): byte_str = bytes("data:image/%s;base64," % fmt, "utf-8") else: byte_str = b"data:image/%s;base64," % fmt byte_str += base64.b64encode(buf.getvalue()) # Python3 forces all strings to default to unicode, but for raster image # formats (eg png, jpg), we want to work with bytes. Thus this step is # needed to ensure compatability for all python versions. byte_str = byte_str.decode('ascii') buf.close() return byte_str
def draw_if_interactive(): """ If interactive mode is on, this allows for updating properties of the figure when each new plotting command is called. """ manager = Gcf.get_active() interactive = matplotlib.is_interactive() angular = mpl_config.get('angular') # Don't bother continuing if we aren't in interactive mode # or if there are no active figures. Also pointless to continue # in angular mode as we don't want to reshow the figure. if not interactive or angular or manager is None: return # Allow for figure to be reshown if close is false since # this function call implies that it has been updated if not mpl_config.get('close'): manager._shown = False
def angular_bind(self, **kwargs): """ Bind figure data to Zeppelin's Angular Object Registry. If mpl_config("angular") is True and PY4J is supported, this allows for the possibility to interactively update a figure from a separate paragraph without having to display it multiple times. """ # This doesn't work for SVG so make sure it's not our format fmt = kwargs.get('format', mpl_config.get('format')) if fmt == 'svg': return # Get the figure data as a byte array src = self.canvas.get_bytes(**kwargs) # Flag to determine whether or not to use # zeppelin's angular display system angular = mpl_config.get('angular') # ZeppelinContext instance (requires PY4J) context = mpl_config.get('context') # Finally we must ensure that automatic closing is set to False, # as otherwise using the angular display system is pointless close = mpl_config.get('close') # If above conditions are met, bind the figure data to # the Angular Object Registry. if not close and angular: if hasattr(context, 'angularBind'): # Binding is performed through figure ID to ensure this works # if multiple figures are open context.angularBind(self.fig_id, src) # Zeppelin will automatically replace this value even if it # is updated from another pargraph thanks to the {{}} notation src = "{{%s}}" % self.fig_id else: warnings.warn("Cannot bind figure to Angular Object Registry. " "Check if PY4J is installed.") return src
def angular_bind(self, **kwargs): """ Bind figure data to Zeppelin's Angular Object Registry. If mpl_config("angular") is True and PY4J is supported, this allows for the possibility to interactively update a figure from a separate paragraph without having to display it multiple times. """ # This doesn't work for SVG so make sure it's not our format fmt = kwargs.get('format', mpl_config.get('format')) if fmt == 'svg': return # Get the figure data as a byte array src = self.canvas.get_bytes(**kwargs) # Flag to determine whether or not to use # zeppelin's angular display system angular = mpl_config.get('angular') # ZeppelinContext instance (requires PY4J) context = mpl_config.get('context') # Finally we must ensure that automatic closing is set to False, # as otherwise using the angular display system is pointless close = mpl_config.get('close') # If above conditions are met, bind the figure data to # the Angular Object Registry. if not close and angular: if hasattr(context, 'angularBind'): # Binding is performed through figure ID to ensure this works # if multiple figures are open context.angularBind(self.fig_id, src) # Zeppelin will automatically replace this value even if it # is updated from another pargraph thanks to the {{}} notation src = "{{%s}}" %self.fig_id else: warnings.warn("Cannot bind figure to Angular Object Registry. " "Check if PY4J is installed.") return src
def __call__(self, close=None, block=None, **kwargs): if close is None: close = mpl_config.get('close') try: managers = Gcf.get_all_fig_managers() if not managers: return # Tell zeppelin that the output will be html using the %html magic # We want to do this only once to avoid seeing "%html" printed # directly to the outout when multiple figures are displayed from # one paragraph. if mpl_config.get('angular'): print('%angular') else: print('%html') # Show all open figures for manager in managers: manager.show(**kwargs) finally: # This closes all the figures if close is set to True. if close and Gcf.get_all_fig_managers(): Gcf.destroy_all()
def get_svg(self, **kwargs): """ Get the svg representation of the figure. Should only be used with svg format. """ # Make sure format is correct fmt = kwargs.get('format', mpl_config.get('format')) if fmt != 'svg': raise ValueError("get_svg() does not support png or jpg, use svg") # For SVG the data string has to be unicode, not bytes buf = StringIO() self.print_figure(buf, **kwargs) svg_str = buf.getvalue() buf.close() return svg_str
def get_bytes(self, **kwargs): """ Get the byte representation of the figure. Should only be used with jpg/png formats. """ # Make sure format is correct fmt = kwargs.get('format', mpl_config.get('format')) if fmt == 'svg': raise ValueError("get_bytes() does not support svg, use png or jpg") # Express the image as bytes buf = BytesIO() self.print_figure(buf, **kwargs) byte_str = b"data:image/%s;base64," %fmt byte_str += base64.b64encode(buf.getvalue()) # Python3 forces all strings to default to unicode, but for raster image # formats (eg png, jpg), we want to work with bytes. Thus this step is # needed to ensure compatability for all python versions. byte_str = byte_str.decode('ascii') buf.close() return byte_str