ggplot2gghighlightcowplotpatchworkemperors (data/emperors.csv)gapminder (library(gapminder))nyc_squirrels (data/nyc_squirrels.csv + data/central_park/)diabetes (data/diabetes.csv)la_heat_income (data/los-angeles.geojson)





colorblindr::palette_OkabeIto())
viridis::inferno())
"grey**", grey(.**))emperors <- read_csv(file.path("data", "emperors.csv"))emperors
## # A tibble: 68 x 16## index name name_full birth death birth_cty## <dbl> <chr> <chr> <date> <date> <chr> ## 1 1 Augu… IMPERATO… 0062-09-23 0014-08-19 Rome ## 2 2 Tibe… TIBERIVS… 0041-11-16 0037-03-16 Rome ## 3 3 Cali… GAIVS IV… 0012-08-31 0041-01-24 Antitum ## 4 4 Clau… TIBERIVS… 0009-08-01 0054-10-13 Lugdunum ## 5 5 Nero NERO CLA… 0037-12-15 0068-06-09 Antitum ## 6 6 Galba SERVIVS … 0002-12-24 0069-01-15 Terracina## 7 7 Otho MARCVS S… 0032-04-28 0069-04-16 Terentin…## 8 8 Vite… AVLVS VI… 0015-09-24 0069-12-20 Rome ## 9 9 Vesp… TITVS FL… 0009-11-17 0079-06-24 Falacrine## 10 10 Titus TITVS FL… 0039-12-30 0081-09-13 Rome ## # … with 58 more rows, and 10 more variables:## # birth_prv <chr>, rise <chr>, reign_start <date>,## # reign_end <date>, cause <chr>, killer <chr>, …emperors %>% count(cause) %>% ggplot(aes(x = n, y = cause)) + geom_col() + geom_text( aes(label = n, x = n - .25), color = "white", size = 5, hjust = 1 ) + cowplot::theme_minimal_vgrid(16) + theme( axis.title.y = element_blank(), legend.position = "none" ) + xlab("number of emperors")
emperors %>% count(cause) %>% arrange(n) %>% mutate(cause = fct_inorder(cause)) %>% ggplot(aes(x = n, y = cause)) + geom_col() + geom_text( aes(label = n, x = n - .25), color = "white", size = 5, hjust = 1 ) + cowplot::theme_minimal_vgrid(16) + theme( axis.title.y = element_blank(), legend.position = "none" ) + xlab("number of emperors")
emperors_assassinated <- emperors %>% count(cause) %>% arrange(n) %>% mutate( assassinated = ifelse(cause == "Assassination", TRUE, FALSE), cause = fct_inorder(cause) )emperors_assassinated %>% ggplot(aes(x = n, y = cause, fill = assassinated)) + geom_col() + geom_text( aes(label = n, x = n - .25), color = "white", size = 5, hjust = 1 ) + cowplot::theme_minimal_vgrid(16) + theme( axis.title.y = element_blank(), legend.position = "none" ) + scale_fill_manual( name = NULL, values = c("#B0B0B0D0", "#D55E00D0") ) + xlab("number of emperors")

arrange() by the number of each type of killermutate(), create a new variable that is TRUE if killer matches the category you want to highlight and FALSE otherwisefill aesthetic of the ggplot callscale_fill_manual() to add the fill colors. Set values to c("#B0B0B0D0", "#D55E00D0").emperor_killers <- emperors %>% # group the least common killers to "other" mutate(killer = fct_lump(killer, 10)) %>% count(killer) %>% arrange(n)emperor_killers
## # A tibble: 14 x 2## killer n## <fct> <int>## 1 Aneurism 1## 2 Court Officials 1## 3 Fire 1## 4 Heart Failure 1## 5 Lightning 1## 6 Usurper 1## 7 Wife 2## 8 Senate 3## 9 Own Army 5## 10 Unknown 5## 11 Opposing Army 6## 12 Praetorian Guard 7## 13 Disease 16## 14 Other Emperor 18lightning_plot <- emperor_killers %>% mutate( lightning = ifelse(killer == "Lightning", TRUE, FALSE), # use `fct_inorder()` to maintain the way we sorted the data killer = fct_inorder(killer) ) %>% ggplot(aes(x = n, y = killer, fill = lightning)) + geom_col() + geom_text( aes(label = n, x = n - .25), color = "white", size = 5, hjust = 1 ) + cowplot::theme_minimal_vgrid(16) + theme( axis.title.y = element_blank(), legend.position = "none" ) + scale_fill_manual(values = c("#B0B0B0D0", "#D55E00D0")) + xlab("number of emperors")lightning_plot
library(gapminder)gapminder
## # A tibble: 1,704 x 6## country continent year lifeExp pop gdpPercap## <fct> <fct> <int> <dbl> <int> <dbl>## 1 Afghanistan Asia 1952 28.8 8425333 779.## 2 Afghanistan Asia 1957 30.3 9240934 821.## 3 Afghanistan Asia 1962 32.0 10267083 853.## 4 Afghanistan Asia 1967 34.0 11537966 836.## 5 Afghanistan Asia 1972 36.1 13079460 740.## 6 Afghanistan Asia 1977 38.4 14880372 786.## 7 Afghanistan Asia 1982 39.9 12881816 978.## 8 Afghanistan Asia 1987 40.8 13867957 852.## 9 Afghanistan Asia 1992 41.7 16317921 649.## 10 Afghanistan Asia 1997 41.8 22227415 635.## # … with 1,694 more rowsgapminder %>% filter(year == 2007) %>% ggplot(aes(log(gdpPercap), lifeExp)) + geom_point( aes(color = country), size = 3.5, alpha = .9 ) + theme_minimal(14) + theme(panel.grid.minor = element_blank()) + labs( x = "log(GDP per capita)", y = "life expectancy" )



