Working with Datasets

Great Tables includes sixteen built-in datasets that are used throughout this User Guide and in the API documentation. These datasets cover a range of subject areas and sizes, from the small exibble toy table (8 rows) to the larger pizzaplace dataset (nearly 50,000 rows). You can load any of them as a Pandas DataFrame, a Polars DataFrame, or both, depending on how you prefer to work.

These built-in datasets exist so you can experiment with Great Tables features without needing to bring your own data. They make it easy to follow along with examples, test table-building code, and explore different formatting options. They also demonstrate the range of data types and structures that Great Tables handles well, from small categorical tables to large transactional datasets with dates, currencies, and numeric measurements.

Accessing Datasets Directly

The simplest way to use a dataset is to import it by name from great_tables.data. This returns a Pandas DataFrame by default (or a Polars DataFrame if Pandas is not installed).

from great_tables import GT
from great_tables.data import exibble

GT(exibble)
num char fctr date time datetime currency row group
0.1111 apricot one 2015-01-15 13:35 2018-01-01 02:22 49.95 row_1 grp_a
2.222 banana two 2015-02-15 14:40 2018-02-02 14:33 17.95 row_2 grp_a
33.33 coconut three 2015-03-15 15:45 2018-03-03 03:44 1.39 row_3 grp_a
444.4 durian four 2015-04-15 16:50 2018-04-04 15:55 65100.0 row_4 grp_a
5550.0 five 2015-05-15 17:55 2018-05-05 04:00 1325.81 row_5 grp_b
fig six 2015-06-15 2018-06-06 16:11 13.255 row_6 grp_b
777000.0 grapefruit seven 19:10 2018-07-07 05:22 row_7 grp_b
8880000.0 honeydew eight 2015-08-15 20:20 0.44 row_8 grp_b

The exibble dataset is also available directly on the top-level great_tables module, which can be convenient for quick experimentation:

import great_tables as gt

GT(gt.exibble)
num char fctr date time datetime currency row group
0.1111 apricot one 2015-01-15 13:35 2018-01-01 02:22 49.95 row_1 grp_a
2.222 banana two 2015-02-15 14:40 2018-02-02 14:33 17.95 row_2 grp_a
33.33 coconut three 2015-03-15 15:45 2018-03-03 03:44 1.39 row_3 grp_a
444.4 durian four 2015-04-15 16:50 2018-04-04 15:55 65100.0 row_4 grp_a
5550.0 five 2015-05-15 17:55 2018-05-05 04:00 1325.81 row_5 grp_b
fig six 2015-06-15 2018-06-06 16:11 13.255 row_6 grp_b
777000.0 grapefruit seven 19:10 2018-07-07 05:22 row_7 grp_b
8880000.0 honeydew eight 2015-08-15 20:20 0.44 row_8 grp_b

All sixteen datasets are available this way: countrypops, sza, gtcars, sp500, pizzaplace, exibble, towny, peeps, films, metro, gibraltar, constants, illness, reactions, photolysis, and nuclides. Each one has its own documentation page in the API reference with a full description of its columns and contents.

This direct import approach is the most concise option and works well when you’re writing examples or exploring the package. Since the default backend is Pandas, existing code that imports datasets this way will continue to work without any changes.

Choosing a Backend with data.pd and data.pl

If you want to be explicit about whether you get a Pandas or Polars DataFrame, use the data.pd and data.pl namespaces. Being explicit about your backend is especially important in shared codebases or library code where you want to guarantee the DataFrame type, regardless of what packages happen to be installed in a given environment. Datasets accessed through these namespaces are loaded on first access and cached for subsequent use, so there’s no performance penalty for repeated access.

To get a dataset as a Polars DataFrame, use data.pl:

from great_tables import GT, data

GT(data.pl.exibble)
num char fctr date time datetime currency row group
0.1111 apricot one 2015-01-15 13:35 2018-01-01 02:22 49.95 row_1 grp_a
2.222 banana two 2015-02-15 14:40 2018-02-02 14:33 17.95 row_2 grp_a
33.33 coconut three 2015-03-15 15:45 2018-03-03 03:44 1.39 row_3 grp_a
444.4 durian four 2015-04-15 16:50 2018-04-04 15:55 65100.0 row_4 grp_a
5550.0 None five 2015-05-15 17:55 2018-05-05 04:00 1325.81 row_5 grp_b
None fig six 2015-06-15 None 2018-06-06 16:11 13.255 row_6 grp_b
777000.0 grapefruit seven None 19:10 2018-07-07 05:22 None row_7 grp_b
8880000.0 honeydew eight 2015-08-15 20:20 None 0.44 row_8 grp_b

