Skip to content

Fix undesired UX behavior of DataFrame output in IPython Notebook #10232

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
wants to merge 1 commit into from

Conversation

danieljl
Copy link
Contributor

Closes #10231

@shoyer shoyer added this to the 0.16.2 milestone Jun 3, 2015
@shoyer shoyer added the IO HTML read_html, to_html, Styler.apply, Styler.applymap label Jun 3, 2015
@shoyer
Copy link
Member

shoyer commented Jun 3, 2015

Could you please squash this to a single commit and add this to the release notes for 0.16.2? I think this would go in under "Other API changes": https://github.com/pydata/pandas/blob/master/doc/source/whatsnew/v0.16.2.txt

@jorisvandenbossche @jreback any thoughts on this issue? see also the associated issue #10231

@danieljl danieljl force-pushed the fix-10231 branch 3 times, most recently from 8941b83 to 1aa2c04 Compare June 3, 2015 08:08
@danieljl
Copy link
Contributor Author

danieljl commented Jun 3, 2015

@shoyer I've squashed it into a single commit. Btw, I think this is more appropriate added to release notes under "Other enhancements", isn't it?

@@ -25,6 +25,8 @@ New features
Other enhancements
^^^^^^^^^^^^^^^^^^

- Fix undesired UX behavior of DataFrame output in IPython Notebook. (:issue:`10231`)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might say: "Removed duplicate scroll bars in DataFrame HTML representation in IPython Notebook" (just to be a little more descriptive)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeh, this needs a bit more explanation. Possibly even a screen shot. Its seems trivial, but people complain about UX changes the most!

@shoyer
Copy link
Member

shoyer commented Jun 3, 2015

@danieljl This is a (small) API change, so I would put it under that category. "Other enhancements" is really for fully backwards compatible changes, e.g., adding a new optional keyword argument.

@jorisvandenbossche
Copy link
Member

Personally I don't think it is needed to put it under API changes, as it is not really something that will break people's code, or something for which people have to adjust there code, it is only a visual change. I would keep 'API changes' for things people have to pay attention to if they use that in their code.

@jorisvandenbossche
Copy link
Member

I was only thinking: how does this behave in older versions of IPython? (eg somebody who is still using IPython 2?)

@shoyer
Copy link
Member

shoyer commented Jun 3, 2015

@jorisvandenbossche would you call this a bug fix? It's kind of a strange case -- we had a work around, which was resolved in a later version of IPython.

See the linked issue for screenshots.

@jorisvandenbossche
Copy link
Member

Maybe we can detect the IPython version and dependable on that leave the max-width in or not?

@shoyer hmm, maybe also not a bug fix. I would keep it at an 'enhancement' of the visual output of a dataframe in the notebook. But does not really matter that much I think

@jreback
Copy link
Contributor

jreback commented Jun 3, 2015

I agree with @jorisvandenbossche I would detect ipython version and not make any change for ipython < 3.

Further, I think this needs a separate section in the what's new with a picture. UX changes needs to be announced loudly (even if its is a 'bug' fix).

@jreback
Copy link
Contributor

jreback commented Jun 5, 2015

@danieljl can you update with ipython version detection?

@danieljl
Copy link
Contributor Author

danieljl commented Jun 6, 2015

@jreback Done. However, in IPython 2 horizontal scroll bar is still unscrollable unless the page is refreshed.

@@ -22,6 +22,7 @@
from numpy import nan as NA
import numpy as np
import numpy.ma as ma
import IPython
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not a required dependency, so do this in the actual function. surround with a try/except. if you cannot figure out the version (e.g. ipython is not installed), then use the new style is ok.

@jreback jreback added the Output-Formatting __repr__ of pandas objects, to_string label Jun 7, 2015
try:
import IPython

if IPython.version_info < (3, 0, 0):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IPython.version_info < LooseVersion("3.0.0")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jreback IPython.version_info is a tuple. Did you mean IPython.__version__? Btw, why is this more preferred?

@jreback
Copy link
Contributor

jreback commented Jun 9, 2015

Put this code as a method in HTMLFormatter.

This needs to be changed a bit. Instead of simply having the div_style wrap the self.html(...) method in __repr_html__, here, I would pass a new parameter to to_html, call it notebook (pass notebook=True, with a default value of notebook=False), pass this thru to the HTMLFormatter class (which sets it as an instance variable).

Then just call this code in write_result.

This will put all of the code in the correct place, and make it obvious what is going on.

@danieljl danieljl force-pushed the fix-10231 branch 2 times, most recently from 7e73bec to 3e0c851 Compare June 9, 2015 10:06
@danieljl
Copy link
Contributor Author

danieljl commented Jun 9, 2015

@jreback Should it be like this 3e0c851?

@@ -25,6 +25,8 @@ New features
Other enhancements
^^^^^^^^^^^^^^^^^^

