Tables
Pyreball allows printing pandas DataFrame objects
into HTML tables with print_table()
function.
Moreover, Pyreball uses DataTables library to add styling and interactivity to the tables.
Basic Usage
The simplest usage is to provide just a DataFrame
object:
import pandas as pd
import pyreball as pb
df = pd.DataFrame(
{
"name": ["Bob", "Carol", "Alice", "Dave"],
"age": [23, 5, 22, 54],
}
)
pb.print_table(df)
Captions
All tables are numbered by default, which causes creation of Table 1.
caption above.
It is possible to provide custom caption text via caption
parameter.
To control whether Table k.
prefix should be displayed, numbered
Boolean parameter can be set accordingly.
import pandas as pd
import pyreball as pb
df = pd.DataFrame(
{
"name": ["Bob", "Carol", "Alice", "Dave"],
"age": [23, 5, 22, 54],
}
)
pb.print_table(df, caption="People with their age.")
pb.print_table(df, caption="People with their age.", numbered=False)
pb.print_table(df, numbered=False)
pb.print_table(df, caption="The table with numbering again.")
Note
All tables are internally numbered, even though the numbering might be turned off for specific tables, as shown in the previous example.
Caption Position
By default, the caption is positioned above the table.
The position can be controlled by caption_position
parameter, which can be set either to top
or bottom
.
import pandas as pd
import pyreball as pb
df = pd.DataFrame(
{
"name": ["Bob", "Carol", "Alice", "Dave"],
"age": [23, 5, 22, 54],
}
)
pb.print_table(df, caption="Top caption.", caption_position="top")
pb.print_table(df, caption="Bottom caption.", caption_position="bottom")
Aligning Tables
Tables can be horizontally aligned by align
parameter, as shown in the following example.
import pandas as pd
import pyreball as pb
df = pd.DataFrame(
{
"name": ["Bob", "Carol", "Alice", "Dave"],
"age": [23, 5, 22, 54],
}
)
pb.print_table(df, caption="Left align.", align="left")
pb.print_table(df, caption="Center align.", align="center")
pb.print_table(df, caption="Right align.", align="right")
Aligning Columns
Numeric columns are aligned to right and columns of other types to left, by default.
This behaviour can be changed through col_align
parameter.
The parameter takes either a string (to set the same alignment for all columns), or a list of strings
(to set the alignment of each column individually).
When a list is provided and index is displayed, the list must contain also values for the index columns.
import pandas as pd
import pyreball as pb
df = pd.DataFrame(
{
"name": ["Bob", "Carol", "Alice", "Dave"],
"age": [23, 5, 22, 54],
},
index=[1, 10, 100, 1000],
)
pb.print_table(df, caption="Default alignment.")
pb.print_table(df, caption="Identical alignment.", col_align="left")
pb.print_table(
df,
caption="Heterogeneous alignment.",
col_align=["center", "right", "left"],
)
Sorting
It is possible to make the table sortable on all columns by setting sortable
parameter to True
,
or by setting sorting_definition
parameter, which also sorts the table initially on the specified column(s).
Parameter sorting_definition
expects a list of tuples, where each tuple contains a column index and string asc
or desc
. The table is primarily sorted according to the first tuple, secondarily according to the second tuple, and so
on.
The following snippet shows the usage of both parameters.
Note
Although the columns in sorting_definition
are indexed from 0, it is necessary to take into account
also the table index when it is displayed. To hide the index, set index
parameter
of print_table()
method to False
.
index
parameter is one of the kwargs
parameters that are passed to
Pandas to_html() method,
which is used internally by Pyreball.
import pandas as pd
import pyreball as pb
df = pd.DataFrame(
{
"name": ["Bob", "Carol", "Alice", "Dave", "Alice"],
"age": [23, 5, 2, 54, 18],
}
)
pb.print_table(df, caption="Sortable table", sortable=True)
pb.print_table(
df,
caption="Table sorted by age (ASC).",
sorting_definition=[(df.columns.get_loc("age") + 1, "asc")],
)
pb.print_table(
df,
caption="Table sorted by name (ASC) and age (DESC).",
sorting_definition=[(1, "asc"), (2, "desc")],
)
pb.print_table(
df,
caption="The same table, but without the index.",
index=False,
sorting_definition=[(0, "asc"), (1, "desc")],
)
Dealing with Large Tables
Each table is fully displayed by default. This is caused by keeping the display_option
parameter
to its default value full
.
However, this might not be practical for large tables.
One solution is to allow vertical scrolling of the table by setting display_option
to scrolling
.
To change the default height of the table, set also scroll_y_height
parameter.
import pandas as pd
import pyreball as pb
df = pd.DataFrame(
[[row * 20 + col for col in range(20)] for row in range(40)],
columns=[f"col_{i}" for i in range(20)],
)
pb.print_table(
df,
caption="Larger table with scrolling.",
display_option="scrolling",
scroll_y_height="500px",
)
Note
By default, Pyreball turns on horizontall scrolling on each table as can be seen in the previous example.
You can turn it off by setting scroll_x
parameter to False
. This, however, might cause the table to overflow
the container.
Another option is to set display_option
to paging
. This option can be further customized by providing custom page
sizes through paging_sizes
parameter. Currently, paging_sizes
takes a list of integers mixed with string All
(the
case of the letters does not matter, so it can be all
or ALL
as well). When All
is used, Pyreball interprets it as
showing all entries on a single page.
import pandas as pd
import pyreball as pb
df = pd.DataFrame(
[[row * 20 + col for col in range(20)] for row in range(40)],
columns=[f"col_{i}" for i in range(20)],
)
pb.print_table(
df,
caption="Larger table with paging.",
display_option="paging",
paging_sizes=[5, 10, "All"],
)
Searching
To allow searching within a table, just set search_box
to True
.
import pandas as pd
import pyreball as pb
df = pd.DataFrame(
{
"name": ["Bob", "Carol", "Alice", "Dave"],
"age": [23, 5, 22, 54],
}
)
pb.print_table(
df,
caption="Table with a search box.",
search_box=True,
)
Complex Headers and Indices
Pandas allows its users to create complex (multi-level) headers and indices. Such tables can be also printed into HTML, which creates additional columns and header rows, as can be seen in the following example. The code snippet also shows how to display index columns as regular columns.
import pandas as pd
import pyreball as pb
df = pd.DataFrame(
[
("Bob", 2, 12, 23, 49),
("Carol", 54, 42, 2, 4),
("Alice", 20, 4, 18, 19),
("Dave", 42, 21, 43, 23),
("Eve", 7, 12, 55, 6),
("Frank", 1, 5, 48, 38),
],
columns=pd.MultiIndex.from_tuples(
[
("name", ""),
("current", "x"),
("current", "y"),
("previous", "x"),
("previous", "y"),
],
),
index=pd.MultiIndex.from_tuples(
[
("red", "dev"),
("red", "dev"),
("red", "qa"),
("blue", "dev"),
("blue", "dev"),
("blue", "qa"),
],
names=["team", "role"],
),
)
pb.print_table(
df,
caption="With index.",
sorting_definition=[(2, "asc")],
)
pb.print_table(
df.reset_index(),
caption="Without index.",
index=False,
sorting_definition=[(2, "asc")],
)
The example also shows that when defining sorting on columns via sorting_definition
parameter,
a user must take into account index columns too.
Index columns must be also taken into account when setting col_align
parameter.
Note
Pyreball sets sparsify
parameter of
Pandas to_html() method to False
,
because DataTables would not be able to display tables with a multi-index correctly,
especially not with sortable columns. This is also the reason why the identical team
values
are not merged in the first table above.
Styling
Tables are also styled with the help of DataTables library.
The default styling class used is display
.
To change the styling, use parameter datatables_style
, which takes either a single string with a class name,
or a list of class names.
Usable class names are listed in the styling reference
of Datatables documentation.
import pandas as pd
import pyreball as pb
df = pd.DataFrame(
{
"name": ["Bob", "Carol", "Alice", "Dave"],
"age": [23, 5, 22, 54],
}
)
pb.print_table(
df,
caption="Style set to 'compact'.",
datatables_style="compact",
)
pb.print_table(
df,
caption="Style set to 'compact' and 'display'.",
datatables_style=["compact", "display"],
)
Custom DataTables Configuration
Most of the parameters in the previous sections were just setting up the parameters of DataTable
JavaScript object
in some predefined manner.
It is possible to completely override such parameters by providing custom dictionary via datatables_definition
parameter. This dictionary is then serialized into JSON and passed to the DataTable
JavaScript object.
import pandas as pd
import pyreball as pb
df = pd.DataFrame(
[[row * 20 + col for col in range(20)] for row in range(40)],
columns=[f"col_{i}" for i in range(20)],
)
datatables_definition = {
"paging": False,
"scrollCollapse": True,
"scrollY": "400px",
"searching": False,
"order": [(1, "desc")],
}
pb.print_table(
df,
caption="Larger table with custom config.",
datatables_definition=datatables_definition,
)