As our work on Great Tables continues, we want you to be able to produce increasingly sophisticated tables. The look of an HTML table really matters and we believe aesthetics can elevate the presentation of tabular data. In the v0.3.0 release, we’ve implemented features that are concerned with modifying the visual aspects of a table. Let’s get down to what’s new in this version.
Modifying the widths of columns
Before v0.3.0, you could not alter the widths of individual columns. This meant that to great extent your content decided the width of individual columns. Even though browsers do an adequate job in sizing the widths of table columns, it doesn’t always result in a pleasing-to-look-at table. What if you want more space? Maybe you want consistently-sized columns? There’s many reasons to want to have a choice in the matter and the new cols_width() method now makes this possible.
Here’s an example where the widths of all columns are set with our preferred length values (in px).
You don’t have to define widths for all columns with cols_width(), and you’re free to use either px or % values when defining widths. See the reference page for more information and relevant examples.
Setting options across the entire table with tab_options()
The new tab_options() method gives you the freedom to specify any of dozens of global style and layout options for the table. Want a font that’s used across all cells? Use the table_font_names= option. Do you need to make the text smaller, but only in the stub? Use stub_font_size= for that. The number of options is perhaps overwhelming at first but we think you’ll enjoy having them around nonetheless. It makes styling the table (and developing your own table themes) a relatively simple task.
Here’s an example that creates a table with a few common components and then uses tab_options() to set up a collection of fonts for the table with the (also new) system_fonts() function:
from great_tables import md, system_fontsgt_tbl = ( GT( exibble[["num", "char", "currency", "row", "group"]], rowname_col="row", groupname_col="group", ) .tab_header( title=md("Data listing from **exibble**"), subtitle=md("`exibble` is a **Great Tables** dataset."), ) .fmt_number(columns="num") .fmt_currency(columns="currency") .tab_source_note(source_note="This is only a subset of the dataset."))gt_tbl.tab_options(table_font_names=system_fonts(name="industrial"))
Data listing from exibble
exibble is a Great Tables dataset.
num
char
currency
grp_a
row_1
0.11
apricot
$49.95
row_2
2.22
banana
$17.95
row_3
33.33
coconut
$1.39
row_4
444.40
durian
$65,100.00
grp_b
row_5
5,550.00
$1,325.81
row_6
fig
$13.26
row_7
777,000.00
grapefruit
row_8
8,880,000.00
honeydew
$0.44
This is only a subset of the dataset.
Note that table_font_names= accepts a list of fonts that operate as fallbacks for users across different systems (i.e., they may not have the font you have). And the system_fonts() helper function in Great Tables makes this easy by providing you with themed, local font stacks that are meant to work across different computing platforms.
Here’s another example where we set the width of the table to span across the entire page (or containing element).
gt_tbl.tab_options(table_width="100%")
Data listing from exibble
exibble is a Great Tables dataset.
num
char
currency
grp_a
row_1
0.11
apricot
$49.95
row_2
2.22
banana
$17.95
row_3
33.33
coconut
$1.39
row_4
444.40
durian
$65,100.00
grp_b
row_5
5,550.00
$1,325.81
row_6
fig
$13.26
row_7
777,000.00
grapefruit
row_8
8,880,000.00
honeydew
$0.44
This is only a subset of the dataset.
One more where the background color of the table is set to "lightcyan":
There are many more options available in tab_options(), so have a look at its reference page for more information and useful examples.
Using the new opt_*() methods to do more complex tasks with table options
While tab_options() is a great method for setting global table options, sometimes you want to set a number of them at once for a combined effect. For that type of operation, we have the opt_*() series of methods. A common thing you might do is align the content in the table header, we can make that an easy thing with opt_align_table_header():
gt_tbl.opt_align_table_header(align="left")
Data listing from exibble
exibble is a Great Tables dataset.
num
char
currency
grp_a
row_1
0.11
apricot
$49.95
row_2
2.22
banana
$17.95
row_3
33.33
coconut
$1.39
row_4
444.40
durian
$65,100.00
grp_b
row_5
5,550.00
$1,325.81
row_6
fig
$13.26
row_7
777,000.00
grapefruit
row_8
8,880,000.00
honeydew
$0.44
This is only a subset of the dataset.
With that, you don’t have to hunt through the myriad options within tab_options() to find the two args you need to get the job done.
The opt_all_caps() method transforms the text within the column labels, the stub, and in all row groups so that we get an all-capitalized (yet somewhat sized down) look that better differentiates the labels from the data. It’s rather easy to use, just do this:
gt_tbl.opt_all_caps()
Data listing from exibble
exibble is a Great Tables dataset.
num
char
currency
grp_a
row_1
0.11
apricot
$49.95
row_2
2.22
banana
$17.95
row_3
33.33
coconut
$1.39
row_4
444.40
durian
$65,100.00
grp_b
row_5
5,550.00
$1,325.81
row_6
fig
$13.26
row_7
777,000.00
grapefruit
row_8
8,880,000.00
honeydew
$0.44
This is only a subset of the dataset.
This sets nine options you’d otherwise set in tab_options() all at once, making life generally easier.
Here’s one last example, this time using opt_vertical_padding(). You’d use that if you’re dissatisfied with the level of top/bottom padding within cells of all locations (e.g., in the table body, in the column labels, etc.). You can either make a table taller or more ‘compressed’ with a single argument: scale=. Here’s an example where the amount of vertical padding is reduced, resulting in a table taking up less vertical space.
gt_tbl.opt_vertical_padding(scale=0.5)
Data listing from exibble
exibble is a Great Tables dataset.
num
char
currency
grp_a
row_1
0.11
apricot
$49.95
row_2
2.22
banana
$17.95
row_3
33.33
coconut
$1.39
row_4
444.40
durian
$65,100.00
grp_b
row_5
5,550.00
$1,325.81
row_6
fig
$13.26
row_7
777,000.00
grapefruit
row_8
8,880,000.00
honeydew
$0.44
This is only a subset of the dataset.
We have the following methods available in the opt_*() family
and we plan to add more opt_*() methods in future releases.
A new formatting method: fmt_image()
Wouldn’t it be great to add graphics to your table? The fmt_image() method provides an easy way to add image files on disk into table body cells. The cells need to contain some reference to an image file. The path= and file_pattern= arguments give you some flexibility in defining exactly where the image files live.
Here’s an example using the metro dataset that’s included within Great Tables.
from great_tables.data import metrofrom importlib_resources import filesimg_paths = files("great_tables") /"data/metro_images"metro_mini = metro[["name", "lines", "passengers"]].head(5)( GT(metro_mini) .fmt_image(columns="lines", path=img_paths, file_pattern="metro_{}.svg") .fmt_integer(columns="passengers") .cols_label( name="Station", lines="Metro Lines", passengers="Passengers per Year (2021)" ) .tab_options(table_width="700px"))
Station
Metro Lines
Passengers per Year (2021)
Argentine
2,079,212
Bastille
8,069,243
Bérault
2,106,827
Champs-Élysées—Clemenceau
1,909,005
Charles de Gaulle—Étoile
4,291,663
Notice that path=img_paths specified the folder the images live in, and file_pattern="metro_{}.svg" provided a template for converting each value in the lines column to an SVG file name.
The fmt_image() method supports three kinds of files as inputs, either: (1) complete http/https or local paths to the files; (2) the file names, where a common path can be provided via the path= arg; or (3) a fragment of the file name, as shown in the example above.
The package has some graphics stored in the data/metro_images directory. They are SVGs and they look very nice in the example table!
See the fmt_image() reference page for more information on this new method.
Wrapping up
This v0.3.0 release has some great new methods that add value to most any table-making endeavor. We also fixed a few bugs along the way so that you’ll have a overall smoother experience when building beautiful tables. As ever, we’ll work toward more and more improvements to give you more creative possibilities!