- Removed duplicate scroll bars in DataFrame HTML representation in IPython Notebook. (:issue:`10231`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for notebook >= version 3.0.0

@jorisvandenbossche jorisvandenbossche mentioned this pull request Jun 9, 2015
@jreback
Copy link
Contributor

jreback commented Jun 10, 2015

pls squash this to a single commit

@@ -25,6 +25,8 @@ New features
Other enhancements
^^^^^^^^^^^^^^^^^^

- Removed duplicate scroll bars in DataFrame HTML representation for IPython 3.0.0 or later. (:issue:`10231`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs some addtl explanation w.r.t. max_rows. IOW, I find that using pd.set_setoption('max_rows,None) is now a nice way to use the notebook (for a terminal I have this set to a smaller value, however). maybe mention of same in options.rst

@jreback
Copy link
Contributor

jreback commented Jun 10, 2015

@TomAugspurger
Copy link
Contributor

looks good.

@sinhrks
Copy link
Member

sinhrks commented Jun 10, 2015

lgtm.

@shoyer
Copy link
Member

shoyer commented Jun 10, 2015

Yep, looks pretty good to me.

@jorisvandenbossche
Copy link
Member

Yes, here as well. I quickly tested it, and although I was used to having shorter outputs of dataframes in my notebook workflow (now it show about 30 rows, with this change the full 60 rows of a truncated dataframe repr will be visible, leading to a longer output), I think I will get used to the change.

The only disadvantage is that I find the "toggle output scrolling" feature of IPython (with this, you see around 9 rows) rather ugly (the way too heavy shadow).
And that I did find the 30 rows you see now a better height as the 60 rows (but that has to do with our default options for max_rows, so another discussion)

@danieljl
Copy link
Contributor Author

@jreback Squashed

@shoyer
Copy link
Member

shoyer commented Jun 10, 2015

@jorisvandenbossche agreed, it is a little ugly to have a drop shadow here. But this is still better than double scroll bars.

@jreback
Copy link
Contributor

jreback commented Jun 10, 2015

@danieljl that looks good. can you expand the whatsnew note a bit? approach this from the perspective of someone reading this, and since this is a UX change, we want to be obvious/clear what exactly this is.

@danieljl
Copy link
Contributor Author

@jreback Whatsnew updated :)

@jorisvandenbossche
Copy link
Member

One comment: this adds a new notebook kwarg to DataFrame.to_html, which I don't think is really useful to be exposed to the user?
Isn't it possible to not add it? (eg leave the logic of that in __repr__ instead of in HTMLFormatter)

@danieljl
Copy link
Contributor Author

@jorisvandenbossche Yup, initially I implemented it in _repr_html_. But I refactored it as suggested by @jreback in #10232 (comment).

@jreback
Copy link
Contributor

jreback commented Jun 10, 2015

I guess we could make it _notebook e.g. a private argument. This totally belongs in the HTMLFormatter class (as for example you could then sub-class it and/or use it somewhere else that you are displaying to a notebook)

@jorisvandenbossche
Copy link
Member

OK, agreed. Other option is to call HTMLFormatter (or DataFrameFormatter) directly from __repr__ instead of to_html, like

return fmt.DataFrameFormatter(self, max_rows=max_rows, max_cols=max_cols,
                              show_dimensions=show_dimensions,
                              notebook=True).to_html()

or if you think this is useful in to_html as well (and not only in HTMLFormatter), let's just document it in the docstring (and maybe use a more generic name like div?)

@jreback
Copy link
Contributor

jreback commented Jun 10, 2015

how about then we make this an argument to to_html instead then. (I still would use notebook as it conveys, hey, we want to output this to a particular medium, html, but needs a special wrapper because its in the notebook)

@danieljl
Copy link
Contributor Author

So should the code be refactored again?

@jorisvandenbossche
Copy link
Member

@danieljl I think the latest what @jreback said was to keep it in to_html, but then it should get added to the docstring, that is all

@@ -1387,7 +1387,8 @@ def to_html(self, buf=None, columns=None, col_space=None, colSpace=None,
escape=escape,
max_rows=max_rows,
max_cols=max_cols,
show_dimensions=show_dimensions)
show_dimensions=show_dimensions,
notebook=notebook)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here pass directly to .to_html() (and add in the doc-string). That way this is not relevant to DataFrameFormatter, just to the HTMLFormatter (which is created in the .to_html call)

@danieljl
Copy link
Contributor Author

If everything's okay, I will squash it again.

@jreback
Copy link
Contributor

jreback commented Jun 11, 2015

lgtm. go ahead and squash

@danieljl
Copy link
Contributor Author

Done

@jreback
Copy link
Contributor

jreback commented Jun 11, 2015

merged via 814dbe8

thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
IO HTML read_html, to_html, Styler.apply, Styler.applymap Output-Formatting __repr__ of pandas objects, to_string
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Undesired UX behavior of DataFrame output in IPython Notebook
6 participants