-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
ENH: Added more options for formats.style.bar #14757
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
Conversation
Codecov Report
@@ Coverage Diff @@
## master #14757 +/- ##
==========================================
- Coverage 90.88% 90.86% -0.03%
==========================================
Files 162 162
Lines 50821 50862 +41
==========================================
+ Hits 46190 46215 +25
- Misses 4631 4647 +16
Continue to review full report at Codecov.
|
pandas/formats/style.py
Outdated
" of length 2 [ `color_negative`, `color_positive`] " | ||
"(eg: color=['#d65f5f', '#5fba7d'])\n" | ||
"Only the first two list elements will be used here.") | ||
warnings.warn(msg, UserWarning) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I do raise TypeError(msg)
instead of issuing a warning?
(removing the line saying that only two elements will be used of course...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer ValueError
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, done.
pandas/formats/style.py
Outdated
" of length 2 [ `color_negative`, `color_positive`] " | ||
"(eg: color=['#d65f5f', '#5fba7d'])\n" | ||
"Only the first two list elements will be used here.") | ||
warnings.warn(msg, UserWarning) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer ValueError
pandas/formats/style.py
Outdated
|
||
normed = s * 50 * width / (100 * m) | ||
|
||
base = 'width: 10em; height: 80%;' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pls pass base
from .bar
because these are identical.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
can you rebase / update |
Sorry for the delay, I'm trying to rebase right now (on 9947a99), but I'm getting a few errors When doing just 'import pandas as pd':
When running the 'formats' nosetests:
Is it only me or is the master broken somehow? |
you need to rebuild the extensions
generally you should do this anytime you pull from master (and there is an update) |
That makes sense, thanks! After building everything works like it used to. |
can you rebase / update |
Done. When do you think this will be merged in? |
The CircleCI has tests that fails, but they run fine on my local branch. For example:
|
we switched to take a look here: https://travis-ci.org/pandas-dev/pandas/jobs/206164419 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pls add a whatsnew note (and you have some failing tests)
pandas/formats/style.py
Outdated
def _bar_left(s, color, width, base): | ||
""" | ||
The minimum value is aligned at the left of the cell | ||
.. versionadded:: 0.17.1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you don't need the vesionadded tags (and they are outdated)
pandas/tests/formats/test_style.py
Outdated
@@ -348,6 +348,109 @@ def test_bar_0points(self): | |||
', transparent 0%)']} | |||
self.assertEqual(result, expected) | |||
|
|||
def test_bar_align_zero_pos_and_neg(self): | |||
df = pd.DataFrame({'A': [-10, 0, 20, 90]}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add this issue number as a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean this pull request number? #14757?
@TomAugspurger can you review |
@jmarrec I would also take your above picture and add it to the style docs themselves (choose a nice place for it). |
My failing tests are in python 2.7 only, because I expect Eg: Result in Python 2.7:
expected:
|
ok, so can do 1 of 2 things.
ideally first way is better |
doc/source/html-styling.ipynb
Outdated
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Use `Styler.set_properties` when the style doesn't actually depend on the values." | ||
"New in version 0.19.2 is the ability to customize further the bar chart: You can now have the `df.style.bar` be centered on zero or midpoint value (in addition to the already existing way of having the min value at the left side of the cell), and you can pass a list of `[color_negative, color_positive]`.\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-> 0.20.0
pandas/formats/style.py
Outdated
width: float | ||
A number between 0 or 100. The largest value will cover ``width`` | ||
percent of the cell's width | ||
align : str, default 'left' | ||
.. versionadded:: 0.19.2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-> 0.20.0
also need a blank line before/after the versionadded tag
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice enhancement! Added some comments
doc/source/html-styling.ipynb
Outdated
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Use `Styler.set_properties` when the style doesn't actually depend on the values." | ||
"New in version 0.20.0 is the ability to customize further the bar chart: You can now have the `df.style.bar` be centered on zero or midpoint value (in addition to the already existing way of having the min value at the left side of the cell), and you can pass a list of `[color_negative, color_positive]`.\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The table below is a nice overview. But it is also a bit hard to interpret as a user what is the actual code he/she should use. Can you add first an example with the existing frame? Eg df.style.bar(subset=['B'], align='mid')
. And then give the overview table.
pandas/formats/style.py
Outdated
.. versionadded:: 0.17.1 | ||
|
||
Parameters | ||
---------- | ||
subset: IndexSlice, default None | ||
a valid slice for ``data`` to limit the style application to | ||
axis: int | ||
color: str | ||
color: str (for align='left') or 2-tuple/list (for align='zero', 'mid') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the _bar_left
function also a tuple is accepted, which contradicts with this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for catching that.
pandas/formats/style.py
Outdated
- '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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find the names a bit confusing. As 'zero' is actually more 'centered'? While I first thought 'mid' would give me centered bars, but that depends on the actual values you have.
BTW, 'mid' actually seems a more sensible default. Maybe we should change that? (cc @TomAugspurger)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find the names a bit confusing. As 'zero' is actually more 'centered'?
I think this is only true if you have all positive values. So
pd.DataFrame(np.arange(-2, 5)).style.bar(align='zero')
Makes sense to me since zero is at the middle.
BTW, 'mid' actually seems a more sensible default.
Probably, but I'm not sure it's worth breaking API. Maybe with a deprecation cycle?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jorisvandenbossche: @TomAugspurger is correct, it's really centered on zero. The example I tried to include in the doc and that I pasted in the first post of this PR should highlight that fact, otherwise I should revise it.
I have no idea how you handle deprecation cycles etc, so I'll leave that completely up to you guys.
pandas/formats/style.py
Outdated
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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you do here an "else" clause to raise a ValueError when a not accepted value for align was passed? and also add a test for it.
(with playing a bit, I already was bitten by this by trying to pass 'right' and 'center' to align, and thinking that it was not working :-))
@jorisvandenbossche I haven't forgotten about your comments, it just fell on my back burner. I'll try to get to it asap in the coming days. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really close. I think just adding the test for raising with invalid align
s. Do you have time to update @jmarrec ?
pandas/formats/style.py
Outdated
width: float | ||
A number between 0 or 100. The largest value will cover ``width`` | ||
percent of the cell's width | ||
align : str, default 'left' | ||
.. versionadded:: 0.19.2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you change these to 0.20.0
pandas/formats/style.py
Outdated
def _bar_left(s, color, width, base): | ||
""" | ||
The minimum value is aligned at the left of the cell | ||
.. versionadded:: 0.17.1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.. versionadded:: 0.20.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure you want me to do that? This method was added in 0.17.1, I just modified it to accept a tuple of color.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jreback told me in an earlier review (Feb 28) that I didn't need the versionadded tags for these, so I deleted them all. Which?
pandas/formats/style.py
Outdated
def _bar_center_zero(s, color, width, base): | ||
""" | ||
Creates a bar chart where the zero is centered in the cell | ||
.. versionadded:: 0.19.2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.. versionadded:: 0.20.0
pandas/formats/style.py
Outdated
def _bar_center_mid(s, color, width, base): | ||
""" | ||
Creates a bar chart where the midpoint is centered in the cell | ||
.. versionadded:: 0.19.2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.. versionadded:: 0.20.0
pandas/formats/style.py
Outdated
width: float | ||
A number between 0 or 100. The largest value will cover ``width`` | ||
percent of the cell's width | ||
align : str, default 'left' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the proper format on this line is
align : {'left', 'zero',' mid'}
But the explanations below are great. Keep those too.
pandas/formats/style.py
Outdated
- '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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find the names a bit confusing. As 'zero' is actually more 'centered'?
I think this is only true if you have all positive values. So
pd.DataFrame(np.arange(-2, 5)).style.bar(align='zero')
Makes sense to me since zero is at the middle.
BTW, 'mid' actually seems a more sensible default.
Probably, but I'm not sure it's worth breaking API. Maybe with a deprecation cycle?
@TomAugspurger Really sorry, it had fallen on the back burner. I'll get on it this week, will try for tomorrow, so I can put this to bed. |
Yikes, this looks really messy sorry. For some reason when I rebased on upstream/master today, my branch diverged. I merged origin/style-bar back into my local branch, and pushed... I didn't know it'd clutter this PR that much, and now that I pushed I don't want to rewrite history. Anyways, I think I made all the changes you three requested, except the versionadded tags on each of the |
@jmarrec looks like you pushed all commits, do this
to fix |
@jreback in your example 'origin' means this 'pandas-dev' repo right? I end up with a detached HEAD, I'm afraid of force pushing. Is that expected? |
i'll fix your branch give me about 15 min |
Author: Julien Marrec <[email protected]> Closes pandas-dev#14757 from jmarrec/style-bar and squashes the following commits: dc3cbe8 [Julien Marrec] Added a whatsnew note af6c9bd [Julien Marrec] Added a simple example before the parametric one 80a3ce0 [Julien Marrec] Check for bad align value and raise. Wrote test for it too 5875eb9 [Julien Marrec] Change docstrings for color and align 5a22ee1 [Julien Marrec] Merge commit '673fb8f828952a4907e5659c1fcf83b771db7280' into style-bar 0e74b4d [Julien Marrec] Fix versionadded 1b7ffa2 [Julien Marrec] Added documentation on the new df.style.bar options for align and Colors in the documentation. 46bee6d [Julien Marrec] Change the tests to match new float formats. 01c200c [Julien Marrec] Format flots to avoid issue with py2.7 / py3.5 compta. 7ac2443 [Julien Marrec] Changes according to @sinhrks: Raise ValueError instead of warnings when color isn’t a str or 2-tuple/list. Passing “base” from bar(). e3f714c [Julien Marrec] Added a check on color argument that will issue a warning. Not sure if need to raise TypeError or issue a UserWarning if a list with more than two elements is passed. f12faab [Julien Marrec] Fixed line too long `git diff upstream/master | flake8 --diff now passes` 7c89137 [Julien Marrec] ENH: Added more options for formats.style.bar 673fb8f [Julien Marrec] Fix versionadded 506f3d2 [Julien Marrec] Added documentation on the new df.style.bar options for align and Colors in the documentation. e0563d5 [Julien Marrec] Change the tests to match new float formats. d210938 [Julien Marrec] Format flots to avoid issue with py2.7 / py3.5 compta. b22f639 [Julien Marrec] Changes according to @sinhrks: Raise ValueError instead of warnings when color isn’t a str or 2-tuple/list. Passing “base” from bar(). 3046626 [Julien Marrec] Added a check on color argument that will issue a warning. Not sure if need to raise TypeError or issue a UserWarning if a list with more than two elements is passed. 524a9ab [Julien Marrec] Fixed line too long `git diff upstream/master | flake8 --diff now passes` d1eafbb [Julien Marrec] ENH: Added more options for formats.style.bar
see the comments - iirc needs some more tests |
Well, missing I'm missing something obvious, but I don't see any comments left to address, that's precisely why I'm asking. Like I wrote a month ago, the only "open" things is what @TomAugspurger asked, that is to change the version added tags, but he was reviewing an outdated version, because before that you already told me to delete these version added tags, which I did. |
I think @jorisvandenbossche's comment https://github.com/pandas-dev/pandas/pull/14757/files/b22f6392b3416cdc02138a79efb8f179751c8141#r104129905 is still outstanding. Handling cases like Also can you change all of the |
Was done on April 5, see https://github.com/jmarrec/pandas/blob/style-bar/pandas/formats/style.py#L1034. I did the change you requested (in all the file not just my changes, used a regex...). Now, is everything ok? |
Whoops, looks like some git issues. Let me see if I can rebase for you, one sec. |
If you find how to fix it (Jreback did earlier), if you could please share which commands did the trick, that'd be great thanks |
You can now have the bar be centered on zero or midpoint value (in addition to the already existing way of having the min value at the left side of the cell) Fixed line too long `git diff upstream/master | flake8 --diff now passes` Change the tests to match new float formats. Added documentation on the new df.style.bar options for align and Colors in the documentation. Fix versionadded ENH: Added more options for formats.style.bar You can now have the bar be centered on zero or midpoint value (in addition to the already existing way of having the min value at the left side of the cell) Fixed line too long `git diff upstream/master | flake8 --diff now passes` Change the tests to match new float formats. Added documentation on the new df.style.bar options for align and Colors in the documentation. Fix versionadded Check for bad align value and raise. Wrote test for it too Added a simple example before the parametric one Added a whatsnew note Replaced 'self.assertEqual(left, rigth)' by 'assert left == right' like @TomAugspurger asked rebased
Typically it's just ca9c0d5 should have everything down in a single commit, if you want to give that a skim to make sure I didn't miss anything. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a commit with a small doc correction (indentation and white space). And also aligned the signature with documentation, adding the new keyword at the end, not breaking people who used axis positional
Let's merge this PR, but, I find we should think about changing the default value. If we all think 'mid' is the more sensible default, IMO we should just change it. |
@TomAugspurger : For subsequent PR's, could you check to make sure that old |
My apologies. I thought I caught all those in the rebase :/ I'll submit a fix now. |
No worries. I'm putting up a PR to remove vestigial statements like these, so that won't be necessary. I just wanted to alert you about it for subsequent PR's. |
* ENH: Added more options for formats.style.bar You can now have the bar be centered on zero or midpoint value (in addition to the already existing way of having the min value at the left side of the cell) Fixed line too long `git diff upstream/master | flake8 --diff now passes` Change the tests to match new float formats. Added documentation on the new df.style.bar options for align and Colors in the documentation. Fix versionadded ENH: Added more options for formats.style.bar You can now have the bar be centered on zero or midpoint value (in addition to the already existing way of having the min value at the left side of the cell) Fixed line too long `git diff upstream/master | flake8 --diff now passes` Change the tests to match new float formats. Added documentation on the new df.style.bar options for align and Colors in the documentation. Fix versionadded Check for bad align value and raise. Wrote test for it too Added a simple example before the parametric one Added a whatsnew note Replaced 'self.assertEqual(left, rigth)' by 'assert left == right' like @TomAugspurger asked rebased * small doc fixes
This is breaking the previous behavior of Pandas when using Example of bar coloring breaking in 0.20:
Shows this in previous verisons: Everything is blue in 0.20+ |
git diff upstream/master | flake8 --diff
You can now have the df.style.bar be centered on zero or midpoint value (in
addition to the already existing way of having the min value at the left side of the cell)
Documentation:
I have produced the following example that I think does a pretty good job of explaining the new capabilities
What do you think?