def update(self, **kwargs): ims = self.ax.images # update extent: self._extent = (self.xaxis.axis[0] - self.xaxis.scale / 2., self.xaxis.axis[-1] + self.xaxis.scale / 2., self.yaxis.axis[-1] + self.yaxis.scale / 2., self.yaxis.axis[0] - self.yaxis.scale / 2.) # Turn on centre_colormap if a diverging colormap is used. if self.centre_colormap == "auto": if "cmap" in kwargs: cmap = kwargs["cmap"] elif ims: cmap = ims[0].get_cmap().name else: cmap = plt.cm.get_cmap().name if cmap in utils.MPL_DIVERGING_COLORMAPS: self.centre_colormap = True else: self.centre_colormap = False redraw_colorbar = False data = rgb_tools.rgbx2regular_array( self.data_function(axes_manager=self.axes_manager), plot_friendly=True) numrows, numcols = data.shape[:2] for marker in self.ax_markers: marker.update() if len(data.shape) == 2: def format_coord(x, y): try: col = self.xaxis.value2index(x) except ValueError: # out of axes limits col = -1 try: row = self.yaxis.value2index(y) except ValueError: row = -1 if col >= 0 and row >= 0: z = data[row, col] return 'x=%1.4g, y=%1.4g, intensity=%1.4g' % (x, y, z) else: return 'x=%1.4g, y=%1.4g' % (x, y) self.ax.format_coord = format_coord old_vmax, old_vmin = self.vmax, self.vmin self.optimize_contrast(data) # If there is an image, any of the contrast bounds have changed and # the new contrast bounds are not the same redraw the colorbar. if (ims and (old_vmax != self.vmax or old_vmin != self.vmin) and self.vmax != self.vmin): redraw_colorbar = True ims[0].autoscale() redraw_colorbar = redraw_colorbar and self.colorbar if self.plot_indices is True: self._text.set_text(self.axes_manager.indices) if self.no_nans: data = np.nan_to_num(data) if self.centre_colormap: vmin, vmax = utils.centre_colormap_values(self.vmin, self.vmax) else: vmin, vmax = self.vmin, self.vmax if ims: ims[0].set_data(data) self.ax.set_xlim(self._extent[:2]) self.ax.set_ylim(self._extent[2:]) ims[0].set_extent(self._extent) self._calculate_aspect() self.ax.set_aspect(self._aspect) ims[0].norm.vmax, ims[0].norm.vmin = vmax, vmin if redraw_colorbar is True: # ims[0].autoscale() self._colorbar.draw_all() self._colorbar.solids.set_animated( self.figure.canvas.supports_blit) else: ims[0].changed() if self.figure.canvas.supports_blit: self._update_animated() else: self.figure.canvas.draw_idle() else: new_args = { 'interpolation': 'nearest', 'vmin': vmin, 'vmax': vmax, 'extent': self._extent, 'aspect': self._aspect, 'animated': self.figure.canvas.supports_blit } new_args.update(kwargs) self.ax.imshow(data, **new_args) self.figure.canvas.draw_idle() if self.axes_ticks == 'off': self.ax.set_axis_off()
def update(self, data_changed=True, auto_contrast=None, vmin=None, vmax=None, **kwargs): """ Parameters ---------- data_changed : bool, optional Fetch and update the data to display. It can be used to avoid unnecessarily reading of the data from disk with working with lazy signal. The default is True. auto_contrast : bool or None, optional Force automatic resetting of the intensity limits. If None, the intensity values will change when 'v' is in autoscale. Default is None. vmin, vmax : float or str `vmin` and `vmax` are used to normalise the displayed data. **kwargs : dict The kwargs are passed to :py:func:`matplotlib.pyplot.imshow`. Raises ------ ValueError When the selected ``norm`` is not valid or the data are not compatible with the selected ``norm``. """ if auto_contrast is None: auto_contrast = 'v' in self.autoscale if data_changed: # When working with lazy signals the following may reread the data # from disk unnecessarily, for example when updating the image just # to recompute the histogram to adjust the contrast. In those cases # use `data_changed=True`. _logger.debug("Updating image slowly because `data_changed=True`") self._update_data() data = self._current_data if rgb_tools.is_rgbx(data): self.colorbar = False data = rgb_tools.rgbx2regular_array(data, plot_friendly=True) data = self._current_data = data self._is_rgb = True ims = self.ax.images # Turn on centre_colormap if a diverging colormap is used. if not self._is_rgb and self.centre_colormap == "auto": if "cmap" in kwargs: cmap = kwargs["cmap"] elif ims: cmap = ims[0].get_cmap().name else: cmap = plt.cm.get_cmap().name if cmap in utils.MPL_DIVERGING_COLORMAPS: self.centre_colormap = True else: self.centre_colormap = False redraw_colorbar = False for marker in self.ax_markers: marker.update() if not self._is_rgb: def format_coord(x, y): try: col = self.xaxis.value2index(x) except ValueError: # out of axes limits col = -1 try: row = self.yaxis.value2index(y) except ValueError: row = -1 if col >= 0 and row >= 0: z = data[row, col] if np.isfinite(z): return f'x={x:1.4g}, y={y:1.4g}, intensity={z:1.4g}' return f'x={x:1.4g}, y={y:1.4g}' self.ax.format_coord = format_coord old_vmin, old_vmax = self._vmin, self._vmax if auto_contrast: vmin, vmax = self._calculate_vmin_max(data, auto_contrast, vmin, vmax) else: # use the value store internally when not explicitely defined if vmin is None: vmin = old_vmin if vmax is None: vmax = old_vmax # If there is an image, any of the contrast bounds have changed and # the new contrast bounds are not the same redraw the colorbar. if (ims and (old_vmin != vmin or old_vmax != vmax) and vmin != vmax): redraw_colorbar = True ims[0].autoscale() if self.centre_colormap: vmin, vmax = utils.centre_colormap_values(vmin, vmax) if self.norm == 'auto' and self.gamma != 1.0: self.norm = 'power' norm = copy.copy(self.norm) if norm == 'power': # with auto norm, we use the power norm when gamma differs from its # default value. norm = PowerNorm(self.gamma, vmin=vmin, vmax=vmax) elif norm == 'log': if np.nanmax(data) <= 0: raise ValueError( 'All displayed data are <= 0 and can not ' 'be plotted using `norm="log"`. ' 'Use `norm="symlog"` to plot on a log scale.') if np.nanmin(data) <= 0: vmin = np.nanmin(np.where(data > 0, data, np.inf)) norm = LogNorm(vmin=vmin, vmax=vmax) elif norm == 'symlog': sym_log_kwargs = { 'linthresh': self.linthresh, 'linscale': self.linscale, 'vmin': vmin, 'vmax': vmax } if LooseVersion(matplotlib.__version__) >= LooseVersion("3.2"): sym_log_kwargs['base'] = 10 norm = SymLogNorm(**sym_log_kwargs) elif inspect.isclass(norm) and issubclass(norm, Normalize): norm = norm(vmin=vmin, vmax=vmax) elif norm not in ['auto', 'linear']: raise ValueError( "`norm` paramater should be 'auto', 'linear', " "'log', 'symlog' or a matplotlib Normalize " "instance or subclass.") else: # set back to matplotlib default norm = None self._vmin, self._vmax = vmin, vmax redraw_colorbar = redraw_colorbar and self.colorbar if self.plot_indices is True: self._text.set_text(self.axes_manager.indices) if self.no_nans: data = np.nan_to_num(data) if ims: # the images has already been drawn previously ims[0].set_data(data) # update extent: if 'x' in self.autoscale: self._extent[0] = self.xaxis.axis[0] - self.xaxis.scale / 2 self._extent[1] = self.xaxis.axis[-1] + self.xaxis.scale / 2 self.ax.set_xlim(self._extent[:2]) if 'y' in self.autoscale: self._extent[2] = self.yaxis.axis[-1] + self.yaxis.scale / 2 self._extent[3] = self.yaxis.axis[0] - self.yaxis.scale / 2 self.ax.set_ylim(self._extent[2:]) if 'x' in self.autoscale or 'y' in self.autoscale: ims[0].set_extent(self._extent) self._calculate_aspect() self.ax.set_aspect(self._aspect) if not self._is_rgb: ims[0].set_norm(norm) ims[0].norm.vmax, ims[0].norm.vmin = vmax, vmin if redraw_colorbar: self._colorbar.draw_all() self._colorbar.solids.set_animated( self.figure.canvas.supports_blit) else: ims[0].changed() if self.figure.canvas.supports_blit: self._update_animated() else: self.figure.canvas.draw_idle() else: # no signal have been drawn yet new_args = { 'interpolation': 'nearest', 'extent': self._extent, 'aspect': self._aspect, 'animated': self.figure.canvas.supports_blit, } if not self._is_rgb: if norm is None: new_args.update({'vmin': vmin, 'vmax': vmax}) else: new_args['norm'] = norm new_args.update(kwargs) self.ax.imshow(data, **new_args) self.figure.canvas.draw_idle() if self.axes_ticks == 'off': self.ax.set_axis_off()
def update(self, **kwargs): ims = self.ax.images # update extent: self._extent = (self.xaxis.axis[0] - self.xaxis.scale / 2., self.xaxis.axis[-1] + self.xaxis.scale / 2., self.yaxis.axis[-1] + self.yaxis.scale / 2., self.yaxis.axis[0] - self.yaxis.scale / 2.) # Turn on centre_colormap if a diverging colormap is used. if self.centre_colormap == "auto": if "cmap" in kwargs: cmap = kwargs["cmap"] elif ims: cmap = ims[0].get_cmap().name else: cmap = plt.cm.get_cmap().name if cmap in utils.MPL_DIVERGING_COLORMAPS: self.centre_colormap = True else: self.centre_colormap = False redraw_colorbar = False data = rgb_tools.rgbx2regular_array(self.data_function( axes_manager=self.axes_manager, **self.data_function_kwargs), plot_friendly=True) numrows, numcols = data.shape[:2] for marker in self.ax_markers: marker.update() if len(data.shape) == 2: def format_coord(x, y): try: col = self.xaxis.value2index(x) except ValueError: # out of axes limits col = -1 try: row = self.yaxis.value2index(y) except ValueError: row = -1 if col >= 0 and row >= 0: z = data[row, col] if np.isfinite(z): return 'x=%1.4g, y=%1.4g, intensity=%1.4g' % (x, y, z) return 'x=%1.4g, y=%1.4g' % (x, y) self.ax.format_coord = format_coord old_vmax, old_vmin = self.vmax, self.vmin self.optimize_contrast(data) # If there is an image, any of the contrast bounds have changed and # the new contrast bounds are not the same redraw the colorbar. if (ims and (old_vmax != self.vmax or old_vmin != self.vmin) and self.vmax != self.vmin): redraw_colorbar = True ims[0].autoscale() redraw_colorbar = redraw_colorbar and self.colorbar if self.plot_indices is True: self._text.set_text(self.axes_manager.indices) if self.no_nans: data = np.nan_to_num(data) if self.centre_colormap: vmin, vmax = utils.centre_colormap_values(self.vmin, self.vmax) else: vmin, vmax = self.vmin, self.vmax norm = copy.copy(self.norm) if norm == 'log': norm = LogNorm(vmin=self.vmin, vmax=self.vmax) elif inspect.isclass(norm) and issubclass(norm, Normalize): norm = norm(vmin=self.vmin, vmax=self.vmax) elif norm not in ['auto', 'linear']: raise ValueError("`norm` paramater should be 'auto', 'linear', " "'log' or a matplotlib Normalize instance or " "subclass.") else: # set back to matplotlib default norm = None if ims: # the images has already been drawn previously ims[0].set_data(data) self.ax.set_xlim(self._extent[:2]) self.ax.set_ylim(self._extent[2:]) ims[0].set_extent(self._extent) self._calculate_aspect() self.ax.set_aspect(self._aspect) ims[0].set_norm(norm) ims[0].norm.vmax, ims[0].norm.vmin = vmax, vmin if redraw_colorbar: # ims[0].autoscale() self._colorbar.draw_all() self._colorbar.solids.set_animated( self.figure.canvas.supports_blit) else: ims[0].changed() if self.figure.canvas.supports_blit: self._update_animated() else: self.figure.canvas.draw_idle() else: # no signal have been drawn yet new_args = { 'interpolation': 'nearest', 'vmin': vmin, 'vmax': vmax, 'extent': self._extent, 'aspect': self._aspect, 'animated': self.figure.canvas.supports_blit, 'norm': norm } new_args.update(kwargs) self.ax.imshow(data, **new_args) self.figure.canvas.draw_idle() if self.axes_ticks == 'off': self.ax.set_axis_off()
def update(self, **kwargs): ims = self.ax.images # update extent: self._extent = (self.xaxis.axis[0] - self.xaxis.scale / 2., self.xaxis.axis[-1] + self.xaxis.scale / 2., self.yaxis.axis[-1] + self.yaxis.scale / 2., self.yaxis.axis[0] - self.yaxis.scale / 2.) # Turn on centre_colormap if a diverging colormap is used. if self.centre_colormap == "auto": if "cmap" in kwargs: cmap = kwargs["cmap"] elif ims: cmap = ims[0].get_cmap().name else: cmap = plt.cm.get_cmap().name if cmap in utils.MPL_DIVERGING_COLORMAPS: self.centre_colormap = True else: self.centre_colormap = False redraw_colorbar = False data = rgb_tools.rgbx2regular_array( self.data_function(axes_manager=self.axes_manager), plot_friendly=True) numrows, numcols = data.shape[:2] for marker in self.ax_markers: marker.update() if len(data.shape) == 2: def format_coord(x, y): try: col = self.xaxis.value2index(x) except ValueError: # out of axes limits col = -1 try: row = self.yaxis.value2index(y) except ValueError: row = -1 if col >= 0 and row >= 0: z = data[row, col] return 'x=%1.4g, y=%1.4g, intensity=%1.4g' % (x, y, z) else: return 'x=%1.4g, y=%1.4g' % (x, y) self.ax.format_coord = format_coord old_vmax, old_vmin = self.vmax, self.vmin self.optimize_contrast(data) # If there is an image, any of the contrast bounds have changed and # the new contrast bounds are not the same redraw the colorbar. if (ims and (old_vmax != self.vmax or old_vmin != self.vmin) and self.vmax != self.vmin): redraw_colorbar = True ims[0].autoscale() redraw_colorbar = redraw_colorbar and self.colorbar if self.plot_indices is True: self._text.set_text(self.axes_manager.indices) if self.no_nans: data = np.nan_to_num(data) if self.centre_colormap: vmin, vmax = utils.centre_colormap_values(self.vmin, self.vmax) else: vmin, vmax = self.vmin, self.vmax if ims: ims[0].set_data(data) self.ax.set_xlim(self._extent[:2]) self.ax.set_ylim(self._extent[2:]) ims[0].set_extent(self._extent) self._calculate_aspect() self.ax.set_aspect(self._aspect) ims[0].norm.vmax, ims[0].norm.vmin = vmax, vmin if redraw_colorbar is True: # ims[0].autoscale() self._colorbar.draw_all() self._colorbar.solids.set_animated(True) else: ims[0].changed() self._draw_animated() # It seems that nans they're simply not drawn, so simply replacing # the data does not update the value of the nan pixels to the # background color. We redraw everything as a workaround. if np.isnan(data).any(): self.figure.canvas.draw() else: new_args = {'interpolation': 'nearest', 'vmin': vmin, 'vmax': vmax, 'extent': self._extent, 'aspect': self._aspect, 'animated': True} new_args.update(kwargs) self.ax.imshow(data, **new_args) self.figure.canvas.draw()
def update(self, data_changed=True, **kwargs): if data_changed: # When working with lazy signals the following may reread the data # from disk unnecessarily, for example when updating the image just # to recompute the histogram to adjust the contrast. In those cases # use `data_changed=True`. _logger.debug("Updating image slowly because `data_changed=True`") self._update_data() data = self._current_data optimize_contrast = kwargs.pop("optimize_contrast", False) if rgb_tools.is_rgbx(data): self.colorbar = False data = rgb_tools.rgbx2regular_array(data, plot_friendly=True) data = self._current_data = data self._is_rgb = True ims = self.ax.images # update extent: self._extent = (self.xaxis.axis[0] - self.xaxis.scale / 2., self.xaxis.axis[-1] + self.xaxis.scale / 2., self.yaxis.axis[-1] + self.yaxis.scale / 2., self.yaxis.axis[0] - self.yaxis.scale / 2.) # Turn on centre_colormap if a diverging colormap is used. if not self._is_rgb and self.centre_colormap == "auto": if "cmap" in kwargs: cmap = kwargs["cmap"] elif ims: cmap = ims[0].get_cmap().name else: cmap = plt.cm.get_cmap().name if cmap in utils.MPL_DIVERGING_COLORMAPS: self.centre_colormap = True else: self.centre_colormap = False redraw_colorbar = False for marker in self.ax_markers: marker.update() if not self._is_rgb: def format_coord(x, y): try: col = self.xaxis.value2index(x) except ValueError: # out of axes limits col = -1 try: row = self.yaxis.value2index(y) except ValueError: row = -1 if col >= 0 and row >= 0: z = data[row, col] if np.isfinite(z): return f'x={x:1.4g}, y={y:1.4g}, intensity={z:1.4g}' return f'x={x:1.4g}, y={y:1.4g}' self.ax.format_coord = format_coord old_vmin, old_vmax = self.vmin, self.vmax self.optimize_contrast(data, optimize_contrast) # Use _vmin_auto and _vmax_auto if optimize_contrast is True if optimize_contrast: vmin, vmax = self._vmin_auto, self._vmax_auto else: vmin, vmax = self.vmin, self.vmax # If there is an image, any of the contrast bounds have changed and # the new contrast bounds are not the same redraw the colorbar. if (ims and (old_vmin != vmin or old_vmax != vmax) and vmin != vmax): redraw_colorbar = True ims[0].autoscale() if self.centre_colormap: vmin, vmax = utils.centre_colormap_values(vmin, vmax) else: vmin, vmax = vmin, vmax if self.norm == 'auto' and self.gamma != 1.0: self.norm = 'power' norm = copy.copy(self.norm) if norm == 'power': # with auto norm, we use the power norm when gamma differs from its # default value. norm = PowerNorm(self.gamma, vmin=vmin, vmax=vmax) elif norm == 'log': if np.nanmax(data) <= 0: raise ValueError( 'All displayed data are <= 0 and can not ' 'be plotted using `norm="log"`. ' 'Use `norm="symlog"` to plot on a log scale.') if np.nanmin(data) <= 0: vmin = np.nanmin(np.where(data > 0, data, np.inf)) norm = LogNorm(vmin=vmin, vmax=vmax) elif norm == 'symlog': norm = SymLogNorm(linthresh=self.linthresh, linscale=self.linscale, vmin=vmin, vmax=vmax) elif inspect.isclass(norm) and issubclass(norm, Normalize): norm = norm(vmin=vmin, vmax=vmax) elif norm not in ['auto', 'linear']: raise ValueError( "`norm` paramater should be 'auto', 'linear', " "'log', 'symlog' or a matplotlib Normalize " "instance or subclass.") else: # set back to matplotlib default norm = None redraw_colorbar = redraw_colorbar and self.colorbar if self.plot_indices is True: self._text.set_text(self.axes_manager.indices) if self.no_nans: data = np.nan_to_num(data) if ims: # the images has already been drawn previously ims[0].set_data(data) self.ax.set_xlim(self._extent[:2]) self.ax.set_ylim(self._extent[2:]) ims[0].set_extent(self._extent) self._calculate_aspect() self.ax.set_aspect(self._aspect) if not self._is_rgb: ims[0].set_norm(norm) ims[0].norm.vmax, ims[0].norm.vmin = vmax, vmin if redraw_colorbar: # ims[0].autoscale() self._colorbar.draw_all() self._colorbar.solids.set_animated( self.figure.canvas.supports_blit) else: ims[0].changed() if self.figure.canvas.supports_blit: self._update_animated() else: self.figure.canvas.draw_idle() else: # no signal have been drawn yet new_args = { 'interpolation': 'nearest', 'extent': self._extent, 'aspect': self._aspect, 'animated': self.figure.canvas.supports_blit, } if not self._is_rgb: new_args.update({'vmin': vmin, 'vmax': vmax, 'norm': norm}) new_args.update(kwargs) self.ax.imshow(data, **new_args) self.figure.canvas.draw_idle() if self.axes_ticks == 'off': self.ax.set_axis_off()