geom_table adds a textual table directly to the ggplot using syntax similar to that of geom_label while geom_table_npc is similar to geom_label_npc in that x and y coordinates are given in npc units.

geom_table(mapping = NULL, data = NULL, stat = "identity",
  position = "identity", ..., parse = FALSE, na.rm = FALSE,
  show.legend = FALSE, inherit.aes = FALSE)

geom_table_npc(mapping = NULL, data = NULL, stat = "identity",
  position = "identity", ..., parse = FALSE, na.rm = FALSE,
  show.legend = FALSE, inherit.aes = FALSE)



The aesthetic mapping, usually constructed with aes or aes_. Only needs to be set at the layer level if you are overriding the plot defaults.


A layer specific dataset - only needed if you want to override the plot defaults.


The statistical transformation to use on the data for this layer, as a string.


Position adjustment, either as a string, or the result of a call to a position adjustment function.


other arguments passed on to layer. This can include aesthetics whose values you want to set, not map. See layer for more details.


If TRUE, the labels will be parsed into expressions and displayed as described in ?plotmath.


If FALSE (the default), removes missing values with a warning. If TRUE silently removes missing values.


logical. Should this layer be included in the legends? NA, the default, includes if any aesthetics are mapped. FALSE never includes, and TRUE always includes.


If FALSE, overrides the default aesthetics, rather than combining with them. This is most useful for helper functions that define both data and aesthetics and shouldn't inherit behaviour from the default plot specification, e.g. borders.


Note the "width" and "height" like of a text element are 0, so stacking and dodging tables will not work by default, and axis limits are not automatically expanded to include all tables. Obviously, tables do have height and width, but they are physical units, not data units. The amount of space they occupy on that plot is not constant in data units: when you resize a plot, tables stay the same size, but the size of the axes changes.


This geom works only with tibbles as data, as it expects a list of data frames or a list of tibbles to be mapped to the label aesthetic. In the current version the following aesthetics affect the text within the table size, colour, and alpha. The argument to parameter parse is simply passed forward to gridExtra::ttheme_default(). As x and y determine the position of the whole table, similarly to that of a text label, justification is interpreted as indicating the position of the table with respect to the $x$ and $y$ coordinates in the data, and angle is used to rotate the table as a whole. Other aesthetics, including fill are not yet implemented, neither are themes for table formatting. annotate() cannot be used with geom = "table". Use geom_table directly also for adding annotations.


You can modify table alignment with the vjust and hjust aesthetics. These can either be a number between 0 (right/bottom) and 1 (top/left) or a character ("left", "middle", "right", "bottom", "center", "top").


This geometry is inspired on answers to two questions in Stackoverflow. In contrast to these earlier examples, the current geom obeys the grammar of graphics, and attempts to be consistent with the behaviour of 'ggplot2' geometries.

See also

function tableGrob as it is used to construct the table.


#> #> Attaching package: 'dplyr'
#> The following object is masked from 'package:testthat': #> #> matches
#> The following objects are masked from 'package:stats': #> #> filter, lag
#> The following objects are masked from 'package:base': #> #> intersect, setdiff, setequal, union
library(tibble) mtcars %>% group_by(cyl) %>% summarize(wt = mean(wt), mpg = mean(mpg)) %>% ungroup() %>% mutate(wt = sprintf("%.2f", wt), mpg = sprintf("%.1f", mpg)) -> tb df <- tibble(x = 0.95, y = 0.95, tb = list(tb)) ggplot(mtcars, aes(wt, mpg, colour = factor(cyl))) + geom_point() + geom_table_npc(data = df, aes(npcx = x, npcy = y, label = tb), hjust = 1, vjust = 1)