Пример #1
0
    def background_gradient(self, cmap='PuBu', low=0, high=0, axis=0,
                            subset=None):
        """
        Color the background in a gradient according to
        the data in each column (optionally row).
        Requires matplotlib.

        Parameters
        ----------
        cmap: str or colormap
            matplotlib colormap
        low, high: float
            compress the range by these values.
        axis: int or str
            1 or 'columns' for columnwise, 0 or 'index' for rowwise
        subset: IndexSlice
            a valid slice for ``data`` to limit the style application to

        Returns
        -------
        self : Styler

        Notes
        -----
        Tune ``low`` and ``high`` to keep the text legible by
        not using the entire range of the color map. These extend
        the range of the data by ``low * (x.max() - x.min())``
        and ``high * (x.max() - x.min())`` before normalizing.
        """
        subset = _maybe_numeric_slice(self.data, subset)
        subset = _non_reducing_slice(subset)
        self.apply(self._background_gradient, cmap=cmap, subset=subset,
                   axis=axis, low=low, high=high)
        return self
Пример #2
0
    def _apply(self, func, axis=0, subset=None, **kwargs):
        subset = slice(None) if subset is None else subset
        subset = _non_reducing_slice(subset)
        data = self.data.loc[subset]
        if axis is not None:
            result = data.apply(func, axis=axis,
                                result_type='expand', **kwargs)
            result.columns = data.columns
        else:
            result = func(data, **kwargs)
            if not isinstance(result, pd.DataFrame):
                raise TypeError(
                    "Function {func!r} must return a DataFrame when "
                    "passed to `Styler.apply` with axis=None"
                    .format(func=func))
            if not (result.index.equals(data.index) and
                    result.columns.equals(data.columns)):
                msg = ('Result of {func!r} must have identical index and '
                       'columns as the input'.format(func=func))
                raise ValueError(msg)

        result_shape = result.shape
        expected_shape = self.data.loc[subset].shape
        if result_shape != expected_shape:
            msg = ("Function {func!r} returned the wrong shape.\n"
                   "Result has shape: {res}\n"
                   "Expected shape:   {expect}".format(func=func,
                                                       res=result.shape,
                                                       expect=expected_shape))
            raise ValueError(msg)
        self._update_ctx(result)
        return self
Пример #3
0
    def bar(self, subset=None, axis=0, color='#d65f5f', width=100):
        """
        Color the background ``color`` proptional to the values in each column.
        Excludes non-numeric data by default.

        .. versionadded:: 0.17.1

        Parameters
        ----------
        subset: IndexSlice, default None
            a valid slice for ``data`` to limit the style application to
        axis: int
        color: str
        width: float
            A number between 0 or 100. The largest value will cover ``width``
            percent of the cell's width

        Returns
        -------
        self : Styler
        """
        subset = _maybe_numeric_slice(self.data, subset)
        subset = _non_reducing_slice(subset)
        self.apply(self._bar, subset=subset, axis=axis, color=color,
                   width=width)
        return self
Пример #4
0
 def test_list_slice(self):
     # like dataframe getitem
     slices = [['A'], Series(['A']), np.array(['A'])]
     df = DataFrame({'A': [1, 2], 'B': [3, 4]}, index=['A', 'B'])
     expected = pd.IndexSlice[:, ['A']]
     for subset in slices:
         result = _non_reducing_slice(subset)
         tm.assert_frame_equal(df.loc[result], df.loc[expected])
Пример #5
0
 def _applymap(self, func, subset=None, **kwargs):
     func = partial(func, **kwargs)  # applymap doesn't take kwargs?
     if subset is None:
         subset = pd.IndexSlice[:]
     subset = _non_reducing_slice(subset)
     result = self.data.loc[subset].applymap(func)
     self._update_ctx(result)
     return self
Пример #6
0
 def _applymap(self, func, subset=None, **kwargs):
     func = partial(func, **kwargs)  # applymap doesn't take kwargs?
     if subset is None:
         subset = pd.IndexSlice[:]
     subset = _non_reducing_slice(subset)
     result = self.data.loc[subset].applymap(func)
     self._update_ctx(result)
     return self
