Pandas DataFrames and Series as Interactive Tables in Jupyter

Pypi Build Status codecov.io Binder Star

Turn pandas DataFrames and Series into interactive datatables in both your notebooks and their HTML representation with a single additional import:

In [1]:
import itables.interactive
import world_bank_data as wb

df = wb.get_countries()
df
Out[1]:
iso2Code name region adminregion incomeLevel lendingType capitalCity longitude latitude
id

You don't see any table above? Please either open the HTML export of this notebook, or run this README on Binder!

Quick start

Install the package with

pip install itables

Activate the interactive mode for all series and dataframes with

In [2]:
import itables.interactive

Display just one series or dataframe as an interactive table with the show function.

In [3]:
from itables import show

x = wb.get_series("SP.POP.TOTL", mrv=1, simplify_index=True)
show(x)
SP.POP.TOTL
Country

Advanced usage

Pagination

How many rows per page

Select how many entries should appear at once in the table with the lengthMenu argument of the show function, or by changing itables.options.default:

In [4]:
import itables.options as opt

opt.lengthMenu = [2, 5, 10, 20, 50, 100, 200, 500]
df
Out[4]:
iso2Code name region adminregion incomeLevel lendingType capitalCity longitude latitude
id

Show the table in full

Show the table in full with the paging argument, either in the show method, or in the options:

In [5]:
show(df.head(), paging=False)
iso2Code name region adminregion incomeLevel lendingType capitalCity longitude latitude
id

Scroll

If you prefer to replace the pagination with a vertical scroll, use for instance

In [6]:
show(df, scrollY="200px", scrollCollapse=True, paging=False)
iso2Code name region adminregion incomeLevel lendingType capitalCity longitude latitude
id

Table and cell style

Select how your table should look like with the classes argument of the show function, or by changing itables.options.classes. For the list of possible values, see datatables' default style and the style examples.

In [7]:
opt.classes = ["display", "nowrap"]
df
Out[7]:
iso2Code name region adminregion incomeLevel lendingType capitalCity longitude latitude
id
In [8]:
opt.classes = ["display", "cell-border"]
df
Out[8]:
iso2Code name region adminregion incomeLevel lendingType capitalCity longitude latitude
id

Float precision

Floats are rounded using pd.options.display.float_format. Please change that format according to your preference.

In [9]:
import math
import pandas as pd

with pd.option_context("display.float_format", "{:,.2f}".format):
    show(pd.Series([i * math.pi for i in range(1, 6)]))
0

You may also choose to convert floating numbers to strings:

In [10]:
with pd.option_context("display.float_format", "${:,.2f}".format):
    show(pd.Series([i * math.pi for i in range(1, 6)]))
0

Advanced cell formatting

Datatables allows to set the cell or row style depending on the cell content, with either the createdRow or createdCell callback. For instance, if we want the cells with negative numbers to be colored in red, we can use the columnDefs.createdCell argument as follows:

In [11]:
show(
    pd.DataFrame([[-1, 2, -3, 4, -5], [6, -7, 8, -9, 10]], columns=list("abcde")),
    columnDefs=[
        {
            "targets": "_all",
            "createdCell": """function (td, cellData, rowData, row, col) {
      if ( cellData < 0 ) {
        $(td).css('color', 'red')
      }
    }""",
        }
    ],
)
a b c d e

Column width

FIXME: This does not appear to be working...

In [12]:
show(df, columnsDefs=[{"width": "200px", "target": 3}])
iso2Code name region adminregion incomeLevel lendingType capitalCity longitude latitude
id

But in some cases - a table with many column like the one below, we can use the width parameter...

