Skip to content

Different ways of handling tables

Code
docs/staging/tables.py
import pandas as pd
from mkreports import Report, md
from plotnine.data import mtcars


def use_tables(report: Report) -> None:
    """
    Show all the different ways on how we can work with tables.
    """
    ex_table = pd.DataFrame(
        [
            {"name": "Alfred", "age": 30, "hair": "red", "married": True},
            {"name": "Beate", "age": 50, "hair": "brown", "married": False},
            {
                "name": "Caro",
                "age": 7,
                "hair": "green",
                "married": False,
            },
        ]
    )
    ex_table["hair"] = pd.Categorical(ex_table.hair)

    p = report.page("usage/tables.md", truncate=True)

    p.H1("Different ways of handling tables")

    p.CollapsedCodeFile(__file__)

    p.Raw(
        """
        Conveying information with tables is very important for 
        any type of report. Standard tables in markdown format 
        can be very useful for this for limited amout of data, but for 
        larger tables more sophisticated libraries are needed. 
        """
    )
    with p.H2("Markdown tables"):
        p.Raw(
            """
            Below an example of a regular markdown table. As it is very wide,
            horizontal scrolling is enabled by default. In addition, the number
            of rows is limited to 10 as there is no automatic paging available.
            """
        )
        p.add(md.Table(pd.DataFrame(mtcars).head(10), index=False))

    with p.H2("DataTable javascript library"):
        p.Raw(
            """
            Here the same table, but displayed using the 
            [DataTables](https://datatables.net/)  
            plugin. With this, we get automatic paging, searching as well as sorting
            by columns. 
            """
        )
        # and as a DataTable
        p.DataTable(pd.DataFrame(mtcars))

        with p.H3("Header filters").ctx("nocode"):
            p.Raw(
                """
                Below a DataTable example with column filters in the header.
                The header in use is determined by the column type of the pandas
                table used for display. 

                - A numeric column gets a range selector
                - A categorical or boolean column a dropdown selection
                - Any other column a text-field.
                """
            )
            p.DataTable(ex_table, add_header_filters=True)

        with p.H3("Download buttons").ctx("nocode"):
            p.Raw(
                """
                An example with buttons for downloading and printing
                of the table.
                """
            )
            p.DataTable(ex_table, downloads=True)

    with p.H2("Tabulator javascript library"):
        p.Raw(
            """
            This time, we use the [Tabulator](http://tabulator.info)
            library. A library with a lot of interesting 
            functionality.
            """
        )
        p.Tabulator(
            pd.DataFrame(mtcars), add_header_filters=False, prettify_colnames=False
        )

        with p.H3("Header filters").ctx("nocode"):
            p.Raw(
                """
                We also can enable header filtering. For the datatypes

                - numeric
                - boolean
                - categorical 
                - str

                default filter options have been defined. Below
                we create a table with various different data types
                to show these functions.

                The applied filters are

                - Input filter for the names
                - Range filter with min and max for age
                - Select dropdown for hair color
                - and checkbox for marital status
                """
            )
            p.Tabulator(ex_table, add_header_filters=True, prettify_colnames=True)

        with p.H3("Download buttons").ctx("nocode"):
            p.P(
                """
                An example showing download buttons for export to csv, json or excel.
                """
            )
            p.Tabulator(
                ex_table,
                add_header_filters=True,
                prettify_colnames=True,
                downloads=True,
            )

    with p.H2("Notes"):
        p.Raw(
            """
            Internally, the tables are serialized to json so that 
            they can be displayed in the web-browser. For any types 
            that are non-native to json (e.g. Path-instances), as a
            default handler the `str` funtion is called. If this
            is not ok, please transform the table columns accordingly.
            """
        )

Conveying information with tables is very important for any type of report. Standard tables in markdown format can be very useful for this for limited amout of data, but for larger tables more sophisticated libraries are needed.

Markdown tables

Below an example of a regular markdown table. As it is very wide, horizontal scrolling is enabled by default. In addition, the number of rows is limited to 10 as there is no automatic paging available.

name mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21 6 160 110 3.9 2.62 16.46 0 1 4 4
Mazda RX4 Wag 21 6 160 110 3.9 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108 93 3.85 2.32 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360 175 3.15 3.44 17.02 0 0 3 2
Valiant 18.1 6 225 105 2.76 3.46 20.22 1 0 3 1
Duster 360 14.3 8 360 245 3.21 3.57 15.84 0 0 3 4
Merc 240D 24.4 4 146.7 62 3.69 3.19 20 1 0 4 2
Merc 230 22.8 4 140.8 95 3.92 3.15 22.9 1 0 4 2
Merc 280 19.2 6 167.6 123 3.92 3.44 18.3 1 0 4 4
docs/staging/tables.py
39
40
41
42
43
44
45
46
p.Raw(
    """
    Below an example of a regular markdown table. As it is very wide,
    horizontal scrolling is enabled by default. In addition, the number
    of rows is limited to 10 as there is no automatic paging available.
    """
)
p.add(md.Table(pd.DataFrame(mtcars).head(10), index=False))

DataTable javascript library

Here the same table, but displayed using the DataTables
plugin. With this, we get automatic paging, searching as well as sorting by columns.

Header filters

Below a DataTable example with column filters in the header. The header in use is determined by the column type of the pandas table used for display.

  • A numeric column gets a range selector
  • A categorical or boolean column a dropdown selection
  • Any other column a text-field.

Download buttons

An example with buttons for downloading and printing of the table.

docs/staging/tables.py
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
p.Raw(
    """
    Here the same table, but displayed using the 
    [DataTables](https://datatables.net/)  
    plugin. With this, we get automatic paging, searching as well as sorting
    by columns. 
    """
)
# and as a DataTable
p.DataTable(pd.DataFrame(mtcars))

with p.H3("Header filters").ctx("nocode"):
    p.Raw(
        """
        Below a DataTable example with column filters in the header.
        The header in use is determined by the column type of the pandas
        table used for display. 

        - A numeric column gets a range selector
        - A categorical or boolean column a dropdown selection
        - Any other column a text-field.
        """
    )
    p.DataTable(ex_table, add_header_filters=True)

with p.H3("Download buttons").ctx("nocode"):
    p.Raw(
        """
        An example with buttons for downloading and printing
        of the table.
        """
    )
    p.DataTable(ex_table, downloads=True)

Tabulator javascript library

This time, we use the Tabulator library. A library with a lot of interesting functionality.

Header filters

We also can enable header filtering. For the datatypes

  • numeric
  • boolean
  • categorical
  • str

default filter options have been defined. Below we create a table with various different data types to show these functions.

The applied filters are

  • Input filter for the names
  • Range filter with min and max for age
  • Select dropdown for hair color
  • and checkbox for marital status

Download buttons

An example showing download buttons for export to csv, json or excel.

docs/staging/tables.py
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
p.Raw(
    """
    This time, we use the [Tabulator](http://tabulator.info)
    library. A library with a lot of interesting 
    functionality.
    """
)
p.Tabulator(
    pd.DataFrame(mtcars), add_header_filters=False, prettify_colnames=False
)

with p.H3("Header filters").ctx("nocode"):
    p.Raw(
        """
        We also can enable header filtering. For the datatypes

        - numeric
        - boolean
        - categorical 
        - str

        default filter options have been defined. Below
        we create a table with various different data types
        to show these functions.

        The applied filters are

        - Input filter for the names
        - Range filter with min and max for age
        - Select dropdown for hair color
        - and checkbox for marital status
        """
    )
    p.Tabulator(ex_table, add_header_filters=True, prettify_colnames=True)

with p.H3("Download buttons").ctx("nocode"):
    p.P(
        """
        An example showing download buttons for export to csv, json or excel.
        """
    )
    p.Tabulator(
        ex_table,
        add_header_filters=True,
        prettify_colnames=True,
        downloads=True,
    )

Notes

Internally, the tables are serialized to json so that they can be displayed in the web-browser. For any types that are non-native to json (e.g. Path-instances), as a default handler the str funtion is called. If this is not ok, please transform the table columns accordingly.

docs/staging/tables.py
133
134
135
136
137
138
139
140
141
p.Raw(
    """
    Internally, the tables are serialized to json so that 
    they can be displayed in the web-browser. For any types 
    that are non-native to json (e.g. Path-instances), as a
    default handler the `str` funtion is called. If this
    is not ok, please transform the table columns accordingly.
    """
)