ENH: Style blocks
State: closed

    ENH: Add blocks to Styler template

    This will make subclassing the Styler and extending
    the templates easier.

    REF: Move template to its own file

    Use Environment and PackageLoader to load it

Labels:
name: Output-Formatting
description: __repr__ of pandas objects, to_string
name: IO HTML
description: read_html, to_html, Styler.apply, Styler.applymap

Comments:
Here's a gist with the new docs: http://nbviewer.jupyter.org/gist/anonymous/db1b30a4ba4085bda612944c6ba9b64e#Extensibility

I think right now the template isn't included in the package, need to update `setup.py`. Will do later but have to run for now.
From the notebook

>For convenience, we provide the styler_factory function that does the same as the custom subclass.

`styler_factory` -> `from_custom_template`


Thanks.

About the API:  I don't really want it at the top level but it has to be public if people are subclassing. I just wasn't sure how we resolved the public API and submodules issue :)

> On Apr 9, 2017, at 8:03 AM, chris-b1 <notifications@github.com> wrote:
> 
> From the notebook
> 
> For convenience, we provide the styler_factory function that does the same as the custom subclass.
> 
> styler_factory -> from_custom_template
> 
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub, or mute the thread.
> 

> I do think it needs to be importable somewhere 'public', not sure if top level is the right spot, could argue either way. Do we need a pandas.api.io?

yes I think this is the way to go. 
> Do we need a pandas.api.io?

We already have a publicly accessible `pandas.io`, so if we want it in `io`, I would put it there.
> We already have a publicly accessible pandas.io, so if we want it in io, I would put it there.

Yeah, having both would be confusing. Are people ok with `pandas.io.Styler`? (or would it be `pandas.io.api.Styler`?)

# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=h1) Report
> Merging [#15954](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/c4d71cea79bee1e9ed3b6ca97f3a5c1b8ad9369f?src=pr&el=desc) will **increase** coverage by `<.01%`.
> The diff coverage is `100%`.

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

```diff
@@            Coverage Diff             @@
##           master   #15954      +/-   ##
==========================================
+ Coverage      91%      91%   +<.01%     
==========================================
  Files         145      145              
  Lines       49581    49586       +5     
==========================================
+ Hits        45123    45128       +5     
  Misses       4458     4458
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `88.77% <100%> (ø)` | :arrow_up: |
| #single | `40.57% <53.84%> (-0.01%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/formats/style.py](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=tree#diff-cGFuZGFzL2Zvcm1hdHMvc3R5bGUucHk=) | `96.28% <100%> (+0.1%)` | :arrow_up: |
| [pandas/\_\_init\_\_.py](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=tree#diff-cGFuZGFzL19faW5pdF9fLnB5) | `92.85% <100%> (+0.17%)` | :arrow_up: |
| [pandas/core/algorithms.py](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvYWxnb3JpdGhtcy5weQ==) | `94.53% <0%> (-0.05%)` | :arrow_down: |
| [pandas/core/base.py](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvYmFzZS5weQ==) | `95.51% <0%> (ø)` | :arrow_up: |
| [pandas/core/series.py](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvc2VyaWVzLnB5) | `94.89% <0%> (ø)` | :arrow_up: |
| [pandas/indexes/base.py](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=tree#diff-cGFuZGFzL2luZGV4ZXMvYmFzZS5weQ==) | `96.09% <0%> (ø)` | :arrow_up: |
| [pandas/core/categorical.py](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvY2F0ZWdvcmljYWwucHk=) | `95.85% <0%> (ø)` | :arrow_up: |
| [pandas/tseries/index.py](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=tree#diff-cGFuZGFzL3RzZXJpZXMvaW5kZXgucHk=) | `95.43% <0%> (ø)` | :arrow_up: |
| [pandas/util/testing.py](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=tree#diff-cGFuZGFzL3V0aWwvdGVzdGluZy5weQ==) | `81.13% <0%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/15954?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/15954?src=pr&el=footer). Last update [c4d71ce...5bff74f](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=h1) Report
> Merging [#15954](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/614a48e3e6640b5694fd1ed6cbe56a760e89dd50?src=pr&el=desc) will **decrease** coverage by `0.02%`.
> The diff coverage is `50%`.

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

```diff
@@            Coverage Diff             @@
##           master   #15954      +/-   ##
==========================================
- Coverage   91.02%      91%   -0.03%     
==========================================
  Files         145      146       +1     
  Lines       50391    50416      +25     
==========================================
+ Hits        45870    45880      +10     
- Misses       4521     4536      +15
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `88.8% <50%> (-0.03%)` | :arrow_down: |
| #single | `40.32% <28.57%> (-0.02%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/util/importing.py](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=tree#diff-cGFuZGFzL3V0aWwvaW1wb3J0aW5nLnB5) | `0% <0%> (ø)` | |
| [pandas/formats/style.py](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=tree#diff-cGFuZGFzL2Zvcm1hdHMvc3R5bGUucHk=) | `96.28% <100%> (+0.1%)` | :arrow_up: |
| [pandas/io/api.py](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=tree#diff-cGFuZGFzL2lvL2FwaS5weQ==) | `71.42% <20%> (-28.58%)` | :arrow_down: |
| [pandas/core/common.py](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvY29tbW9uLnB5) | `90.68% <0%> (-0.35%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/15954?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/15954?src=pr&el=footer). Last update [614a48e...c6765f3](https://codecov.io/gh/pandas-dev/pandas/pull/15954?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
jinja2 being optional makes putting this in the namespace a bit strange. Happy to hear suggestions on ways to make that / the API tests better :/
As I said above, we already have public things in `pandas.io`, so I don't really see the point of creating a new `pandas.api.io` ?
Ah, what @chris-b1  said :-)
Currently, our API documentation lists it as `pandas.formats.style.Styler` (so when moving, we should deprecate that). So one possibility would be to move the full formats module into `pandas.io` ? Or move to core and only expose the public ones in `pandas.io` (or in `pandas.io.formats` / `pandas.io.style`).

If we decide to move the `formats` module (which would certainly be for another PR), we could also just leave `Styler` where it is for now in this PR, and do the move / change of locations / deprecation in the other PR.
OK, should be good now. Sorry about that.
I am shortly going to move a bunch of things around. But ``pandas.io`` is going to stay (``pandas.formats`` will move).
you *could* move ``.style`` under ``.io`` if you want.
> You have an example in the notebook I suppose. Is it possible to put a link here to such an example? Not sure how it works with nbsphinx included files to put links to specific sections

@jorisvandenbossche yeah that worked! It's just

    :ref`text <notebook.ipynb#section-title>`
@TomAugspurger lgtm. merge when ready.
FYI: http://pandas-docs.github.io/pandas-docs-travis/style.html#Fun-stuff is raising in built dev docs.
``ipywidgets`` I think is needed in doc-build.
> ipywidgets I think is needed in doc-build.

Did you see that in one of the travis logs? https://travis-ci.org/pandas-dev/pandas/jobs/222148043 seems to be ok.
@TomAugspurger see the link above, its in the built docs.
Whoops, looked right past that. Yeah I guess they've split that out now.

I can do now, or in a separate PR since all the checks already passed here.
either way 
or can add and push then merge 
good to go?
thanks @TomAugspurger 
Opened a follow-up issue for the remaining issues that were being discussed: https://github.com/pandas-dev/pandas/issues/16009
http://pandas-docs.github.io/pandas-docs-travis/style.html

maybe internally should just catch warnings?
```
/home/travis/miniconda3/envs/pandas/lib/python3.5/site-packages/matplotlib/colors.py:581: RuntimeWarning: invalid value encountered in less
  cbook._putmask(xa, xa < 0.0, -1)
```