Skip to content

QST: What is the use of cell_context in the Styler? #35998

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 of 2 tasks
grantstead opened this issue Aug 30, 2020 · 7 comments
Closed
1 of 2 tasks

QST: What is the use of cell_context in the Styler? #35998

grantstead opened this issue Aug 30, 2020 · 7 comments
Labels
Styler conditional formatting using DataFrame.style Usage Question

Comments

@grantstead
Copy link

  • 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 (

cell_context = dict()
) 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

@grantstead grantstead added Needs Triage Issue that has not been reviewed by a pandas team member Usage Question labels Aug 30, 2020
@jbrockmendel jbrockmendel added Styler conditional formatting using DataFrame.style and removed Needs Triage Issue that has not been reviewed by a pandas team member labels Sep 1, 2020
@attack68
Copy link
Contributor

attack68 commented Sep 2, 2020

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!!

@grantstead
Copy link
Author

grantstead commented Sep 3, 2020

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

@attack68
Copy link
Contributor

attack68 commented Sep 3, 2020

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.

@attack68
Copy link
Contributor

attack68 commented Sep 6, 2020

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

@grantstead
Copy link
Author

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

@attack68
Copy link
Contributor

This has been closed by #36159

@mroeschke
Copy link
Member

Thanks @attack68

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Styler conditional formatting using DataFrame.style Usage Question
Projects
None yet
Development

No branches or pull requests

4 participants