def update_histogram(self): if self._histogram_cache is not None: return self._histogram_cache if not self._viewer_callbacks_set: self.viewer_state.add_callback('x_att', self.reset_cache, priority=100000) self.viewer_state.add_callback('x_log', self.reset_cache, priority=100000) self.viewer_state.add_callback('hist_x_min', self.reset_cache, priority=100000) self.viewer_state.add_callback('hist_x_max', self.reset_cache, priority=100000) self.viewer_state.add_callback('hist_n_bin', self.reset_cache, priority=100000) self._viewer_callbacks_set = True if (self.viewer_state is None or self.viewer_state.x_att is None or self.viewer_state.hist_x_min is None or self.viewer_state.hist_x_max is None or self.viewer_state.hist_n_bin is None or self.viewer_state.x_log is None): raise IncompatibleDataException() if isinstance(self.layer, Subset): data = self.layer.data subset_state = self.layer.subset_state else: data = self.layer subset_state = None range = sorted( (self.viewer_state.hist_x_min, self.viewer_state.hist_x_max)) hist_values = data.compute_histogram( [self._viewer_state.x_att], range=[range], bins=[self._viewer_state.hist_n_bin], log=[self._viewer_state.x_log], subset_state=subset_state) # TODO: determine whether this belongs here or in the layer artist if isinstance(range[0], np.datetime64): range = [datetime64_to_mpl(range[0]), datetime64_to_mpl(range[1])] if self._viewer_state.x_log: hist_edges = np.logspace(np.log10(range[0]), np.log10(range[1]), self._viewer_state.hist_n_bin + 1) else: hist_edges = np.linspace(range[0], range[1], self._viewer_state.hist_n_bin + 1) self._histogram_cache = hist_edges, hist_values
def update_histogram(self): current_settings = (id(self.viewer_state.x_att), self.viewer_state.x_log, self.viewer_state.hist_x_min, self.viewer_state.hist_x_max, self.viewer_state.hist_n_bin) if self._histogram_cache is not None and self._histogram_cache[ 0] == current_settings: return self._histogram_cache[1] if (self.viewer_state is None or self.viewer_state.x_att is None or self.viewer_state.hist_x_min is None or self.viewer_state.hist_x_max is None or self.viewer_state.hist_n_bin is None or self.viewer_state.x_log is None): raise IncompatibleDataException() if isinstance(self.layer, Subset): data = self.layer.data subset_state = self.layer.subset_state else: data = self.layer subset_state = None range = sorted( (self.viewer_state.hist_x_min, self.viewer_state.hist_x_max)) hist_values = data.compute_histogram( [self._viewer_state.x_att], range=[range], bins=[self._viewer_state.hist_n_bin], log=[self._viewer_state.x_log], subset_state=subset_state) # TODO: determine whether this belongs here or in the layer artist if isinstance(range[0], np.datetime64): range = [datetime64_to_mpl(range[0]), datetime64_to_mpl(range[1])] if self._viewer_state.x_log: hist_edges = np.logspace(np.log10(range[0]), np.log10(range[1]), self._viewer_state.hist_n_bin + 1) else: hist_edges = np.linspace(range[0], range[1], self._viewer_state.hist_n_bin + 1) self._histogram_cache = current_settings, (hist_edges, hist_values)
def update_histogram(self): if self._histogram_cache is not None: return self._histogram_cache if not self._viewer_callbacks_set: self.viewer_state.add_callback('x_att', self.reset_cache, priority=100000) self.viewer_state.add_callback('x_log', self.reset_cache, priority=100000) self.viewer_state.add_callback('hist_x_min', self.reset_cache, priority=100000) self.viewer_state.add_callback('hist_x_max', self.reset_cache, priority=100000) self.viewer_state.add_callback('hist_n_bin', self.reset_cache, priority=100000) self._viewer_callbacks_set = True if (self.viewer_state is None or self.viewer_state.x_att is None or self.viewer_state.hist_x_min is None or self.viewer_state.hist_x_max is None or self.viewer_state.hist_n_bin is None or self.viewer_state.x_log is None): raise IncompatibleDataException() if isinstance(self.layer, Subset): data = self.layer.data subset_state = self.layer.subset_state else: data = self.layer subset_state = None range = sorted((self.viewer_state.hist_x_min, self.viewer_state.hist_x_max)) hist_values = data.compute_histogram([self._viewer_state.x_att], range=[range], bins=[self._viewer_state.hist_n_bin], log=[self._viewer_state.x_log], subset_state=subset_state) # TODO: determine whether this belongs here or in the layer artist if isinstance(range[0], np.datetime64): range = [datetime64_to_mpl(range[0]), datetime64_to_mpl(range[1])] if self._viewer_state.x_log: hist_edges = np.logspace(np.log10(range[0]), np.log10(range[1]), self._viewer_state.hist_n_bin + 1) else: hist_edges = np.linspace(range[0], range[1], self._viewer_state.hist_n_bin + 1) self._histogram_cache = hist_edges, hist_values
def update_histogram(self): current_settings = (id(self.viewer_state.x_att), self.viewer_state.x_log, self.viewer_state.hist_x_min, self.viewer_state.hist_x_max, self.viewer_state.hist_n_bin) if self._histogram_cache is not None and self._histogram_cache[0] == current_settings: return self._histogram_cache[1] if (self.viewer_state is None or self.viewer_state.x_att is None or self.viewer_state.hist_x_min is None or self.viewer_state.hist_x_max is None or self.viewer_state.hist_n_bin is None or self.viewer_state.x_log is None): raise IncompatibleDataException() if isinstance(self.layer, Subset): data = self.layer.data subset_state = self.layer.subset_state else: data = self.layer subset_state = None range = sorted((self.viewer_state.hist_x_min, self.viewer_state.hist_x_max)) hist_values = data.compute_histogram([self._viewer_state.x_att], range=[range], bins=[self._viewer_state.hist_n_bin], log=[self._viewer_state.x_log], subset_state=subset_state) # TODO: determine whether this belongs here or in the layer artist if isinstance(range[0], np.datetime64): range = [datetime64_to_mpl(range[0]), datetime64_to_mpl(range[1])] if self._viewer_state.x_log: hist_edges = np.logspace(np.log10(range[0]), np.log10(range[1]), self._viewer_state.hist_n_bin + 1) else: hist_edges = np.linspace(range[0], range[1], self._viewer_state.hist_n_bin + 1) self._histogram_cache = current_settings, (hist_edges, hist_values)
def _update_data(self): # Layer artist has been cleared already if len(self.mpl_artists) == 0: return try: if not self.state.density_map: x = ensure_numerical( self.layer[self._viewer_state.x_att].ravel()) if x.dtype.kind == 'M': x = datetime64_to_mpl(x) except (IncompatibleAttribute, IndexError): # The following includes a call to self.clear() self.disable_invalid_attributes(self._viewer_state.x_att) return else: self.enable() try: if not self.state.density_map: y = ensure_numerical( self.layer[self._viewer_state.y_att].ravel()) if y.dtype.kind == 'M': y = datetime64_to_mpl(y) except (IncompatibleAttribute, IndexError): # The following includes a call to self.clear() self.disable_invalid_attributes(self._viewer_state.y_att) return else: self.enable() if self.state.markers_visible: if self.state.density_map: # We don't use x, y here because we actually make use of the # ability of the density artist to call a custom histogram # method which is defined on this class and does the data # access. self.plot_artist.set_data([], []) self.scatter_artist.set_offsets(np.zeros((0, 2))) else: if self.state.cmap_mode == 'Fixed' and self.state.size_mode == 'Fixed': # In this case we use Matplotlib's plot function because it has much # better performance than scatter. self.plot_artist.set_data(x, y) self.scatter_artist.set_offsets(np.zeros((0, 2))) else: self.plot_artist.set_data([], []) offsets = np.vstack((x, y)).transpose() self.scatter_artist.set_offsets(offsets) else: self.plot_artist.set_data([], []) self.scatter_artist.set_offsets(np.zeros((0, 2))) if self.state.line_visible: if self.state.cmap_mode == 'Fixed': self.line_collection.set_points(x, y, oversample=False) else: # In the case where we want to color the line, we need to over # sample the line by a factor of two so that we can assign the # correct colors to segments - if we didn't do this, then # segments on one side of a point would be a different color # from the other side. With oversampling, we can have half a # segment on either side of a point be the same color as a # point self.line_collection.set_points(x, y) else: self.line_collection.set_points([], []) for eartist in ravel_artists(self.errorbar_artist): try: eartist.remove() except ValueError: pass if self.vector_artist is not None: self.vector_artist.remove() self.vector_artist = None if self.state.vector_visible: if self.state.vx_att is not None and self.state.vy_att is not None: vx = ensure_numerical(self.layer[self.state.vx_att].ravel()) vy = ensure_numerical(self.layer[self.state.vy_att].ravel()) if self.state.vector_mode == 'Polar': ang = vx length = vy # assume ang is anti clockwise from the x axis vx = length * np.cos(np.radians(ang)) vy = length * np.sin(np.radians(ang)) else: vx = None vy = None if self.state.vector_arrowhead: hw = 3 hl = 5 else: hw = 1 hl = 0 vmax = nanmax(np.hypot(vx, vy)) self.vector_artist = self.axes.quiver( x, y, vx, vy, units='width', pivot=self.state.vector_origin, headwidth=hw, headlength=hl, scale_units='width', angles='xy', scale=10 / self.state.vector_scaling * vmax) self.mpl_artists[self.vector_index] = self.vector_artist if self.state.xerr_visible or self.state.yerr_visible: keep = ~np.isnan(x) & ~np.isnan(y) if self.state.xerr_visible and self.state.xerr_att is not None: xerr = ensure_numerical( self.layer[self.state.xerr_att].ravel()).copy() keep &= ~np.isnan(xerr) else: xerr = None if self.state.yerr_visible and self.state.yerr_att is not None: yerr = ensure_numerical( self.layer[self.state.yerr_att].ravel()).copy() keep &= ~np.isnan(yerr) else: yerr = None if xerr is not None: xerr = xerr[keep] if yerr is not None: yerr = yerr[keep] self._errorbar_keep = keep self.errorbar_artist = self.axes.errorbar(x[keep], y[keep], fmt='none', xerr=xerr, yerr=yerr) self.mpl_artists[self.errorbar_index] = self.errorbar_artist