ENH: Added more options for formats.style.bar
State: closed

 - [x]  4 tests added  and passed
 - [x] passes ``git diff upstream/master | flake8 --diff``
 - [x] Update documentation

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

```
import pandas as pd
from IPython.display import HTML

# Case 1: s.min() < 0:
test1 = pd.Series([-100,-60,-30,-20], name='All Negative')
# Case 2: s.max() < 0:
test2 = pd.Series([10,20,50,100], name='All Positive')
# Case 3:
test3 = pd.Series([-10,-5,0,90], name='Both Pos and Neg')

head = """
<table>
    <thead>
        <th>Align</th>
        <th>All Negative</th>
        <th>All Positive</th>
        <th>Both Neg and Pos</th>
    </thead>
    </tbody>

"""

aligns = ['left','zero','mid']
for align in aligns:
    row = "<tr><th>{}</th>".format(align)
    for serie in [test1,test2,test3]:
        s = serie.copy()
        s.name=''
        row += "<td>{}</td>".format(s.to_frame().style.bar(align=align, 
                                                           color=['#d65f5f', '#5fba7d'], 
                                                           width=100).render()) #testn['width']
    row += '</tr>'
    head += row
    
head+= """
</tbody>
</table>"""
        

HTML(head)
```

![screen shot 2016-11-28 at 17 06 21](https://cloud.githubusercontent.com/assets/5479063/20675547/04c4af52-b58d-11e6-9695-48a01c37d522.png)

What do you think?





Labels:
name: Output-Formatting
description: __repr__ of pandas objects, to_string

Comments:
# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/14757?src=pr&el=h1) Report
> Merging [#14757](https://codecov.io/gh/pandas-dev/pandas/pull/14757?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/6d0118e3573bde1e009949eda30d1844fb344789?src=pr&el=desc) will **decrease** coverage by `0.02%`.
> The diff coverage is `92.5%`.

[![Impacted file tree graph](https://codecov.io/gh/pandas-dev/pandas/pull/14757/graphs/tree.svg?width=650&height=150&src=pr&token=eZ4WkYLtcO)](https://codecov.io/gh/pandas-dev/pandas/pull/14757?src=pr&el=tree)

```diff
@@            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
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `88.64% <92.5%> (-0.03%)` | :arrow_down: |
| #single | `40.3% <10%> (-0.03%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/14757?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/io/formats/style.py](https://codecov.io/gh/pandas-dev/pandas/pull/14757?src=pr&el=tree#diff-cGFuZGFzL2lvL2Zvcm1hdHMvc3R5bGUucHk=) | `95.89% <92.5%> (-0.48%)` | :arrow_down: |
| [pandas/plotting/\_converter.py](https://codecov.io/gh/pandas-dev/pandas/pull/14757?src=pr&el=tree#diff-cGFuZGFzL3Bsb3R0aW5nL19jb252ZXJ0ZXIucHk=) | `63.54% <0%> (-1.82%)` | :arrow_down: |
| [pandas/core/common.py](https://codecov.io/gh/pandas-dev/pandas/pull/14757?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvY29tbW9uLnB5) | `90.68% <0%> (-0.35%)` | :arrow_down: |
| [pandas/core/generic.py](https://codecov.io/gh/pandas-dev/pandas/pull/14757?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZ2VuZXJpYy5weQ==) | `91.63% <0%> (ø)` | :arrow_up: |
| [pandas/core/config\_init.py](https://codecov.io/gh/pandas-dev/pandas/pull/14757?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvY29uZmlnX2luaXQucHk=) | `94.52% <0%> (+0.23%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/14757?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/14757?src=pr&el=footer). Last update [6d0118e...c7d41fb](https://codecov.io/gh/pandas-dev/pandas/pull/14757?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

can you rebase / update
cc @TomAugspurger 

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':

> AttributeError: module 'pandas' has no attribute 'compat'

When running the 'formats' nosetests:

> AttributeError: module 'pandas.lib' has no attribute 'is_decimal'


Is it only me or is the master broken somehow?
you need to rebuild the extensions

``python setup.py build_ext --inplace``

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:

```
pandas$ nosetests pandas/tests/formats/test_style.py:TestStyler.test_bar_align_mid_all_pos
.
----------------------------------------------------------------------
Ran 1 test in 0.044s

OK
```

we switched to ``pytest`` recently FYI

take a look here: https://travis-ci.org/pandas-dev/pandas/jobs/206164419 
@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 `80.0%` but I get `80%` instead.

Eg:

Result in Python 2.7:

```
 (3, 0): ['width: 10em',
  ' height: 80%',
  'background: linear-gradient(90deg, transparent 0%, transparent 80%, #d65f5f 80%, #d65f5f 100%, transparent 100%)']}
```

expected:
```

 (3, 0): ['width: 10em',
  ' height: 80%',
  'background: linear-gradient(90deg, transparent 0%, transparent 80.0%, #d65f5f 80.0%, #d65f5f 100%, transparent 100%)']}
```
ok, so can do 1 of 2 things.

- conform both results in py2 and py3 (e.g. you are formatting the string)
or
- use a subtition for that value in the test (with different values for py2 and py3).

ideally first way is better
cc @jorisvandenbossche 
@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.
@TomAugspurger status?
@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 `_bar_xxx` methods since @jreback had told me to delete them and it seems @TomAugspurger reviewed an older version where they were still there but outdated (I have deleted them a while ago). If you want me to add them I guess I can. Otherwise I hope this is ready to go!
@jmarrec looks like you pushed all commits, do this

```
git rebase -i thisbranch origin/master
git push yourorigin thisbranch -f
```

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
@jreback will this make it in (or through #15900, now closed)? 
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 `.bar(align='foo')`. That should raise with something like `ValueError('align' must be one of {'left', 'zero', 'mid'}, got 'foo' instead)`

Also can you change all of the `self.assertEqual(left, right)`s to `assert left == right`?
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
Typically it's just `git fetch upstream`, then `git rebase upstream/master`. This was a bit tricker than usual because it's been sitting out for so long (sorry about that) and we've re-arranged a lot of things now.  This causes conflicts, since two commits touched the same lines so you have to go in and fix them manually with your editor. Then it's `git add <files>` and `git rebase --continue.` until you're fully rebased.

https://github.com/pandas-dev/pandas/pull/14757/commits/ca9c0d546833e25d08f080059e71e89bb153d7a2 *should* have everything down in a single commit, if you want to give that a skim to make sure I didn't miss anything.