Пример #7
0
 def test_list_slice(self):
     # like dataframe getitem
     slices = [['A'], Series(['A']), np.array(['A'])]
     df = DataFrame({'A': [1, 2], 'B': [3, 4]}, index=['A', 'B'])
     expected = pd.IndexSlice[:, ['A']]
     for subset in slices:
         result = _non_reducing_slice(subset)
         tm.assert_frame_equal(df.loc[result], df.loc[expected])
Пример #8
0
    def background_gradient(self,
                            cmap='PuBu',
                            low=0,
                            high=0,
                            axis=0,
                            subset=None,
                            text_color_threshold=0.408):
        """
        Color the background in a gradient according to
        the data in each column (optionally row).

        Requires matplotlib.

        Parameters
        ----------
        cmap : str or colormap
            matplotlib colormap
        low, high : float
            compress the range by these values.
        axis : {0 or 'index', 1 or 'columns', None}, default 0
            apply to each column (``axis=0`` or ``'index'``), to each row
            (``axis=1`` or ``'columns'``), or to the entire DataFrame at once
            with ``axis=None``.
        subset : IndexSlice
            a valid slice for ``data`` to limit the style application to.
        text_color_threshold : float or int
            luminance threshold for determining text color. Facilitates text
            visibility across varying background colors. From 0 to 1.
            0 = all text is dark colored, 1 = all text is light colored.

            .. versionadded:: 0.24.0

        Returns
        -------
        self : Styler

        Raises
        ------
        ValueError
            If ``text_color_threshold`` is not a value from 0 to 1.

        Notes
        -----
        Set ``text_color_threshold`` or tune ``low`` and ``high`` to keep the
        text legible by not using the entire range of the color map. The range
        of the data is extended by ``low * (x.max() - x.min())`` and ``high *
        (x.max() - x.min())`` before normalizing.
        """
        subset = _maybe_numeric_slice(self.data, subset)
        subset = _non_reducing_slice(subset)
        self.apply(self._background_gradient,
                   cmap=cmap,
                   subset=subset,
                   axis=axis,
                   low=low,
                   high=high,
                   text_color_threshold=text_color_threshold)
        return self
Пример #9
0
 def _apply_formatters(self):
     """Apply all added formatting."""
     for subset, function in self.formatters:
         if subset is None:
             subset = self.data.index
         else:
             subset = _non_reducing_slice(subset)
         self.data.loc[subset] = self.data.loc[subset].applymap(function)
     return self
Пример #10
0
 def _apply_formatters(self):
     """Apply all added formatting."""
     for subset, function in self.formatters:
         if subset is None:
             subset = self.data.index
         else:
             subset = _non_reducing_slice(subset)
         self.data.loc[subset] = self.data.loc[subset].applymap(function)
     return self
Пример #11
0
 def _apply(self, func, axis=0, subset=None, **kwargs):
     subset = slice(None) if subset is None else subset
     subset = _non_reducing_slice(subset)
     if axis is not None:
         result = self.data.loc[subset].apply(func, axis=axis, **kwargs)
     else:
         # like tee
         result = func(self.data.loc[subset], **kwargs)
     self._update_ctx(result)
     return self
Пример #12
0
 def _apply(self, func, axis=0, subset=None, **kwargs):
     subset = slice(None) if subset is None else subset
     subset = _non_reducing_slice(subset)
     if axis is not None:
         result = self.data.loc[subset].apply(func, axis=axis, **kwargs)
     else:
         # like tee
         result = func(self.data.loc[subset], **kwargs)
     self._update_ctx(result)
     return self
Пример #13
0
 def _highlight_handler(self,
                        subset=None,
                        color='yellow',
                        axis=None,
                        max_=True):
     subset = _non_reducing_slice(_maybe_numeric_slice(self.data, subset))
     self.apply(self._highlight_extrema,
                color=color,
                axis=axis,
                subset=subset,
                max_=max_)
     return self