library(ggrepel)library(ggrepel)
geom_text_repel()geom_label_repel()gapminder %>% filter(year == 2007) %>% ggplot(aes(log(gdpPercap), lifeExp)) + geom_point( size = 3.5, alpha = .9, shape = 21, col = "white", fill = "#0162B2" ) + geom_text_repel(aes(label = country)) + theme_minimal(14) + theme(panel.grid.minor = element_blank()) + labs( x = "log(GDP per capita)", y = "life expectancy" )
sample() to select 10 random countries to plot (run the set.seed() line first if you want the same results)mutate() call, check if country is one of the countries in ten_countries. If it's not, make the label an empty string (""),label aesthetic using the variable just created in mutate()library(gapminder)library(ggrepel)set.seed(42)ten_countries <- gapminder$country %>% levels() %>% sample(10)ten_countries
## [1] "Ghana" "Italy" "Lesotho" "Swaziland" "Zimbabwe" ## [6] "Thailand" "Gambia" "Chile" "Korea, Rep." "Paraguay"p1 <- gapminder %>% filter(year == 2007) %>% mutate( label = ifelse( country %in% ten_countries, as.character(country), "" ) ) %>% ggplot(aes(log(gdpPercap), lifeExp)) + geom_point( size = 3.5, alpha = .9, shape = 21, col = "white", fill = "#0162B2" )scatter_plot <- p1 + geom_text_repel( aes(label = label), size = 4.5, point.padding = .2, box.padding = .3, force = 1, min.segment.length = 0 ) + theme_minimal(14) + theme( legend.position = "none", panel.grid.minor = element_blank() ) + labs( x = "log(GDP per capita)", y = "life expectancy" )scatter_plot
p1 + geom_text( data = function(x) filter(x, country == "Gabon"), aes(label = country), size = 4.5, hjust = 0, nudge_x = .06 ) + theme_minimal(14) + theme( legend.position = "none", panel.grid.minor = element_blank() ) + labs( x = "log(GDP per capita)", y = "life expectancy" )
library(cowplot)library(cowplot)marginal_histogram <- axis_canvas(scatter_plot, "y") + geom_histogram( data = gapminder %>% filter(year == 2007), bins = 40, aes(y = lifeExp), fill = "#0162B2E6", color = "white" )scatter_plot %>% insert_yaxis_grob(marginal_histogram) %>% ggdraw()





