Pandas: QST: What is the use of cell_context in the Styler?

Created on 31 Aug 2020  路  7Comments  路  Source: pandas-dev/pandas

  • [X] I have searched the [pandas] tag on StackOverflow for similar questions.

  • [ ] I have asked my usage related question on StackOverflow.


Question about pandas

Note: If you'd still like to submit a question, please read this guide detailing how to provide the necessary information for us to reproduce your question.

In pandas/io/formats/style.py (https://github.com/pandas-dev/pandas/blob/3ef3617c2e784b98db83ab437e7607459f68a1cc/pandas/io/formats/style.py#L265) the cell_context dict is created (empty). It is referenced twice (on line 318 and 382), where values are accessed, if they are present. The dict is however never updated.

What is the use of this variable? It seems to me to be quite useless as there is no way to set it's content. Is it purely there for future use? I use v0.23 where it was already like this, so I expected it to have changed in master, but this doesn't seem to be the case. Is there some way of setting it that I'm not aware of?

There are a few stack overflow questions (https://stackoverflow.com/questions/55236631/add-custom-css-class-to-column-or-cell-of-a-dataframe and https://stackoverflow.com/questions/62075616/add-style-class-to-pandas-dataframe-html) )by others,s not me) that ask how to set the class of a cell. These seem related to how this dict's values could be set. To "implement" support for classes, I simply overwrote the render method to call _translate and then to adjust the d["body']'s content where I added to the cell's class value. If cell_context could be set, then there would be no need to do this overriding after the fact (and actually benefit from the looking that is performed against cell_context)... (I would like to respond to these two questions, possibly with my monkey-patching, but preferably with what happens in _translate()).

Thanks,
Grant

Styler Usage Question

All 7 comments

I actually observed the same in my recent Styler pull requests: #35607, #35643

It seems that this was present in the original commit by @TomAugspurger 702d63e in 2015. I can only speculate this was either for future dev, or it was replaced in the code by a new design approach and never removed before commit.

I think adding classes is a good idea and is what I might consider after getting these two pull requests through... Do submit your own though if its already developed!!

Thanks @attack68 . I unfortunately don't have a fix to contribute here. I worked around this by writing a render method, which takes the styler. This is not great, but I can't easily change the pandas source code in my env. My render method looks like this:

`
def render(self):
""" Custom renderer to add to the class indicating cells that are late on the burndown.

        Params:
            self (Styler): the styler that is being rendered.
        Returns:
            str: The rendered HTML content.
    """
    self._compute()
    d = self._translate()
    # Add classes from another dataframe with the same shape (via classes)
    levels = len(self.index.levels)
    for cell in classes_pivot.itertuples():
        if cell.value:
            d['body'][cell.row][cell.column + levels]['class'] += cell.value
    trimmed = [x for x in d['cellstyle']] # if any(any(y) for y in x['props'])]
    d['cellstyle'] = trimmed
    return self.template.render(**d)

`

The classes_pivot DataFrame _happens to be_ the same shape (and indexes) as the DataFrame being rendered by the Styler. It contains the str to use as the class(es) to add, or a blank string. I simply calculated the various classes I wanted to add beforehand, and then upon render there is little effort spent on calculating it. This was much faster than trying to do it via styles.

Not sure this can act as inspiration as it is a pretty poor implementation and doesn't access/address the cell_context variable, which to me seems to be a better option in the long run.

Cheers,
Grant

For what its worth, my pull request for tooltips current does exactly the same thing as what you are doing, and I also express that it could be optimised (but for small tables not currently worth the effort)

def _render_tooltips(self, d):
        """
        Mutate the render dictionary to allow for tooltips:
        - Add `<span>` HTML element to each data cells `display_value`. Ignores headers.
        - Add table level CSS styles to control pseudo classes.
        Parameters
        ----------
        d : dict
            The dictionary prior to rendering
        """
        if self.tooltip_styles:
            for row in d["body"]:
                for item in row:
                    if item["type"] == "td":
                        item["display_value"] = (
                            str(item["display_value"])
                            + f'<span class="{self.tooltip_class}"></span>'
                        )
            d["table_styles"].extend(self.tooltip_class_styles)
            d["table_styles"].extend(self.tooltip_styles)

I'll continue to keep and eye out and see if any other developments are made.

I have published a PR at #36159 which addresses this and uses cell_context.

Looked at the code. Seems great. Thanks for that!

This has been closed by #36159

Thanks @attack68

Was this page helpful?
0 / 5 - 0 ratings