Пример #14
0
    def background_gradient(self, cmap='PuBu', low=0, high=0, axis=0,
                            subset=None, text_color_threshold=0.408):
        """
        Color the background in a gradient according to
        the data in each column (optionally row).

        Requires matplotlib.

        Parameters
        ----------
        cmap : str or colormap
            matplotlib colormap
        low, high : float
            compress the range by these values.
        axis : {0 or 'index', 1 or 'columns', None}, default 0
            apply to each column (``axis=0`` or ``'index'``), to each row
            (``axis=1`` or ``'columns'``), or to the entire DataFrame at once
            with ``axis=None``.
        subset : IndexSlice
            a valid slice for ``data`` to limit the style application to.
        text_color_threshold : float or int
            luminance threshold for determining text color. Facilitates text
            visibility across varying background colors. From 0 to 1.
            0 = all text is dark colored, 1 = all text is light colored.

            .. versionadded:: 0.24.0

        Returns
        -------
        self : Styler

        Raises
        ------
        ValueError
            If ``text_color_threshold`` is not a value from 0 to 1.

        Notes
        -----
        Set ``text_color_threshold`` or tune ``low`` and ``high`` to keep the
        text legible by not using the entire range of the color map. The range
        of the data is extended by ``low * (x.max() - x.min())`` and ``high *
        (x.max() - x.min())`` before normalizing.
        """
        subset = _maybe_numeric_slice(self.data, subset)
        subset = _non_reducing_slice(subset)
        self.apply(self._background_gradient, cmap=cmap, subset=subset,
                   axis=axis, low=low, high=high,
                   text_color_threshold=text_color_threshold)
        return self
Пример #15
0
    def test_non_reducing_slice_on_multiindex(self):
        # GH 19861
        dic = {
            ("a", "d"): [1, 4],
            ("a", "c"): [2, 3],
            ("b", "c"): [3, 2],
            ("b", "d"): [4, 1],
        }
        df = pd.DataFrame(dic, index=[0, 1])
        idx = pd.IndexSlice
        slice_ = idx[:, idx["b", "d"]]
        tslice_ = _non_reducing_slice(slice_)

        result = df.loc[tslice_]
        expected = pd.DataFrame({("b", "d"): [4, 1]})
        tm.assert_frame_equal(result, expected)
Пример #16
0
    def test_non_reducing_slice_on_multiindex(self):
        # GH 19861
        dic = {
            ('a', 'd'): [1, 4],
            ('a', 'c'): [2, 3],
            ('b', 'c'): [3, 2],
            ('b', 'd'): [4, 1]
        }
        df = pd.DataFrame(dic, index=[0, 1])
        idx = pd.IndexSlice
        slice_ = idx[:, idx['b', 'd']]
        tslice_ = _non_reducing_slice(slice_)

        result = df.loc[tslice_]
        expected = pd.DataFrame({('b', 'd'): [4, 1]})
        tm.assert_frame_equal(result, expected)
Пример #17
0
    def background_gradient(self,
                            cmap='PuBu',
                            low=0,
                            high=0,
                            axis=0,
                            subset=None):
        """
        Color the background in a gradient according to
        the data in each column (optionally row).
        Requires matplotlib.

        .. versionadded:: 0.17.1

        Parameters
        ----------
        cmap: str or colormap
            matplotlib colormap
        low, high: float
            compress the range by these values.
        axis: int or str
            1 or 'columns' for columnwise, 0 or 'index' for rowwise
        subset: IndexSlice
            a valid slice for ``data`` to limit the style application to

        Returns
        -------
        self : Styler

        Notes
        -----
        Tune ``low`` and ``high`` to keep the text legible by
        not using the entire range of the color map. These extend
        the range of the data by ``low * (x.max() - x.min())``
        and ``high * (x.max() - x.min())`` before normalizing.
        """
        subset = _maybe_numeric_slice(self.data, subset)
        subset = _non_reducing_slice(subset)
        self.apply(self._background_gradient,
                   cmap=cmap,
                   subset=subset,
                   axis=axis,
                   low=low,
                   high=high)
        return self