summarize() call, create a variable called y that is the maximum lifeExp value for every continent For the labels, we'll use the continent names, which will be retained automatically.legend.position = "none" in theme().axis_canvas(line_plot, axis = "y") creates a new ggplot2 canvas based on the y axis from line_plot. Add a text geom (using + as you normally would). In the text geom: set data to direct_labels; in aes(), set y = y, label = continent; Outside of aes() set x to 0.05 (to add a little buffer); Make the size of the text 4.5; Set the horizontal justification to 0insert_yaxis_grob() to take lineplot and insert direct_labels_axis.ggdraw()library(cowplot)# get the mean life expectancy by continent and yearcontinent_data <- gapminder %>% group_by(continent, year) %>% summarise(lifeExp = mean(lifeExp))direct_labels <- continent_data %>% group_by(continent) %>% summarize(y = max(lifeExp))line_plot <- continent_data %>% ggplot(aes(year, lifeExp, col = continent)) + geom_line(size = 1) + theme_minimal_hgrid() + theme(legend.position = "none") + scale_color_manual(values = continent_colors) + scale_x_continuous(expand = expansion()) + labs(y = "life expectancy")direct_labels_axis <- axis_canvas(line_plot, axis = "y") + geom_text( data = direct_labels, aes(y = y, label = continent), x = .05, size = 4.5, hjust = 0 )p_direct_labels <- insert_yaxis_grob(line_plot, direct_labels_axis)ggdraw(p_direct_labels)
nyc_squirrels <- read_csv(file.path("data", "nyc_squirrels.csv"))central_park <- sf::read_sf(file.path("data", "central_park"))nyc_squirrels <- read_csv(file.path("data", "nyc_squirrels.csv"))central_park <- sf::read_sf(file.path("data", "central_park"))
nyc_squirrels %>% drop_na(primary_fur_color) %>% ggplot() + geom_sf(data = central_park, color = "grey85") + geom_point( aes(x = long, y = lat, color = primary_fur_color), size = .8 ) + cowplot::theme_map(16) + colorblindr::scale_color_OkabeIto(name = "primary fur color")
nyc_squirrels %>% drop_na(primary_fur_color) %>% ggplot() + geom_sf(data = central_park, color = "grey85") + geom_point( aes(x = long, y = lat, color = primary_fur_color), size = .8 ) + facet_wrap(vars(primary_fur_color)) + cowplot::theme_map(16) + theme(legend.position = "none") + colorblindr::scale_color_OkabeIto()
label_colors <- c("all squirrels" = "grey75", "highlighted group" = "#0072B2")nyc_squirrels %>% drop_na(primary_fur_color) %>% ggplot() + geom_sf(data = central_park, color = "grey85") + geom_point( data = function(x) select(x, -primary_fur_color), aes(x = long, y = lat, color = "all squirrels"), size = .8 ) + geom_point( aes(x = long, y = lat, color = "highlighted group"), size = .8 ) + cowplot::theme_map(16) + theme( legend.position = "bottom", legend.justification = "center" ) + facet_wrap(vars(primary_fur_color)) + scale_color_manual(name = NULL, values = label_colors) + guides(color = guide_legend(override.aes = list(size = 3)))





