コード例 #1
0
 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
コード例 #2
0
    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
コード例 #3
0
    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)
コード例 #4
0
ファイル: regions.py プロジェクト: wwwennie/miu_maps
    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
コード例 #5
0
ファイル: LogAnalyser.py プロジェクト: Neuroinflab/PyMICE
  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)
コード例 #6
0
ファイル: regions.py プロジェクト: tkf/fillplots
    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
コード例 #7
0
ファイル: repr_density.py プロジェクト: giruenf/GRIPy
    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
コード例 #8
0
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
コード例 #9
0
    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
コード例 #10
0
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)
コード例 #11
0
ファイル: LogAnalyser.py プロジェクト: Neuroinflab/PyMICE
  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)
コード例 #12
0
ファイル: errorfill.py プロジェクト: lambdalisue/mpltools
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)