Пример #18
0
    def hide_columns(self, subset):
        """
        Hide columns from rendering.

        .. versionadded:: 0.23.0

        Parameters
        ----------
        subset: IndexSlice
            An argument to ``DataFrame.loc`` that identifies which columns
            are hidden.

        Returns
        -------
        self : Styler
        """
        subset = _non_reducing_slice(subset)
        hidden_df = self.data.loc[subset]
        self.hidden_columns = self.columns.get_indexer_for(hidden_df.columns)
        return self
Пример #19
0
    def test_non_reducing_slice(self):
        df = DataFrame([[0, 1], [2, 3]])

        slices = [
            # pd.IndexSlice[:, :],
            pd.IndexSlice[:, 1],
            pd.IndexSlice[1, :],
            pd.IndexSlice[[1], [1]],
            pd.IndexSlice[1, [1]],
            pd.IndexSlice[[1], 1],
            pd.IndexSlice[1],
            pd.IndexSlice[1, 1],
            slice(None, None, None),
            [0, 1],
            np.array([0, 1]),
            Series([0, 1])
        ]
        for slice_ in slices:
            tslice_ = _non_reducing_slice(slice_)
            assert isinstance(df.loc[tslice_], DataFrame)
Пример #20
0
    def test_non_reducing_slice(self):
        df = pd.DataFrame([[0, 1], [2, 3]])

        slices = [
            # pd.IndexSlice[:, :],
            pd.IndexSlice[:, 1],
            pd.IndexSlice[1, :],
            pd.IndexSlice[[1], [1]],
            pd.IndexSlice[1, [1]],
            pd.IndexSlice[[1], 1],
            pd.IndexSlice[1],
            pd.IndexSlice[1, 1],
            slice(None, None, None),
            [0, 1],
            np.array([0, 1]),
            pd.Series([0, 1])
        ]
        for slice_ in slices:
            tslice_ = _non_reducing_slice(slice_)
            assert isinstance(df.loc[tslice_], DataFrame)
Пример #21
0
    def hide_columns(self, subset):
        """
        Hide columns from rendering.

        .. versionadded:: 0.23.0

        Parameters
        ----------
        subset: IndexSlice
            An argument to ``DataFrame.loc`` that identifies which columns
            are hidden.

        Returns
        -------
        self : Styler
        """
        subset = _non_reducing_slice(subset)
        hidden_df = self.data.loc[subset]
        self.hidden_columns = self.columns.get_indexer_for(hidden_df.columns)
        return self
Пример #22
0
    def _apply(self, func, axis=0, subset=None, **kwargs):
        subset = slice(None) if subset is None else subset
        subset = _non_reducing_slice(subset)
        data = self.data.loc[subset]
        if axis is not None:
            result = data.apply(func, axis=axis, result_type="expand", **kwargs)
            result.columns = data.columns
        else:
            result = func(data, **kwargs)
            if not isinstance(result, pd.DataFrame):
                raise TypeError(
                    "Function {func!r} must return a DataFrame when "
                    "passed to `Styler.apply` with axis=None".format(func=func)
                )
            if not (
                result.index.equals(data.index) and result.columns.equals(data.columns)
            ):
                msg = (
                    "Result of {func!r} must have identical index and "
                    "columns as the input".format(func=func)
                )
                raise ValueError(msg)

        result_shape = result.shape
        expected_shape = self.data.loc[subset].shape
        if result_shape != expected_shape:
            msg = (
                "Function {func!r} returned the wrong shape.\n"
                "Result has shape: {res}\n"
                "Expected shape:   {expect}".format(
                    func=func, res=result.shape, expect=expected_shape
                )
            )
            raise ValueError(msg)
        self._update_ctx(result)
        return self