ggplot() function, add y = ..count.. to aes()geom_density() to the plot. This should go before the existing geom_density() so that it shows up in the background.geom_density(), set the data argument to be a function. This function should take a data frame and remove gender (which we're about to facet on).aes() to set color and fill. Both should equal "all participants", not gender.facet_wrap() to facet the plot by gender.diabetes %>% drop_na(glyhb, gender) %>% ggplot(aes(glyhb, y = ..count..)) + geom_density( data = function(x) select(x, -gender), aes(fill = "all participants", color = "all participants") ) + geom_density(aes(fill = gender, color = gender)) + facet_wrap(vars(gender)) + scale_x_log10(name = "glycosylated hemoglobin a1c") + scale_color_manual(name = NULL, values = density_colors) + scale_fill_manual(name = NULL, values = density_colors) + theme_minimal_hgrid(16) + theme(legend.position = "bottom", legend.justification = "center")
library(gghighlight)
gghighlight(predicate)
le_dropped, that is TRUE if life expectancy was higher in 1992. Then, we join le_dropped back to the data so we can use it in gghighlight(). Run the code at each step.legend.position argument in theme(). Take a look at the base plot.gghighlight() to add direct labels to the plot. For the first argument, tell it which lines to highlight using le_dropped. Also add the arguments use_group_by = FALSE and unhighlighted_colour = "grey90".use_direct_label = FALSE to gghighlight() and then facet the plot (using facet_wrap()) by countryle_line_plot + gghighlight( le_dropped, use_group_by = FALSE, unhighlighted_colour = "grey90" )
le_line_plot + gghighlight( le_dropped, use_group_by = FALSE, use_direct_label = FALSE, unhighlighted_colour = "grey90" ) + facet_wrap(vars(country))
dog_sighting <- nyc_squirrels %>% mutate(dog = str_detect(other_activities, "dog")) %>% filter(dog)lbl <- "All other dog sightings involved a squirrel hiding or being chased. This squirrel,however, was actively teasing a dog."dog_plot <- nyc_squirrels %>% ggplot() + geom_sf(data = central_park, color = "grey80") + geom_point(aes(x = long, y = lat), size = .8) + geom_point( data = dog_sighting, aes( x = long, y = lat, color = "squirrel interacting\nwith a dog" ), size = 1.5 )dog_plot + ggrepel::geom_label_repel( data = filter( dog_sighting, str_detect(other_activities, "teasing") ), aes(x = long, y = lat, label = lbl), nudge_x = .015, size = 3.5, lineheight = .8, segment.color = "grey70" ) + cowplot::theme_map() + theme(legend.position = c(.05, .9)) + scale_color_manual(name = NULL, values = "#FB1919")
label <- "Carus, Roman emperor from 282–283,allegedly died of a lightning strike while campaigning against the Empire of Iranians. He was succeded by his sons, Carinus, who died in battle, and Numerian, whose cause of death is unknown."lightning_plot + geom_label( data = data.frame(x = 5.8, y = 5, label = label), aes(x = x, y = y, label = label), hjust = 0, lineheight = .8, inherit.aes = FALSE, label.size = NA ) + geom_curve( data = data.frame(x = 5.6, y = 5, xend = 1.2, yend = 5), mapping = aes(x = x, y = y, xend = xend, yend = yend), colour = "grey75", size = 0.5, curvature = -0.1, arrow = arrow(length = unit(0.01, "npc"), type = "closed"), inherit.aes = FALSE )



geom_text() and geom_curve() to base_map. Give each geom the relevant data that you just named in (2).lineheight of the text geom to 0.8. Then, add arrows to the curve geom usiing the arrow() function. Give it two arguments: length = unit(0.01, "npc") and type = "closed". Run the plot.coord_sf(clip = "off") to prevent clipping the text.text_labels <- tibble::tribble( ~x, ~y, ~label, -118.90, 34.00, west_label, -118.20, 34.22, east_label)arrows <- tibble::tribble( ~x, ~y, ~xend, ~yend, -118.73, 34.035, -118.60, 34.10, -118.21, 34.195, -118.35, 34.18, -118.08, 34.185, -118.15, 34.10 )base_map + geom_text( data = text_labels, aes(x, y, label = label), hjust = 0, vjust = 0.5, lineheight = .8 ) + geom_curve( data = arrows, aes(x =x, y = y, xend = xend, yend = yend), colour = "grey75", size = 0.3, curvature = -0.1, arrow = arrow(length = unit(0.01, "npc"), type = "closed") ) + coord_sf(clip = "off")
library(patchwork)



label_frames() will help us label the frame variable better. theme_multiplot() is the theme we'll add to each plot. We'll use diabetes_complete for the plots (removing the missing values of the variables we're plotting produce the same plots as diabetes would, but it prevents ggplot2 from warning us that it's dropping the data internally). Nothing to change here!plot_a and take a look. Nothing to change here, either!plot_b don't match plot_a. Add scale_color_manual() to make the colors consistent.scale_fill_manual(). For the fill colors, we'll add a bit of transparency. Paste "B3" to the end of the colors in plot_colors. "B3" is equivalent to 70% transparency (or alpha = .7) in hex code (see this GitHub page with translations from percent to hex, but note that in R you need to put the transparency at the end of the six character hex code).tag label like the other two plots. Add one to the labs() call.legend.position to c(1, 1.25) in theme(). We wont' be able to see it in plot_c, but it will show up in the combined plot!plot_a and plot_b on top and plot_c on the bottom.plot_b <- diabetes_complete %>% ggplot( aes(fct_rev(frame), waist/hip, fill = gender, col = gender) ) + geom_boxplot( outlier.color = NA, alpha = .8, width = .5 ) + theme_multiplot() + theme(axis.title.x = element_blank()) + scale_color_manual(values = plot_colors) + scale_fill_manual(values = paste0(plot_colors, "B0")) + scale_x_discrete(labels = label_frames) + labs(tag = "B")plot_b
plot_c <- diabetes_complete %>% ggplot(aes(waist/hip, glyhb, col = gender)) + geom_point( shape = 21, col = "white", fill = "grey80", size = 2.5 ) + geom_smooth( method = "lm", formula = y ~ x, se = FALSE, size = 1.1 ) + theme_minimal(base_size = 14) + theme( legend.position = c(1, 1.25), legend.justification = c(1, 0), legend.direction = "horizontal", panel.grid.minor = element_blank() ) + facet_wrap(~fct_rev(frame), labeller = as_labeller(label_frames)) + scale_y_log10(breaks = c(3.5, 5.0, 7.0, 10.0, 14.0)) + scale_color_manual(name = "", values = plot_colors) + guides(color = guide_legend(override.aes = list(size = 5))) + labs(y = "hemoglobin a1c", tag = "C")plot_c

library(patchwork)(plot_a + plot_b) / plot_c
Keyboard shortcuts
| ↑, ←, Pg Up, k | Go to previous slide |
| ↓, →, Pg Dn, Space, j | Go to next slide |
| Home | Go to first slide |
| End | Go to last slide |
| Number + Return | Go to specific slide |
| b / m / f | Toggle blackout / mirrored / fullscreen mode |
| c | Clone slideshow |
| p | Toggle presenter mode |
| t | Restart the presentation timer |
| ?, h | Toggle this help |
| Esc | Back to slideshow |