To explicitly request a Pandas DataFrame, use data.pd:

GT(data.pd.exibble)
num char fctr date time datetime currency row group
0.1111 apricot one 2015-01-15 13:35 2018-01-01 02:22 49.95 row_1 grp_a
2.222 banana two 2015-02-15 14:40 2018-02-02 14:33 17.95 row_2 grp_a
33.33 coconut three 2015-03-15 15:45 2018-03-03 03:44 1.39 row_3 grp_a
444.4 durian four 2015-04-15 16:50 2018-04-04 15:55 65100.0 row_4 grp_a
5550.0 five 2015-05-15 17:55 2018-05-05 04:00 1325.81 row_5 grp_b
fig six 2015-06-15 2018-06-06 16:11 13.255 row_6 grp_b
777000.0 grapefruit seven 19:10 2018-07-07 05:22 row_7 grp_b
8880000.0 honeydew eight 2015-08-15 20:20 0.44 row_8 grp_b

The data.pl namespace is especially useful in Polars-only workflows. It reads directly from the underlying CSV files using Polars’ own reader, so there is no dependency on Pandas and no need to convert with pl.from_pandas(). Similarly, data.pd always uses the Pandas CSV reader regardless of what other libraries are installed.

Using load_dataset()

The load_dataset() function provides a programmatic way to load any dataset in a specific format. This is convenient when the dataset name or backend is determined at runtime, for example in a loop, a parameterized notebook, or a function that accepts the table type as an argument.

from great_tables import GT, load_dataset

gtcars_pl = load_dataset(dataset="gtcars", tbl_type="polars")

(
    GT(gtcars_pl.head(5))
    .cols_hide(columns=["trim", "trsmn", "drivetrain", "bdy_style"])
)
mfr model year hp hp_rpm trq trq_rpm mpg_c mpg_h ctry_origin msrp
Ford GT 2017 647.0 6250.0 550.0 5900.0 11.0 18.0 United States 447000.0
Ferrari 458 Speciale 2015 597.0 9000.0 398.0 6000.0 13.0 17.0 Italy 291744.0
Ferrari 458 Spider 2015 562.0 9000.0 398.0 6000.0 13.0 17.0 Italy 263553.0
Ferrari 458 Italia 2014 562.0 9000.0 398.0 6000.0 13.0 17.0 Italy 233509.0
Ferrari 488 GTB 2016 661.0 8000.0 561.0 3000.0 15.0 22.0 Italy 245400.0

The tbl_type= parameter accepts "pandas" (the default) or "polars", and the dataset= parameter accepts any of the sixteen dataset names listed above. Here is the same idea with a Pandas DataFrame:

sp500_pd = load_dataset(dataset="sp500", tbl_type="pandas")

GT(sp500_pd.head(5))
date open high low close volume adj_close
2015-12-31 2060.5901 2062.54 2043.62 2043.9399 2655330000.0 2043.9399
2015-12-30 2077.3401 2077.3401 2061.97 2063.3601 2367430000.0 2063.3601
2015-12-29 2060.54 2081.5601 2060.54 2078.3601 2542000000.0 2078.3601
2015-12-28 2057.77 2057.77 2044.2 2056.5 2492510000.0 2056.5
2015-12-24 2063.52 2067.3601 2058.73 2060.99 1411860000.0 2060.99

If you pass an unrecognized dataset name or table type, load_dataset() raises a ValueError with a message listing the valid options. This makes it safe to use in automated workflows where a typo might otherwise lead to a confusing AttributeError.

Summary of Access Patterns

The table below summarizes the three approaches. All of them read directly from the package’s bundled CSV files, so no network access is needed and the data is always available.

Pattern Returns Use when…
data.exibble Pandas (default) You want the simplest import
data.pd.exibble Pandas (always) You want to be explicit about Pandas
data.pl.exibble Polars (always) You’re working in a Polars-only workflow
load_dataset("exibble", tbl_type="polars") Polars The dataset name or type is a variable

Whichever approach you choose, the resulting DataFrame can be passed directly to GT() to start building a table. In the rest of this User Guide we’ll mostly use the simple from great_tables.data import ... style, but everything you see works just as well with a Polars DataFrame loaded through data.pl or load_dataset().