Пример #23
0
    def background_gradient(
        self,
        cmap="PuBu",
        low=0,
        high=0,
        axis=0,
        subset=None,
        text_color_threshold=0.408,
        vmin: Optional[float] = None,
        vmax: Optional[float] = None,
    ):
        """
        Color the background in a gradient style.

        The background font is determined according
        to the data in each column (optionally row). Requires matplotlib.

        Parameters
        ----------
        cmap : str or colormap
            Matplotlib colormap.
        low : float
            Compress the range by the low.
        high : float
            Compress the range by the high.
        axis : {0 or 'index', 1 or 'columns', None}, default 0
            Apply to each column (``axis=0`` or ``'index'``), to each row
            (``axis=1`` or ``'columns'``), or to the entire DataFrame at once
            with ``axis=None``.
        subset : IndexSlice
            A valid slice for ``data`` to limit the style application to.
        text_color_threshold : float or int
            Luminance threshold for determining text font. Facilitates text
            visibility across varying background colors. From 0 to 1.
            0 = all text is dark colored, 1 = all text is light colored.

            .. versionadded:: 0.24.0

        vmin : float, optional
            Minimum data value that corresponds to colormap minimum value.
            When None (default): the minimum value of the data will be used.

            .. versionadded:: 1.0.0

        vmax : float, optional
            Maximum data value that corresponds to colormap maximum value.
            When None (default): the maximum value of the data will be used.

            .. versionadded:: 1.0.0

        Returns
        -------
        self : Styler

        Raises
        ------
        ValueError
            If ``text_color_threshold`` is not a value from 0 to 1.

        Notes
        -----
        Set ``text_color_threshold`` or tune ``low`` and ``high`` to keep the
        text legible by not using the entire range of the font map. The range
        of the data is extended by ``low * (x.max() - x.min())`` and ``high *
        (x.max() - x.min())`` before normalizing.
        """
        subset = _maybe_numeric_slice(self.data, subset)
        subset = _non_reducing_slice(subset)
        self.apply(
            self._background_gradient,
            cmap=cmap,
            subset=subset,
            axis=axis,
            low=low,
            high=high,
            text_color_threshold=text_color_threshold,
            vmin=vmin,
            vmax=vmax,
        )
        return self
Пример #24
0
    def test_non_reducing_slice(self, slc):
        df = DataFrame([[0, 1], [2, 3]])

        tslice_ = _non_reducing_slice(slc)
        assert isinstance(df.loc[tslice_], DataFrame)
Пример #25
0
    def format(self, formatter, subset=None):
        """
        Format the text display value of cells.

        .. versionadded:: 0.18.0

        Parameters
        ----------
        formatter: str, callable, or dict
        subset: IndexSlice
            An argument to ``DataFrame.loc`` that restricts which elements
            ``formatter`` is applied to.

        Returns
        -------
        self : Styler

        Notes
        -----

        ``formatter`` is either an ``a`` or a dict ``{column name: a}`` where
        ``a`` is one of

        - str: this will be wrapped in: ``a.format(x)``
        - callable: called with the value of an individual cell

        The default display value for numeric values is the "general" (``g``)
        format with ``pd.options.display.precision`` precision.

        Examples
        --------

        >>> df = pd.DataFrame(np.random.randn(4, 2), columns=['a', 'b'])
        >>> df.style.format("{:.2%}")
        >>> df['c'] = ['a', 'b', 'c', 'd']
        >>> df.style.format({'c': str.upper})
        """
        if subset is None:
            row_locs = range(len(self.data))
            col_locs = range(len(self.data.columns))
        else:
            subset = _non_reducing_slice(subset)
            if len(subset) == 1:
                subset = subset, self.data.columns

            sub_df = self.data.loc[subset]
            row_locs = self.data.index.get_indexer_for(sub_df.index)
            col_locs = self.data.columns.get_indexer_for(sub_df.columns)

        if isinstance(formatter, MutableMapping):
            for col, col_formatter in formatter.items():
                # formatter must be callable, so '{}' are converted to lambdas
                col_formatter = _maybe_wrap_formatter(col_formatter)
                col_num = self.data.columns.get_indexer_for([col])[0]

                for row_num in row_locs:
                    self._display_funcs[(row_num, col_num)] = col_formatter
        else:
            # single scalar to format all cells with
            locs = product(*(row_locs, col_locs))
            for i, j in locs:
                formatter = _maybe_wrap_formatter(formatter)
                self._display_funcs[(i, j)] = formatter
        return self
