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:
| 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.
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.
| 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().