pandasjupyterscrollbarnbconvertlongtable

How to add a vertical scrollbar in html output from jupyter notebook with nbconvert?


I am automatizing some reports with jupyter and exporting it to html. I have some large tables, and I want to add a scrollbar to rigthside of table. A similar question is here: How to get a vertical scrollbar in HTML output from Jupyter notebooks. Here are a reproducible example:

    import pandas as pd
    import numpy as np

    pd.set_option('display.max_columns', None)
    pd.set_option('display.max_rows', None)

    np.random.seed(2021)

    df = pd.DataFrame({'type': ['a'] * 50 + ['b'] * 50,
              'var_1': np.random.normal(size=100),
              'var_2': np.random.normal(size=100)})

I think it could be done using .css styling, but I'm having dificulties to apply it. Pandas have some useful methods for styling tables (https://pandas.pydata.org/pandas-docs/stable/user_guide/style.html). Then, I tryed the following:

   vscrollbar = {
     'selector': 'div.output_html',
     'props': ' height: 500px; overflow-y: scroll;'
   }

   df.style.set_table_styles([vscrollbar])

After that, I compile the notebook from CLI with

   jupyter-nbconvert example.ipybn --to-html

The output don't show the right scrollbar. But if I inspect the html code, the style that I passed throw Pandas is there

...
<style type="text/css">
#T_e24f1_ table {
  height: 500px;
  overflow-y: scroll;
}
</style>
<table id="T_e24f1_">
  <thead>
    <tr>
      <th class="blank level0">&nbsp;</th>
      <th class="col_heading level0 col0">type</th>
      <th class="col_heading level0 col1">var_1</th>
      <th class="col_heading level0 col2">var_2</th>
    </tr>
  </thead>
  <tbody>
...

I don't know if I'm passing the right selector, or if jupyter is overwriting this style.

How can I get a right scrollbar for long tables in html output from jupyter nbconvert?


Solution

  • There is a list of things you should know.

    1. selector is a method that could help you to select one or several elements in html. So, maybe, you need to learn about how to use it. For your example. It should be '', cause, if you ever checked what the code output in ipynb, you will see like this below.
    #T_f2ffe_  div.output_html{
      height: 500px;
      overflow-y: scroll;
    }
    

    The first part #T_f2ffe_ is generated randomly by pandas and the second part div.output_html is what you write. And these selectors will work together, and that will cause you to not specify any elements

    1. A table in html, its height is calculated in two aspects, the td height and the number of td. If you want the css height to work, you'd better add display:inline-block first.

    So here is the final answer that will work by little change.

    vscrollbar = {
     'selector': '',
     'props': ' height: 500px; overflow-y: scroll;display: inline-block;'
    }
    
    df.style.set_table_styles([vscrollbar])
    

    And the html looks like.

    enter image description here