Пример #26
0
 def _highlight_handler(self, subset=None, color='yellow', axis=None,
                        max_=True):
     subset = _non_reducing_slice(_maybe_numeric_slice(self.data, subset))
     self.apply(self._highlight_extrema, color=color, axis=axis,
                subset=subset, max_=max_)
     return self
Пример #27
0
    def bar(self, subset=None, axis=0, color='#d65f5f', width=100,
            align='left'):
        """
        Color the background ``color`` proportional to the values in each
        column.
        Excludes non-numeric data by default.

        Parameters
        ----------
        subset: IndexSlice, default None
            a valid slice for ``data`` to limit the style application to
        axis: int
        color: str or 2-tuple/list
            If a str is passed, the color is the same for both
            negative and positive numbers. If 2-tuple/list is used, the
            first element is the color_negative and the second is the
            color_positive (eg: ['#d65f5f', '#5fba7d'])
        width: float
            A number between 0 or 100. The largest value will cover ``width``
            percent of the cell's width
        align : {'left', 'zero',' mid'}, default 'left'
            - 'left' : the min value starts at the left of the cell
            - 'zero' : a value of zero is located at the center of the cell
            - 'mid' : the center of the cell is at (max-min)/2, or
              if values are all negative (positive) the zero is aligned
              at the right (left) of the cell

              .. versionadded:: 0.20.0

        Returns
        -------
        self : Styler
        """
        subset = _maybe_numeric_slice(self.data, subset)
        subset = _non_reducing_slice(subset)

        base = 'width: 10em; height: 80%;'

        if not(is_list_like(color)):
            color = [color, color]
        elif len(color) == 1:
            color = [color[0], color[0]]
        elif len(color) > 2:
            msg = ("Must pass `color` as string or a list-like"
                   " of length 2: [`color_negative`, `color_positive`]\n"
                   "(eg: color=['#d65f5f', '#5fba7d'])")
            raise ValueError(msg)

        if align == 'left':
            self.apply(self._bar_left, subset=subset, axis=axis, color=color,
                       width=width, base=base)
        elif align == 'zero':
            self.apply(self._bar_center_zero, subset=subset, axis=axis,
                       color=color, width=width, base=base)
        elif align == 'mid':
            self.apply(self._bar_center_mid, subset=subset, axis=axis,
                       color=color, width=width, base=base)
        else:
            msg = ("`align` must be one of {'left', 'zero',' mid'}")
            raise ValueError(msg)

        return self
Пример #28
0
    def bar(self,
            subset=None,
            axis=0,
            color='#d65f5f',
            width=100,
            align='left',
            vmin=None,
            vmax=None):
        """
        Draw bar chart in the cell backgrounds.

        Parameters
        ----------
        subset : IndexSlice, optional
            A valid slice for `data` to limit the style application to.
        axis : int, str or None, default 0
            Apply to each column (`axis=0` or `'index'`)
            or to each row (`axis=1` or `'columns'`) or
            to the entire DataFrame at once with `axis=None`.
        color : str or 2-tuple/list
            If a str is passed, the color is the same for both
            negative and positive numbers. If 2-tuple/list is used, the
            first element is the color_negative and the second is the
            color_positive (eg: ['#d65f5f', '#5fba7d']).
        width : float, default 100
            A number between 0 or 100. The largest value will cover `width`
            percent of the cell's width.
        align : {'left', 'zero',' mid'}, default 'left'
            How to align the bars with the cells.
            - 'left' : the min value starts at the left of the cell.
            - 'zero' : a value of zero is located at the center of the cell.
            - 'mid' : the center of the cell is at (max-min)/2, or
              if values are all negative (positive) the zero is aligned
              at the right (left) of the cell.

              .. versionadded:: 0.20.0

        vmin : float, optional
            Minimum bar value, defining the left hand limit
            of the bar drawing range, lower values are clipped to `vmin`.
            When None (default): the minimum value of the data will be used.

            .. versionadded:: 0.24.0

        vmax : float, optional
            Maximum bar value, defining the right hand limit
            of the bar drawing range, higher values are clipped to `vmax`.
            When None (default): the maximum value of the data will be used.

            .. versionadded:: 0.24.0


        Returns
        -------
        self : Styler
        """
        if align not in ('left', 'zero', 'mid'):
            raise ValueError("`align` must be one of {'left', 'zero',' mid'}")

        if not (is_list_like(color)):
            color = [color, color]
        elif len(color) == 1:
            color = [color[0], color[0]]
        elif len(color) > 2:
            raise ValueError("`color` must be string or a list-like"
                             " of length 2: [`color_neg`, `color_pos`]"
                             " (eg: color=['#d65f5f', '#5fba7d'])")

        subset = _maybe_numeric_slice(self.data, subset)
        subset = _non_reducing_slice(subset)
        self.apply(self._bar,
                   subset=subset,
                   axis=axis,
                   align=align,
                   colors=color,
                   width=width,
                   vmin=vmin,
                   vmax=vmax)

        return self
