ggposter builds an A1 (or other true-size) conference poster from ggplot2. A poster is declared as a title band plus columns of rounded, tab-headed cards – text, tables, ggplot2 figures, or photo strips – assembled with grid and gtable and rendered at true size with embedded fonts, including CJK (Japanese). Content and layout can be written as an R list or a YAML file; figures, tables, and photos are supplied separately as R objects.
Installation
You can install the development version of ggposter from GitHub with:
Example
The layout below follows a typical conference poster – a full-width title band and a two-column body of rounded, tab-headed cards for introduction/methods/summary on the left and results/conclusions on the right – filled in with the mpg fuel-economy dataset bundled with ggplot2. The title, author, and affiliation are placeholders. It also shows two features for keeping a card’s height tied to what’s actually in it, instead of a fixed proportion of the column: height = "auto" sizes a card to fit its own content, and notes puts a bullet-list description beside a table or figure.
library(ggposter)
library(ggplot2)
tbl_class <- aggregate(cbind(hwy, cty) ~ class, data = mpg, FUN = function(x) round(mean(x), 1))
names(tbl_class) <- c("Class", "Mean hwy", "Mean cty")
class_best <- tbl_class$Class[which.max(tbl_class$`Mean hwy`)]
class_worst <- tbl_class$Class[which.min(tbl_class$`Mean hwy`)]
tbl_drv <- aggregate(cbind(hwy, cty) ~ drv, data = mpg, FUN = function(x) round(mean(x), 1))
names(tbl_drv) <- c("Drivetrain", "Mean hwy", "Mean cty")
drv_best <- tbl_drv$Drivetrain[which.max(tbl_drv$`Mean hwy`)]
drv_worst <- tbl_drv$Drivetrain[which.min(tbl_drv$`Mean hwy`)]
fig_facet <- ggplot(mpg, aes(displ, hwy, colour = class)) +
geom_point() +
labs(caption = paste(
"• Highway mileage falls as engine displacement rises.",
"• Compact and subcompact classes reach the highest mileage.",
sep = "\n")) +
theme_bw() +
theme(legend.position = "inside", legend.position.inside = c(0.85, 0.72),
legend.background = element_rect(fill = scales::alpha("white", 0.7), colour = NA),
legend.key.size = unit(0.9, "lines"),
plot.caption = element_text(hjust = 0, size = rel(1.3), colour = "black"))
fig_scatter <- ggplot(mpg, aes(cty, hwy, colour = drv)) +
geom_point(alpha = 0.7) +
theme_bw() +
theme(legend.position = "inside", legend.position.inside = c(0.75, 0.32),
legend.background = element_rect(fill = scales::alpha("white", 0.7), colour = NA))
fig_box <- ggplot(mpg, aes(drv, hwy, fill = drv)) +
geom_boxplot(show.legend = FALSE) +
labs(x = "Drivetrain", y = "Highway mpg") +
theme_bw()
drv_med <- aggregate(hwy ~ drv, data = mpg, FUN = median)
drv_box_best <- as.character(drv_med$drv[which.max(drv_med$hwy)])
mpg_heat <- aggregate(hwy ~ class + drv, data = mpg, FUN = function(x) round(mean(x), 1))
fig_heat <- ggplot(mpg_heat, aes(drv, class, fill = hwy)) +
geom_tile(colour = "white") +
geom_text(aes(label = hwy), size = 2.6) +
scale_fill_gradient(low = "#E8F5E9", high = "#2E7D32") +
labs(x = "Drivetrain", y = "Class", fill = "Mean hwy") +
theme_minimal() +
theme(legend.position = "bottom")
img_dir <- system.file("extdata", package = "ggposter")
stock_photos <- c("small.JPG", "tall.jpg", "wide.jpg", "large.JPG")
stock_labels <- c("Photo A", "Photo B", "Photo C", "Photo D")
spec <- list(
title = list(
title = "Example Poster: Fuel Economy Patterns in the mpg Dataset",
authors = "*Jane Doe (Example University), John Smith (Example Institute)",
funding = "This is a demonstration poster for the ggposter package; it does not describe real research."
),
layout = list(
left = c("objectives", "background", "methods", "summary_table", "fig_box", "fig_heat"),
right = c("conclusions", "results_table", "fig_facet", "fig_scatter", "photos_2")
),
sections = list(
objectives = list(header = "OBJECTIVES", height = "auto", body = list(type = "text", md = c(
"- Demonstrate the ggposter package.",
"- Use the mpg fuel-economy dataset as example content.",
"- Combine text, tables, figures, and photos in one poster."
))),
background = list(header = "BACKGROUND", height = "auto", body = list(type = "text", md = c(
"- Conference posters often mix text, tables, and figures.",
"- ggposter arranges these as rounded, tab-headed cards.",
"- Layout and content can be declared as an R list or a YAML file."
))),
methods = list(header = "METHODS", height = "auto", body = list(type = "text", md = c(
"- Data: the mpg dataset (234 vehicles, model years 1999-2008).",
"- Figures: highway/city mileage by class and drivetrain.",
"- Photos: generic stock images bundled with ggposter."
))),
summary_table = list(header = "SUMMARY by class", height = "auto", body = list(
type = "table", object = "tbl_class", title = "Mean mileage by vehicle class",
notes = c(
sprintf("- **%s** has the best highway mileage of all vehicle classes in this dataset.", class_best),
sprintf("- **%s** has the worst, largely due to its greater size and weight.", class_worst),
"- Compact and subcompact classes have nearly identical mean highway mileage.",
"- Midsize vehicles average close to the compact/subcompact classes.",
"- Pickup and SUV classes have the two lowest highway mileages, both under 19 mpg.",
"- City mileage tracks highway mileage closely across all seven classes."
)
)),
fig_box = list(header = "Mileage spread by drivetrain", height = "auto", body = list(
type = "figure", object = "fig_box", notes_width = 0.4, height = 117,
notes = c(
"- Boxes show the full spread of highway mileage, not just the mean.",
sprintf("- **%s**-wheel drive has the highest median highway mileage.", drv_box_best)
)
)),
fig_heat = list(header = "Mean mileage: class x drivetrain", height = "auto", body = list(
type = "figure", object = "fig_heat", notes_width = 0.4, height = 137,
notes = c(
"- Colour shows mean highway mpg for each class/drivetrain combination.",
"- Blank cells are combinations that don't occur in the data."
)
)),
conclusions = list(header = "CONCLUSIONS", height = "auto", body = list(type = "text", md = c(
"- Compact and subcompact cars get the best highway mileage.",
"- SUVs and pickups get the lowest.",
"- ggposter can lay out this kind of summary automatically."
))),
results_table = list(header = "SUMMARY by drivetrain", height = "auto", body = list(
type = "table", object = "tbl_drv", title = "Mean mileage by drivetrain",
notes = c(
sprintf("- **%s**-wheel drive has the best highway mileage among the three drivetrain types.", drv_best),
sprintf("- **%s**-wheel drive has the worst, mainly due to the added weight of the drivetrain.", drv_worst),
"- The gap between front- and four-wheel drive is nearly 9 mpg highway."
)
)),
fig_facet = list(header = "Mileage by class", height = "auto",
body = list(type = "figure", object = "fig_facet", height = 280)),
fig_scatter = list(header = "Highway vs. city mileage", height = "auto", body = list(
type = "figure", object = "fig_scatter", notes_width = 0.45, height = 102,
notes = c(
"- Highway and city mileage are closely correlated.",
"- 4-wheel drive vehicles cluster at the low-mileage end.",
"- Front-wheel drive vehicles cluster at the high-mileage end."
)
)),
photos_2 = list(header = "More sample photos", height = "auto", body = list(
type = "image", files = stock_photos, labels = stock_labels,
width = 230
))
)
)
p <- poster(
spec,
objects = list(tbl_class = tbl_class, tbl_drv = tbl_drv,
fig_facet = fig_facet, fig_scatter = fig_scatter,
fig_box = fig_box, fig_heat = fig_heat),
theme = theme_green(base_size = 24),
base_dir = img_dir
)The same layout, theme, title, and section text can live in a YAML file instead of an inline R list, keeping the declarative content separate from the R code. Only the figures and tables stay in R, passed in via objects (reusing the same objects built above); image paths in the spec resolve relative to the YAML file’s own directory. p_yml below is identical to p above:
yml_path <- system.file("extdata", "poster_readme_example.yml", package = "ggposter")
p_yml <- poster(
yml_path,
objects = list(tbl_class = tbl_class, tbl_drv = tbl_drv,
fig_facet = fig_facet, fig_scatter = fig_scatter,
fig_box = fig_box, fig_heat = fig_heat)
)Rendering a poster at true size makes font sizes and spacing come out correctly proportioned; previewing it at an arbitrary plot size (as this README does) does not, so we render a scaled-down preview PNG instead of printing p directly:
render_poster(p, "man/figures/README-poster-preview.png", scale = 0.3, dpi = 150)
knitr::include_graphics("man/figures/README-poster-preview.png")
Seeing each card’s plot area
Passing show_plot_area = TRUE to render_poster() outlines every card’s header tab and body – the area its text, table, figure, or photo strip actually occupies – with a dashed border, on top of the content. A table/figure paired with a bullet-list description gets two separate borders, one for each side, rather than one around the pair. It’s an output option, so the same poster p renders both the normal version above and the outlined version below – useful for checking exactly how much of a card each of its parts fills:
render_poster(p, "man/figures/README-poster-preview-plot-area.png",
scale = 0.3, dpi = 150, show_plot_area = TRUE)
knitr::include_graphics("man/figures/README-poster-preview-plot-area.png")
Save it at true size, with fonts embedded:
render_poster(p, "poster.pdf") # true A1 size
render_poster(p, "preview.png", scale = 0.25, dpi = 150) # A4-ish previewSee vignette("ggposter") for the full spec schema, theming, and a reproduction of a real conference poster.
How to make an academic poster
The poster below is a quick tour of ggposter’s card types rather than a real research example: the left column has one card of each kind – a bullet list, a figure, a figure with a caption below it, a table with notes beside it, a photo strip, and finally how the title and layout parts of the spec themselves are written – the center column shows the YAML spec for the matching card on the left, and the right column shows the equivalent R code.
howto_fig <- ggplot(mpg, aes(displ, hwy)) +
geom_point(colour = "#2E7D32") +
theme_bw()
howto_fig_notes <- ggplot(mpg, aes(class, hwy)) +
geom_boxplot(fill = "#A5D6A7") +
labs(x = "Class", y = "Highway mpg") +
theme_bw()
howto_tbl_notes <- data.frame(Drivetrain = c("f", "4", "r"),
`Mean highway mpg` = c(28.2, 19.2, 21.0),
check.names = FALSE)
howto_spec <- list(
title = list(
title = "How to Make an Academic Poster",
authors = "*A guide to the ggposter card types",
funding = "Each left-column card demonstrates one card type; the matching center-column card shows the YAML spec for it; the matching right-column card shows the equivalent R code."
),
layout = list(
align_rows = TRUE,
left = c(
"howto_title", "howto_layout",
"howto_bullets", "howto_table_notes",
"howto_figure", "howto_figure_notes",
"howto_photo"),
center = c(
"yml_title", "yml_layout",
"yml_bullets", "yml_table_notes",
"yml_figure", "yml_figure_notes",
"yml_photo"),
right = c(
"code_title", "code_layout",
"code_bullets", "code_table_notes",
"code_figure", "code_figure_notes",
"code_photo")
),
sections = list(
howto_title = list(header = "The title band", height = "auto", body = list(
type = "text", md = c(
"- `title` is written once, not per column.",
"- `title`, `authors`, `funding` stack top to bottom.",
"- It spans the full poster width, above every column."
)
)),
howto_layout = list(header = "The layout", height = "auto", body = list(
type = "text", md = c(
"- `layout` assigns section names to columns.",
"- Column names are free-form -- not just left/right.",
"- `align_rows: true` lines up each row to the tallest card at that row."
)
)),
howto_bullets = list(header = "Bullet list only", height = "auto", body = list(
type = "text", md = c(
"- Bullet points summarize key facts.",
"- Each line starts with a dash.",
"- Long lines wrap to fit the card."
)
)),
howto_figure = list(header = "Figure only", height = "auto", body = list(
type = "figure", object = "howto_fig", height = 100
)),
howto_figure_notes = list(header = "Figure + bullets (below)", height = "auto", body = list(
type = "figure", object = "howto_fig_notes", height = 110,
caption = paste(
"- A figure's caption= adds bullets below it.",
"- Great for calling out key takeaways.",
sep = "\n"
)
)),
howto_table_notes = list(header = "Table + bullets (right)", height = "auto", body = list(
type = "table", object = "howto_tbl_notes", notes_width = 0.4,
notes = c(
"- A table's notes= sits beside it.",
"- Good for a short note."
)
)),
howto_photo = list(header = "Photo strip", height = "auto", body = list(
type = "image", files = c("small.JPG", "tall.jpg", "wide.jpg"),
labels = c("Photo 1", "Photo 2", "Photo 3"), width = 200
)),
yml_title = list(header = "YAML: title", height = "auto", body = list(
type = "text", md = c(
"title:",
" title: \"How to Make an Academic Poster\"",
" authors: \"*A guide to the ggposter card types\"",
" funding: \"...\""
)
)),
yml_layout = list(header = "YAML: layout", height = "auto", body = list(
type = "text", md = c(
"layout:",
" align_rows: true",
" left: howto_bullets, ...",
" center: yml_bullets, ...",
" right: code_bullets, ..."
)
)),
yml_bullets = list(header = "YAML: bullet list", height = "auto", body = list(
type = "text", md = c(
"howto_bullets:",
" header: \"Bullet list only\"",
" height: \"auto\"",
" body:",
" type: text",
" md:",
" \\- \"- Bullet points summarize key facts.\"",
" \\- \"- Each line starts with a dash.\"",
" \\- \"- Long lines wrap to fit the card.\""
)
)),
yml_figure = list(header = "YAML: figure only", height = "auto", body = list(
type = "text", md = c(
"howto_figure:",
" header: \"Figure only\"",
" height: \"auto\"",
" body:",
" type: figure",
" object: howto_fig",
" height: 80"
)
)),
yml_figure_notes = list(header = "YAML: figure + bullets", height = "auto", body = list(
type = "text", md = c(
"howto_figure_notes:",
" header: \"Figure + bullets (below)\"",
" height: \"auto\"",
" body:",
" type: figure",
" object: howto_fig_notes",
" height: 110",
" caption: |-",
" \\- A figure's caption= adds bullets below it.",
" \\- Great for calling out key takeaways."
)
)),
yml_table_notes = list(header = "YAML: table + bullets", height = "auto", body = list(
type = "text", md = c(
"howto_table_notes:",
" header: \"Table + bullets (right)\"",
" height: \"auto\"",
" body:",
" type: table",
" object: howto_tbl_notes",
" notes_width: 0.4",
" notes:",
" \\- \"- A table's notes= sits beside it.\"",
" \\- \"- Good for a short note.\""
)
)),
yml_photo = list(header = "YAML: photo strip", height = "auto", body = list(
type = "text", md = c(
"howto_photo:",
" header: \"Photo strip\"",
" height: \"auto\"",
" body:",
" type: image",
" files:",
" \\- small.JPG",
" \\- tall.jpg",
" \\- wide.jpg",
" labels:",
" \\- \"Photo 1\"",
" \\- \"Photo 2\"",
" \\- \"Photo 3\"",
" width: 200"
)
)),
code_title = list(header = "Code: title", height = "auto", body = list(
type = "text", md = c(
"title = list(",
" title = \"How to Make an Academic Poster\",",
" authors = \"*A guide to the ggposter card types\",",
" funding = \"...\"",
")"
)
)),
code_layout = list(header = "Code: layout", height = "auto", body = list(
type = "text", md = c(
"layout = list(",
" align_rows = TRUE,",
" left = c(\"howto_bullets\", ...),",
" center = c(\"yml_bullets\", ...),",
" right = c(\"code_bullets\", ...)",
")"
)
)),
code_bullets = list(header = "Code: bullet list", height = "auto", body = list(
type = "text", md = c(
"list(",
" header = \"Bullet list only\",",
" body = list(",
" type = \"text\",",
" md = c(",
" \"- Bullet points summarize key facts.\",",
" \"- Each line starts with a dash.\",",
" \"- Long lines wrap to fit the card.\"",
" )",
" )",
")"
)
)),
code_figure = list(header = "Code: figure only", height = "auto", body = list(
type = "text", md = c(
"list(",
" header = \"Figure only\",",
" body = list(",
" type = \"figure\",",
" object = \"howto_fig\",",
" height = 80",
" )",
")"
)
)),
code_figure_notes = list(header = "Code: figure + bullets", height = "auto", body = list(
type = "text", md = c(
"list(",
" header = \"Figure + bullets (below)\",",
" body = list(",
" type = \"figure\",",
" object = \"howto_fig_notes\",",
" height = 80,",
" caption = paste(",
" \"- A figure's caption= adds bullets below it.\",",
" \"- Great for calling out key takeaways.\",",
" sep = \"\\n\"",
" )",
" )",
")"
)
)),
code_table_notes = list(header = "Code: table + bullets", height = "auto", body = list(
type = "text", md = c(
"list(",
" header = \"Table + bullets (right)\",",
" body = list(",
" type = \"table\",",
" object = \"howto_tbl_notes\",",
" notes_width = 0.4,",
" notes = c(",
" \"- A table's notes= sits beside it.\",",
" \"- Good for a short note.\"",
" )",
" )",
")"
)
)),
code_photo = list(header = "Code: photo strip", height = "auto", body = list(
type = "text", md = c(
"list(",
" header = \"Photo strip\",",
" body = list(",
" type = \"image\",",
" files = c(\"small.JPG\", \"tall.jpg\", \"wide.jpg\"),",
" labels = c(\"Photo 1\", \"Photo 2\", \"Photo 3\"),",
" width = 200",
" )",
")"
)
))
)
)
p_howto <- poster(
howto_spec,
objects = list(howto_fig = howto_fig, howto_fig_notes = howto_fig_notes,
howto_tbl_notes = howto_tbl_notes),
theme = theme_green(base_size = 18),
base_dir = img_dir
)The same layout, theme, title, and section text can live in a YAML file instead of an inline R list; only the figures and tables stay in R, passed in via objects. p_howto_yml below is identical to p_howto above:
howto_yml_path <- system.file("extdata", "poster_sample_howto.yml", package = "ggposter")
p_howto_yml <- poster(
howto_yml_path,
objects = list(howto_fig = howto_fig, howto_fig_notes = howto_fig_notes,
howto_tbl_notes = howto_tbl_notes)
)
render_poster(p_howto, "man/figures/README-howto-poster.png", scale = 0.3, dpi = 150)
knitr::include_graphics("man/figures/README-howto-poster.png")