In [13]:
show(x.to_frame().T, columnDefs=[{"width": "80px", "targets": "_all"}])
Country Arab World Caribbean small states Central Europe and the Baltics Early-demographic dividend East Asia & Pacific East Asia & Pacific (excluding high income) East Asia & Pacific (IDA & IBRD countries) Euro area Europe & Central Asia Europe & Central Asia (excluding high income) Europe & Central Asia (IDA & IBRD countries) European Union Fragile and conflict affected situations Heavily indebted poor countries (HIPC) High income IBRD only IDA & IBRD total IDA blend IDA only IDA total Late-demographic dividend Latin America & Caribbean Latin America & Caribbean (excluding high income) Latin America & the Caribbean (IDA & IBRD countries) Least developed countries: UN classification Low & middle income Low income Lower middle income Middle East & North Africa Middle East & North Africa (excluding high income) Middle East & North Africa (IDA & IBRD countries) Middle income North America Not classified OECD members Other small states Pacific island small states Post-demographic dividend Pre-demographic dividend Small states South Asia South Asia (IDA & IBRD) Sub-Saharan Africa Sub-Saharan Africa (excluding high income) Sub-Saharan Africa (IDA & IBRD countries) Upper middle income World Afghanistan Albania Algeria American Samoa Andorra Angola Antigua and Barbuda Argentina Armenia Aruba Australia Austria Azerbaijan Bahamas, The Bahrain Bangladesh Barbados Belarus Belgium Belize Benin Bermuda Bhutan Bolivia Bosnia and Herzegovina Botswana Brazil British Virgin Islands Brunei Darussalam Bulgaria Burkina Faso Burundi Cabo Verde Cambodia Cameroon Canada Cayman Islands Central African Republic Chad Channel Islands Chile China Colombia Comoros Congo, Dem. Rep. Congo, Rep. Costa Rica Cote d'Ivoire Croatia Cuba Curacao Cyprus Czech Republic Denmark Djibouti Dominica Dominican Republic Ecuador Egypt, Arab Rep. El Salvador Equatorial Guinea Eritrea Estonia Eswatini Ethiopia Faroe Islands Fiji Finland France French Polynesia Gabon Gambia, The Georgia Germany Ghana Gibraltar Greece Greenland Grenada Guam Guatemala Guinea Guinea-Bissau Guyana Haiti Honduras Hong Kong SAR, China Hungary Iceland India Indonesia Iran, Islamic Rep. Iraq Ireland Isle of Man Israel Italy Jamaica Japan Jordan Kazakhstan Kenya Kiribati Korea, Dem. People’s Rep. Korea, Rep. Kosovo Kuwait Kyrgyz Republic Lao PDR Latvia Lebanon Lesotho Liberia Libya Liechtenstein Lithuania Luxembourg Macao SAR, China Madagascar Malawi Malaysia Maldives Mali Malta Marshall Islands Mauritania Mauritius Mexico Micronesia, Fed. Sts. Moldova Monaco Mongolia Montenegro Morocco Mozambique Myanmar Namibia Nauru Nepal Netherlands New Caledonia New Zealand Nicaragua Niger Nigeria North Macedonia Northern Mariana Islands Norway Oman Pakistan Palau Panama Papua New Guinea Paraguay Peru Philippines Poland Portugal Puerto Rico Qatar Romania Russian Federation Rwanda Samoa San Marino Sao Tome and Principe Saudi Arabia Senegal Serbia Seychelles Sierra Leone Singapore Sint Maarten (Dutch part) Slovak Republic Slovenia Solomon Islands Somalia South Africa South Sudan Spain Sri Lanka St. Kitts and Nevis St. Lucia St. Martin (French part) St. Vincent and the Grenadines Sudan Suriname Sweden Switzerland Syrian Arab Republic Tajikistan Tanzania Thailand Timor-Leste Togo Tonga Trinidad and Tobago Tunisia Turkey Turkmenistan Turks and Caicos Islands Tuvalu Uganda Ukraine United Arab Emirates United Kingdom United States Uruguay Uzbekistan Vanuatu Venezuela, RB Vietnam Virgin Islands (U.S.) West Bank and Gaza Yemen, Rep. Zambia Zimbabwe

HTML in cells

In [14]:
import pandas as pd

show(
    pd.Series(
        [
            "<b>bold</b>",
            "<i>italic</i>",
            '<a href="https://github.com/mwouts/itables">link</a>',
        ],
        name="HTML",
    ),
    paging=False,
)
HTML

Select rows

Not currently implemented. May be made available at a later stage using the select extension for datatables.

Copy, CSV, PDF and Excel buttons

Not currently implemented. May be made available at a later stage thanks to the buttons extension for datatable.

Large table support

itables will not display dataframes that are larger than maxBytes, which is equal to 1MB by default. Truncate the dataframe with df.head(), or set the maxBytes parameter or option to an other value to display the dataframe. Or deactivate the limit with maxBytes=0.

Note that datatables support server-side processing. At a later stage we may implement support for larger tables using this feature.

In [15]:
df = wb.get_indicators()
df.values.nbytes
Out[15]:
826512
In [16]:
opt.maxBytes = 1000000
df
Out[16]:
name unit source sourceNote sourceOrganization topics
id

References

DataTables

  • DataTables is a plug-in for the jQuery Javascript library. It has a great documentation, and a large set of examples.
  • The R package DT uses datatables.net as the underlying library for both R notebooks and Shiny applications. In addition to the standard functionalities of the library (display, sort, filtering and row selection), RStudio seems to have implemented cell edition.
  • Marek Cermak has an interesting tutorial on how to use datatables within Jupyter. He also published jupyter-datatables, with a focus on numerical data and distribution plots.

Alternatives

ITables is not a Jupyter widget, which means that it does not allows you to edit the content of the dataframe. If you are looking for Jupyter widgets, have a look at

If you are looking for a table component that will fit in Dash applications, see datatable by Dash.

Contributing

I think it would be very helpful to have an identical table component for both Jupyter and Dash. Please let us know if you are interested in drafting a new table component based on an existing Javascript library for Dash.

Also, if you happen to prefer another Javascript table library (say, ag-grid), and you would like to see it supported in itables, please open either an issue or a PR, and let us know what is the minimal code to display a table in Jupyter using your library.

Appendix

Below we initialize the github star button Star that appears on top of this notebook:

In [17]:
%%HTML
<script async defer src="https://buttons.github.io/buttons.js"></script>