Пример #29
0
    def bar(self,
            subset=None,
            axis=0,
            color='#d65f5f',
            width=100,
            align='left'):
        """
        Color the background ``color`` proptional to the values in each column.
        Excludes non-numeric data by default.

        .. versionadded:: 0.17.1

        Parameters
        ----------
        subset: IndexSlice, default None
            a valid slice for ``data`` to limit the style application to
        axis: int
        color: str or 2-tuple/list
            If a str is passed, the color is the same for both
            negative and positive numbers. If 2-tuple/list is used, the
            first element is the color_negative and the second is the
            color_positive (eg: ['#d65f5f', '#5fba7d'])
        width: float
            A number between 0 or 100. The largest value will cover ``width``
            percent of the cell's width
        align : {'left', 'zero',' mid'}, default 'left'
            - 'left' : the min value starts at the left of the cell
            - 'zero' : a value of zero is located at the center of the cell
            - 'mid' : the center of the cell is at (max-min)/2, or
              if values are all negative (positive) the zero is aligned
              at the right (left) of the cell

              .. versionadded:: 0.20.0

        Returns
        -------
        self : Styler
        """
        subset = _maybe_numeric_slice(self.data, subset)
        subset = _non_reducing_slice(subset)

        base = 'width: 10em; height: 80%;'

        if not (is_list_like(color)):
            color = [color, color]
        elif len(color) == 1:
            color = [color[0], color[0]]
        elif len(color) > 2:
            msg = ("Must pass `color` as string or a list-like"
                   " of length 2: [`color_negative`, `color_positive`]\n"
                   "(eg: color=['#d65f5f', '#5fba7d'])")
            raise ValueError(msg)

        if align == 'left':
            self.apply(self._bar_left,
                       subset=subset,
                       axis=axis,
                       color=color,
                       width=width,
                       base=base)
        elif align == 'zero':
            self.apply(self._bar_center_zero,
                       subset=subset,
                       axis=axis,
                       color=color,
                       width=width,
                       base=base)
        elif align == 'mid':
            self.apply(self._bar_center_mid,
                       subset=subset,
                       axis=axis,
                       color=color,
                       width=width,
                       base=base)
        else:
            msg = ("`align` must be one of {'left', 'zero',' mid'}")
            raise ValueError(msg)

        return self
