18

I would like to render a pandas dataframe to HTML in the same way as the Jupyter Notebook does it, i.e. with all the bells and wistles like nice looking styling, column highlighting, and column sorting on click.

enter image description here

pandas.to_html outputs just a plain HTML table and requires manual styling etc.

Is the dataframe rendering code used by jupyter available as a standalone module that can be used in any web app?

Also, are the assets such as js/css files decoupled from jupyter so that they can be easily reused?

ccpizza
  • 28,968
  • 18
  • 162
  • 169
  • 1
    This might answer your question: https://stackoverflow.com/questions/36897366/pandas-to-html-using-the-style-options-or-custom-css – Joe B Jan 25 '19 at 20:44
  • In the long run I gave up on the idea of using jupyter styling because I didn't like the verbosity of the generated inline styles, and opted instead for serving the data as JSON into a dynamic [angular material table component](https://material.angular.io/components/table/overview) -- this way you can have server-side paging, proper sorting and apply all sorts of client-side transformations, including OOTB locale-dependent date and number formatting. – ccpizza Jan 26 '19 at 09:46

2 Answers2

6

This works well for me

def getTableHTML(df):
    
    """
    From https://stackoverflow.com/a/49687866/2007153
    
    Get a Jupyter like html of pandas dataframe
    
    """

    styles = [
        #table properties
        dict(selector=" ", 
             props=[("margin","0"),
                    ("font-family",'"Helvetica", "Arial", sans-serif'),
                    ("border-collapse", "collapse"),
                    ("border","none"),
    #                 ("border", "2px solid #ccf")
                       ]),

        #header color - optional
    #     dict(selector="thead", 
    #          props=[("background-color","#cc8484")
    #                ]),

        #background shading
        dict(selector="tbody tr:nth-child(even)",
             props=[("background-color", "#fff")]),
        dict(selector="tbody tr:nth-child(odd)",
             props=[("background-color", "#eee")]),

        #cell spacing
        dict(selector="td", 
             props=[("padding", ".5em")]),

        #header cell properties
        dict(selector="th", 
             props=[("font-size", "100%"),
                    ("text-align", "center")]),


    ]
    return (df.style.set_table_styles(styles)).render()
iris = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv')
getTableHTML(iris)
DougR
  • 3,196
  • 1
  • 28
  • 29
4

Some points to clarify first:

  • Pandas doesn't have anything to do with the styling, and the styling happens to all HTML tables, not only dataframes. That is easily checked by displaying an HTML table in Jupyter (example code at the end of the answer).
  • It seems that your Jupyter or one of your installed extensions is doing "extra" styling, the default style doesn't include column sorting or column highlighting. There is only odd/even rows coloring and row highlighting (checked on Jupyter source code and my local Jupyter installation). This means that my answer may not include all the styling you want.

The Answer

Is the dataframe rendering code used by jupyter available as a standalone module that can be used in any web app?

Not exactly a standalone module, but all the tables formatting and styling seem to be attached to the rendered_html class. Double-checked that by inspecting the notebook HTML in Firefox.
You can use the .less file linked above directly or copy the required styles to your HTML.

Also, are the assets such as js/css files decoupled from jupyter so that they can be easily reused?

Like any well-designed web project (and actually any software project), the packages and modules are well separated. This means that you can re-use a lot of the code in your project with minimal effort. You can find most of the .less styling files in Jupyter source code here.


An example to check if the styling happens to all HTML tables:

from IPython.display import HTML

HTML('''<table>
  <thead><tr><th></th><th>a</th><th>b</th></tr></thead>
  <tbody>
    <tr><th>0</th><td>1</td><td>3</td></tr>
    <tr><th>1</th><td>2</td><td>4</td></tr>
  </tbody>
</table>''')
Qusai Alothman
  • 1,982
  • 9
  • 23
  • Indeed, I had [jupyter_contrib_nbextensions](https://github.com/ipython-contrib/jupyter_contrib_nbextensions) installed and that added the extra column sorting and row highlighting. Thanks for the `less` link! – ccpizza Jan 29 '19 at 11:05
  • @qusai-alothman I appreciate this explanation, I just didn't understand how I can use that `rendered_html_class` you referred to to style my dataframe? – fazistinho_ Nov 18 '20 at 17:47