def span_where(x, ymin, ymax, where, **kwargs): """ Create a BrokenBarHCollection to plot horizontal bars from over the regions in *x* where *where* is True. The bars range on the y-axis from *ymin* to *ymax* A :class:`BrokenBarHCollection` is returned. *kwargs* are passed on to the collection. """ xranges = [] for ind0, ind1 in mlab.contiguous_regions(where): xslice = x[ind0:ind1] if not len(xslice): continue xranges.append((xslice[0], xslice[-1]-xslice[0])) collection = BrokenBarHCollection(xranges, [ymin, ymax-ymin], **kwargs) return collection
def detect_elements(self, acoustic_processing): """ The detection is made over an acoustic processing detecting continuous areas of it over the specified threshold :param acoustic_processing: the array with the acoustic processing made :return: """ if self.envelope_method is None: return [] threshold = self.envelope_method.get_threshold_level( acoustic_processing) self.threshold_visual_item = pg.InfiniteLine(pos=threshold * self._y_scale, angle=0, pen=self.THRESHOLD_PEN) return mlab.contiguous_regions(acoustic_processing > threshold)
def contiguous_domains(self): from matplotlib import mlab xlim = self._get_xlim() num = self.config.num_boundary_samples xs = numpy.linspace(*xlim, num=num) (ymin, ymax) = self.config.ylim (lower_f, upper_f) = self._y_funcs() lower = lower_f(xs) upper = upper_f(xs) def find_bound(i, fallback): xs2 = numpy.linspace(xs[i - 1], xs[i], num_finer) diff = upper_f(xs2) - lower_f(xs2) try: if diff[0] > 0: j = mlab.cross_from_above(diff, 0)[0] - 1 else: j = mlab.cross_from_below(diff, 0)[0] return xs2[j] except IndexError: return fallback num_finer = num domains = [] for (i, j) in mlab.contiguous_regions(lower < upper): if i == 0: x0 = xlim[0] else: x0 = find_bound(i, xs[i]) if j == len(upper): x1 = xlim[1] else: x1 = find_bound(j, xs[j - 1]) domains.append((x0, x1)) return domains
def __call__(self, md): # TODO Make sure we do not get strange starting and ending times # resulting from strange bins results = [] log = md.getLog() for cage in md.getInmates(): for side in range(1, 9): # XXX: idea - get timestamps from md._Data_logDateTime tt = np.array([toTimestampUTC(l.DateTime) for l in log \ if l.Type == 'Lickometer' and l.Cage == cage and l.Side == side]) if len(tt) > 0: ttMin = tt.min() span = tt.max() - ttMin nBins = ceil(span / self.medBin) medBins = np.linspace(ttMin, ttMin + nBins * self.medBin, int(nBins) + 1) medHist, _ = np.histogram(tt, bins=medBins) # short_bins = np.arange(tt.min(), tt.max() # + self.short_bin, self.short_bin) # short_hist = np.histogram(tt, bins=short_bins)[0] if (medHist > self.medThreshold).any(): # or np.all(short_hist > self.threshold_short): pass idcs = mmlab.contiguous_regions(medHist > self.medThreshold) # print(idcs) for tstartidx, tstopidx in idcs: tstart = medBins[tstartidx] tstop = medBins[tstopidx] # print('%s\t%s" % (tstart, tstop)) results.append(ExcludeMiceData(startTime=datetime.fromtimestamp(tstart, UTC), endTime=datetime.fromtimestamp(tstop, UTC), logType='Lickometer', cage=cage, corner=(side + 1) // 2, side=side, notes=str(sum(medHist[tstartidx:tstopidx])) + ' cases. ' + self.notes)) return tuple(results)
def _my_fill(self, axes, y, x1, x2=0, where=None, interpolate=False, step=None, **kwargs): # Handle united data, such as dates axes._process_unit_info(ydata=y, xdata=x1, kwargs=kwargs) axes._process_unit_info(xdata=x2) # Convert the arrays so we can work with them y = np.ma.masked_invalid(axes.convert_yunits(y)) x1 = np.ma.masked_invalid(axes.convert_xunits(x1)) x2 = np.ma.masked_invalid(axes.convert_xunits(x2)) if x1.ndim == 0: x1 = np.ones_like(y) * x1 if x2.ndim == 0: x2 = np.ones_like(y) * x2 if where is None: where = np.ones(len(y), np.bool) else: where = np.asarray(where, np.bool) if not (y.shape == x1.shape == x2.shape == where.shape): raise ValueError("Argument dimensions are incompatible") mask = reduce(np.ma.mask_or, [np.ma.getmask(a) for a in (y, x1, x2)]) if mask is not np.ma.nomask: where &= ~mask polys = [] for ind0, ind1 in mlab.contiguous_regions(where): yslice = y[ind0:ind1] x1slice = x1[ind0:ind1] x2slice = x2[ind0:ind1] if step is not None: step_func = cbook.STEP_LOOKUP_MAP[step] yslice, x1slice, x2slice = step_func(yslice, x1slice, x2slice) if not len(yslice): continue N = len(yslice) Y = np.zeros((2 * N + 2, 2), np.float) if interpolate: def get_interp_point(ind): im1 = max(ind - 1, 0) y_values = y[im1:ind + 1] diff_values = x1[im1:ind + 1] - x2[im1:ind + 1] x1_values = x1[im1:ind + 1] if len(diff_values) == 2: if np.ma.is_masked(diff_values[1]): return y[im1], x1[im1] elif np.ma.is_masked(diff_values[0]): return y[ind], x1[ind] diff_order = diff_values.argsort() diff_root_y = np.interp(0, diff_values[diff_order], y_values[diff_order]) diff_root_x = np.interp(diff_root_y, y_values, x1_values) return diff_root_x, diff_root_y start = get_interp_point(ind0) end = get_interp_point(ind1) else: # the purpose of the next two lines is for when x2 is a # scalar like 0 and we want the fill to go all the way # down to 0 even if none of the x1 sample points do start = x2slice[0], yslice[0] # Y[0] = x2slice[0], yslice[0] end = x2slice[-1], yslice[ -1] # Y[N + 1] = x2slice[-1], yslice[-1] Y[0] = start Y[N + 1] = end Y[1:N + 1, 0] = x1slice Y[1:N + 1, 1] = yslice Y[N + 2:, 0] = x2slice[::-1] Y[N + 2:, 1] = yslice[::-1] polys.append(Y) collection = mcoll.PolyCollection(polys, **kwargs) # now update the datalim and autoscale X1Y = np.array([x1[where], y[where]]).T X2Y = np.array([x2[where], y[where]]).T axes.dataLim.update_from_data_xy(X1Y, axes.ignore_existing_data_limits, updatex=True, updatey=True) axes.ignore_existing_data_limits = False axes.dataLim.update_from_data_xy(X2Y, axes.ignore_existing_data_limits, updatex=True, updatey=False) axes.add_collection(collection, autolim=False) axes.autoscale_view() return collection
def gradient_fill(x, percentiles, ax=None, fignum=None, **kwargs): _, ax = ax_default(fignum, ax) plots = [] #here's the box if 'linewidth' not in kwargs: kwargs['linewidth'] = 0.5 if not 'alpha' in kwargs.keys(): kwargs['alpha'] = 1. / (len(percentiles)) # pop where from kwargs where = kwargs.pop('where') if 'where' in kwargs else None # pop interpolate, which we actually do not do here! if 'interpolate' in kwargs: kwargs.pop('interpolate') def pairwise(inlist): l = len(inlist) for i in range(int(np.ceil(l / 2.))): yield inlist[:][i], inlist[:][(l - 1) - i] polycol = [] for y1, y2 in pairwise(percentiles): import matplotlib.mlab as mlab # Handle united data, such as dates ax._process_unit_info(xdata=x, ydata=y1) ax._process_unit_info(ydata=y2) # Convert the arrays so we can work with them from numpy import ma x = ma.masked_invalid(ax.convert_xunits(x)) y1 = ma.masked_invalid(ax.convert_yunits(y1)) y2 = ma.masked_invalid(ax.convert_yunits(y2)) if y1.ndim == 0: y1 = np.ones_like(x) * y1 if y2.ndim == 0: y2 = np.ones_like(x) * y2 if where is None: where = np.ones(len(x), np.bool) else: where = np.asarray(where, np.bool) if not (x.shape == y1.shape == y2.shape == where.shape): raise ValueError("Argument dimensions are incompatible") mask = reduce(ma.mask_or, [ma.getmask(a) for a in (x, y1, y2)]) if mask is not ma.nomask: where &= ~mask polys = [] for ind0, ind1 in mlab.contiguous_regions(where): xslice = x[ind0:ind1] y1slice = y1[ind0:ind1] y2slice = y2[ind0:ind1] if not len(xslice): continue N = len(xslice) X = np.zeros((2 * N + 2, 2), np.float) # the purpose of the next two lines is for when y2 is a # scalar like 0 and we want the fill to go all the way # down to 0 even if none of the y1 sample points do start = xslice[0], y2slice[0] end = xslice[-1], y2slice[-1] X[0] = start X[N + 1] = end X[1:N + 1, 0] = xslice X[1:N + 1, 1] = y1slice X[N + 2:, 0] = xslice[::-1] X[N + 2:, 1] = y2slice[::-1] polys.append(X) polycol.extend(polys) from matplotlib.collections import PolyCollection plots.append(PolyCollection(polycol, **kwargs)) ax.add_collection(plots[-1], autolim=True) ax.autoscale_view() return plots
def fill_gradient(self, canvas, X, percentiles, color=Tango.colorsHex['mediumBlue'], label=None, **kwargs): ax = canvas plots = [] if 'edgecolors' not in kwargs: kwargs['edgecolors'] = 'none' if 'facecolors' in kwargs: color = kwargs.pop('facecolors') if 'array' in kwargs: array = kwargs.pop('array') else: array = 1.-np.abs(np.linspace(-.97, .97, len(percentiles)-1)) if 'alpha' in kwargs: alpha = kwargs.pop('alpha') else: alpha = .8 if 'cmap' in kwargs: cmap = kwargs.pop('cmap') else: cmap = LinearSegmentedColormap.from_list('WhToColor', (color, color), N=array.size) cmap._init() cmap._lut[:-3, -1] = alpha*array kwargs['facecolors'] = [cmap(i) for i in np.linspace(0,1,cmap.N)] # pop where from kwargs where = kwargs.pop('where') if 'where' in kwargs else None # pop interpolate, which we actually do not do here! if 'interpolate' in kwargs: kwargs.pop('interpolate') def pairwise(iterable): "s -> (s0,s1), (s1,s2), (s2, s3), ..." from itertools import tee #try: # from itertools import izip as zip #except ImportError: # pass a, b = tee(iterable) next(b, None) return zip(a, b) polycol = [] for y1, y2 in pairwise(percentiles): import matplotlib.mlab as mlab # Handle united data, such as dates ax._process_unit_info(xdata=X, ydata=y1) ax._process_unit_info(ydata=y2) # Convert the arrays so we can work with them from numpy import ma x = ma.masked_invalid(ax.convert_xunits(X)) y1 = ma.masked_invalid(ax.convert_yunits(y1)) y2 = ma.masked_invalid(ax.convert_yunits(y2)) if y1.ndim == 0: y1 = np.ones_like(x) * y1 if y2.ndim == 0: y2 = np.ones_like(x) * y2 if where is None: where = np.ones(len(x), np.bool) else: where = np.asarray(where, np.bool) if not (x.shape == y1.shape == y2.shape == where.shape): raise ValueError("Argument dimensions are incompatible") from functools import reduce mask = reduce(ma.mask_or, [ma.getmask(a) for a in (x, y1, y2)]) if mask is not ma.nomask: where &= ~mask polys = [] for ind0, ind1 in mlab.contiguous_regions(where): xslice = x[ind0:ind1] y1slice = y1[ind0:ind1] y2slice = y2[ind0:ind1] if not len(xslice): continue N = len(xslice) p = np.zeros((2 * N + 2, 2), np.float) # the purpose of the next two lines is for when y2 is a # scalar like 0 and we want the fill to go all the way # down to 0 even if none of the y1 sample points do start = xslice[0], y2slice[0] end = xslice[-1], y2slice[-1] p[0] = start p[N + 1] = end p[1:N + 1, 0] = xslice p[1:N + 1, 1] = y1slice p[N + 2:, 0] = xslice[::-1] p[N + 2:, 1] = y2slice[::-1] polys.append(p) polycol.extend(polys) from matplotlib.collections import PolyCollection if 'zorder' not in kwargs: kwargs['zorder'] = 0 plots.append(PolyCollection(polycol, **kwargs)) ax.add_collection(plots[-1], autolim=True) ax.autoscale_view() return plots
def errorfill(x, y, yerr=None, xerr=None, color=None, ls=None, lw=None, where=None, alpha=1, alpha_fill=0.3, label='', label_fill='', ax=None): """Plot data with errors marked by a filled region. Parameters ---------- x, y : arrays Coordinates of data. yerr, xerr: [scalar | N, (N, 1), or (2, N) array] Error for the input data. - If scalar, then filled region spans `y +/- yerr` or `x +/- xerr`. color : Matplotlib color Color of line and fill region. ls : Matplotlib line style Style of the line lw : Matplotlib line width, float value in points Width of the line where : If None, default to fill between everywhere. If not None, it is an N-length numpy boolean array and the fill will only happen over the regions where where==True. alpha : float Opacity used for plotting. alpha_fill : float Opacity of filled region. Note: the actual opacity of the fill is `alpha * alpha_fill`. label : str Label for line. label_fill : str Label for filled region. ax : Axis instance The plot is drawn on axis `ax`. If `None` the current axis is used """ ax = ax if ax is not None else plt.gca() alpha_fill *= alpha if color is None: color = next(ax._get_lines.color_cycle) #python 2 and 3 compatible if ls is None: ls = plt.rcParams['lines.linestyle'] if lw is None: lw = plt.rcParams['lines.linewidth'] if where is None: #plot the all line if where is not set ax.plot(x, y, color, linestyle=ls, linewidth=lw, alpha=alpha, label=label) else: #emulate the 'where' keyword in fill_between (from matplotlib/axes.py) import matplotlib.mlab as mlab for ind0, ind1 in mlab.contiguous_regions(where): xslice = x[ind0:ind1] yslice = y[ind0:ind1] if not len(xslice): continue ax.plot(xslice, yslice, color, linestyle=ls, linewidth=lw, alpha=alpha, label=label) if yerr is not None and xerr is not None: msg = "Setting both `yerr` and `xerr` is not supported. Ignore `xerr`." warnings.warn(msg) kwargs_fill = dict(color=color, alpha=alpha_fill, label=label_fill) if yerr is not None: ymin, ymax = extrema_from_error_input(y, yerr) fill_between(x, ymax, ymin, ax=ax, where=where, **kwargs_fill) elif xerr is not None: xmin, xmax = extrema_from_error_input(x, xerr) fill_between_x(y, xmax, xmin, ax=ax, where=where, **kwargs_fill)
def __call__(self, md): results = [] log = md.getLog(order='DateTime') for cage in md.getInmates(): for corner in range(1, 5): # XXX: idea - get timestamps from md._Data_logDateTime tt = np.array([toTimestampUTC(l.DateTime) for l in log \ if l.Cage == cage and l.Corner == corner and l.Notes.startswith('Presence signal')]) if len(tt) > 0: # print('%s\t%s\t%s' % (cage, corner, len(events))) ttOrig = tt.copy() tds = np.diff(tt) # # Wywalanie jesli sa co najmniej 3 w czasie ponizej minuty # idcs = np.zeros_like(tt) # for idx, there, dthere in zip(range(len(tt)-1), tt[:-1], tds): # if dthere < 60.: # # print idx, there, dthere # idx2 = np.where((tt >= there)&(tt < there + 60.))[0] # # print idx, idx2 # if len(idx2) >= 3: # idcs[idx2] = 1 # print idcs # tt = np.delete(tt, np.where(idcs)) # Wywalamy blizsze siebie niz 30 s idcs = np.where(tds < 30.)[0] tt = np.delete(tt, np.unique(np.array([idcs, idcs+1]))) # XXX: czy to spowoduje, ze ciag bledow pozostanie niezauwazony??? if len(tt) > 0: # Wywalamy jesli izolowany tds = np.diff(tt) mask = np.zeros_like(tt) mask[0] += 0.5 mask[-1] += 0.5 idcs2 = np.where(tds > 1800.)[0] mask[idcs2] += 0.5 mask[idcs2 + 1] += 0.5 tt = np.delete(tt, np.where(mask > 0.75)) if len(tt) > 0: # Pomijamy jesli <= 4 bledy w dobie ttMin = tt.min() span = tt.max() - ttMin nBins = ceil(span / (24 * 3600.)) longBins = np.linspace(ttMin, ttMin + nBins * 24 * 3600., int(nBins) + 1) hist, _ = np.histogram(tt, bins=longBins) print(tt) print(longBins) print(hist) if (hist > 4).any(): # print('%s\t%s\t%s\t%s' % (cage, corner, 'Zostalo ', len(tt))) nBins = ceil(span / self.finBin) bins = np.arange(ttMin, ttMin + nBins * self.finBin, int(nBins) + 1) hist, _ = np.histogram(tt, bins=bins) idcs = mmlab.contiguous_regions(hist) for tstartidx, tstopidx in idcs: tstart = bins[tstartidx] tstop = bins[tstopidx] results.append(ExcludeMiceData(startTime=datetime.fromtimestamp(tstart, UTC), endTime=datetime.fromtimestamp(tstop, UTC), logType='Presence', cage=cage, corner=corner, notes=str(sum(hist[tstartidx:tstopidx])) + ' cases. ' + self.notes)) return tuple(results)
def errorfill(x, y, yerr=None, xerr=None, color=None, ls=None, lw=None, where=None, alpha=1, alpha_fill=0.3, label='', label_fill='', ax=None): """Plot data with errors marked by a filled region. Parameters ---------- x, y : arrays Coordinates of data. yerr, xerr: [scalar | N, (N, 1), or (2, N) array] Error for the input data. - If scalar, then filled region spans `y +/- yerr` or `x +/- xerr`. color : Matplotlib color Color of line and fill region. ls : Matplotlib line style Style of the line lw : Matplotlib line width, float value in points Width of the line where : If None, default to fill between everywhere. If not None, it is an N-length numpy boolean array and the fill will only happen over the regions where where==True. alpha : float Opacity used for plotting. alpha_fill : float Opacity of filled region. Note: the actual opacity of the fill is `alpha * alpha_fill`. label : str Label for line. label_fill : str Label for filled region. ax : Axis instance The plot is drawn on axis `ax`. If `None` the current axis is used """ ax = ax if ax is not None else plt.gca() alpha_fill *= alpha if color is None: color = ax._get_lines.color_cycle.next() if ls is None: ls = plt.rcParams['lines.linestyle'] if lw is None: lw = plt.rcParams['lines.linewidth'] if where is None: #plot the all line if where is not set ax.plot(x, y, color, linestyle=ls, linewidth=lw, alpha=alpha, label=label) else: #emulate the 'where' keyword in fill_between (from matplotlib/axes.py) import matplotlib.mlab as mlab for ind0, ind1 in mlab.contiguous_regions(where): xslice = x[ind0:ind1] yslice = y[ind0:ind1] if not len(xslice): continue ax.plot(xslice, yslice, color, linestyle=ls, linewidth=lw, alpha=alpha, label=label) if yerr is not None and xerr is not None: msg = "Setting both `yerr` and `xerr` is not supported. Ignore `xerr`." warnings.warn(msg) kwargs_fill = dict(color=color, alpha=alpha_fill, label=label_fill) if yerr is not None: ymin, ymax = extrema_from_error_input(y, yerr) fill_between(x, ymax, ymin, ax=ax, where=where, **kwargs_fill) elif xerr is not None: xmin, xmax = extrema_from_error_input(x, xerr) fill_between_x(y, xmax, xmin, ax=ax, where=where, **kwargs_fill)