Пример #30
0
    def bar(self, subset=None, axis=0, color='#d65f5f', width=100,
            align='left', vmin=None, vmax=None):
        """
        Draw bar chart in the cell backgrounds.

        Parameters
        ----------
        subset : IndexSlice, optional
            A valid slice for `data` to limit the style application to.
        axis : int, str or None, default 0
            Apply to each column (`axis=0` or `'index'`)
            or to each row (`axis=1` or `'columns'`) or
            to the entire DataFrame at once with `axis=None`.
        color : str or 2-tuple/list
            If a str is passed, the color is the same for both
            negative and positive numbers. If 2-tuple/list is used, the
            first element is the color_negative and the second is the
            color_positive (eg: ['#d65f5f', '#5fba7d']).
        width : float, default 100
            A number between 0 or 100. The largest value will cover `width`
            percent of the cell's width.
        align : {'left', 'zero',' mid'}, default 'left'
            How to align the bars with the cells.

            - 'left' : the min value starts at the left of the cell.
            - 'zero' : a value of zero is located at the center of the cell.
            - 'mid' : the center of the cell is at (max-min)/2, or
              if values are all negative (positive) the zero is aligned
              at the right (left) of the cell.

              .. versionadded:: 0.20.0

        vmin : float, optional
            Minimum bar value, defining the left hand limit
            of the bar drawing range, lower values are clipped to `vmin`.
            When None (default): the minimum value of the data will be used.

            .. versionadded:: 0.24.0

        vmax : float, optional
            Maximum bar value, defining the right hand limit
            of the bar drawing range, higher values are clipped to `vmax`.
            When None (default): the maximum value of the data will be used.

            .. versionadded:: 0.24.0

        Returns
        -------
        self : Styler
        """
        if align not in ('left', 'zero', 'mid'):
            raise ValueError("`align` must be one of {'left', 'zero',' mid'}")

        if not (is_list_like(color)):
            color = [color, color]
        elif len(color) == 1:
            color = [color[0], color[0]]
        elif len(color) > 2:
            raise ValueError("`color` must be string or a list-like"
                             " of length 2: [`color_neg`, `color_pos`]"
                             " (eg: color=['#d65f5f', '#5fba7d'])")

        subset = _maybe_numeric_slice(self.data, subset)
        subset = _non_reducing_slice(subset)
        self.apply(self._bar, subset=subset, axis=axis,
                   align=align, colors=color, width=width,
                   vmin=vmin, vmax=vmax)

        return self
Пример #31
0
    def format(self, formatter, subset=None):
        """
        Format the text display value of cells.

        .. versionadded:: 0.18.0

        Parameters
        ----------
        formatter: str, callable, or dict
        subset: IndexSlice
            An argument to ``DataFrame.loc`` that restricts which elements
            ``formatter`` is applied to.

        Returns
        -------
        self : Styler

        Notes
        -----

        ``formatter`` is either an ``a`` or a dict ``{column name: a}`` where
        ``a`` is one of

        - str: this will be wrapped in: ``a.format(x)``
        - callable: called with the value of an individual cell

        The default display value for numeric values is the "general" (``g``)
        format with ``pd.options.display.precision`` precision.

        Examples
        --------

        >>> df = pd.DataFrame(np.random.randn(4, 2), columns=['a', 'b'])
        >>> df.style.format("{:.2%}")
        >>> df['c'] = ['a', 'b', 'c', 'd']
        >>> df.style.format({'C': str.upper})
        """
        if subset is None:
            row_locs = range(len(self.data))
            col_locs = range(len(self.data.columns))
        else:
            subset = _non_reducing_slice(subset)
            if len(subset) == 1:
                subset = subset, self.data.columns

            sub_df = self.data.loc[subset]
            row_locs = self.data.index.get_indexer_for(sub_df.index)
            col_locs = self.data.columns.get_indexer_for(sub_df.columns)

        if isinstance(formatter, MutableMapping):
            for col, col_formatter in formatter.items():
                # formatter must be callable, so '{}' are converted to lambdas
                col_formatter = _maybe_wrap_formatter(col_formatter)
                col_num = self.data.columns.get_indexer_for([col])[0]

                for row_num in row_locs:
                    self._display_funcs[(row_num, col_num)] = col_formatter
        else:
            # single scalar to format all cells with
            locs = product(*(row_locs, col_locs))
            for i, j in locs:
                formatter = _maybe_wrap_formatter(formatter)
                self._display_funcs[(i, j)] = formatter
        return self