class: center, middle, inverse, title-slide .title[ # Styling ] .author[ ### Visualizing and communicating data with R
The R Bootcamp @ Unibas
] .date[ ### November 2023 ] --- layout: true <div class="my-footer"> <span style="text-align:center"> <span> <img src="https://raw.githubusercontent.com/therbootcamp/therbootcamp.github.io/master/_sessions/_image/by-sa.png" height=14 style="vertical-align: middle"/> </span> <a href="https://therbootcamp.github.io/"> <span style="padding-left:82px"> <font color="#7E7E7E"> https://therbootcamp.github.io </font> </span> </a> <a href="https://therbootcamp.github.io/"> <font color="#7E7E7E"> The R Bootcamp | November 2023 </font> </a> </span> </div> --- .pull-left45[ # Styling plots <ul> <li class="m1"><span>Save plot as <highm>gg</highm> object.</span></li> <li class="m2"><span>Use existing <highm>theme_*()</highm> presets.</span></li> <li class="m3"><span>Customize details using <highm>theme()</highm>.</span></li> <li class="m4"><span>Adjust dimensions using <highm>scale_*()</highm>.</span></li> <li class="m5"><span>Add an notion using <highm>labs()</highm>.</span></li> <li class="m6"><span>Write your plot as a <highm>.pdf</highm> or <highm>.png</highm>.</span></li> </ul> ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-2-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # The <mono>gg</mono> object <ul> <li class="m1"><span>The output of <mono>ggplot()</mono> can be stored in an <mono>gg</mono> object.</span></li> <li class="m2"><span>The <mono>gg</mono> object can be expanded using <mono>+</mono> and the plot can be generated by a simple print.</span></li> </ul> <br> ```r # store plot as object my_plot <- ggplot(basel, aes(x = year, y = income_median, col = quarter)) + geom_line() + geom_point() ``` ] .pull-right45[ <br> ```r my_plot ``` <img src="styling_files/figure-html/unnamed-chunk-4-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # `theme_*()` <ul> <li class="m1"><span>Using <mono>theme_*()</mono> the plot can be styled according to various presets.</span></li> <li class="m2"><span>A few <mono>theme</mono>s: <br><br> <ul class="level"> <li><span><mono>theme_gray()</mono></span></li> <li><span><mono>theme_classic()</mono></span></li> <li><span><mono>theme_void()</mono></span></li> <li><span><mono>theme_minimal()</mono></span></li> <li><span><mono>theme_excel() (<mono>ggthemes</mono>)</mono></span></li> <li><span><mono>theme_economist() (<mono>ggthemes</mono>)</mono></span></li> </ul> </span></li> </ul> ] .pull-right45[ <br> ```r my_plot + theme_classic() ``` <img src="styling_files/figure-html/unnamed-chunk-5-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # `theme_*()` <ul> <li class="m1"><span>Using <mono>theme_*()</mono> the plot can be styled according to various presets.</span></li> <li class="m2"><span>A few <mono>theme</mono>s: <br><br> <ul class="level"> <li><span><mono>theme_gray()</mono></span></li> <li><span><mono>theme_classic()</mono></span></li> <li><span><mono>theme_void()</mono></span></li> <li><span><mono>theme_minimal()</mono></span></li> <li><span><mono>theme_excel() (<mono>ggthemes</mono>)</mono></span></li> <li><span><mono>theme_economist() (<mono>ggthemes</mono>)</mono></span></li> </ul> </span></li> </ul> ] .pull-right45[ <br> ```r my_plot + theme_excel() ``` <img src="styling_files/figure-html/unnamed-chunk-6-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # `theme_*()` <ul> <li class="m1"><span>Using <mono>theme_*()</mono> the plot can be styled according to various presets.</span></li> <li class="m2"><span>A few <mono>theme</mono>s: <br><br> <ul class="level"> <li><span><mono>theme_gray()</mono></span></li> <li><span><mono>theme_classic()</mono></span></li> <li><span><mono>theme_void()</mono></span></li> <li><span><mono>theme_minimal()</mono></span></li> <li><span><mono>theme_excel() (<mono>ggthemes</mono>)</mono></span></li> <li><span><mono>theme_economist() (<mono>ggthemes</mono>)</mono></span></li> </ul> </span></li> </ul> ] .pull-right45[ <br> ```r my_plot + theme_economist() ``` <img src="styling_files/figure-html/unnamed-chunk-7-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # `theme_*()` <ul> <li class="m1"><span>Using <mono>theme_*()</mono> the plot can be styled according to various presets.</span></li> <li class="m2"><span>A few <mono>theme</mono>s: <br><br> <ul class="level"> <li><span><mono>theme_gray()</mono></span></li> <li><span><mono>theme_classic()</mono></span></li> <li><span><mono>theme_void()</mono></span></li> <li><span><mono>theme_minimal()</mono></span></li> <li><span><mono>theme_excel() (<mono>ggthemes</mono>)</mono></span></li> <li><span><mono>theme_economist() (<mono>ggthemes</mono>)</mono></span></li> </ul> </span></li> </ul> ] .pull-right45[ <br> ```r my_plot + theme_wsj() ``` <img src="styling_files/figure-html/unnamed-chunk-8-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # `theme_*()` <ul> <li class="m1"><span>Using <mono>theme_*()</mono> the plot can be styled according to various presets.</span></li> <li class="m2"><span>A few <mono>theme</mono>s: <br><br> <ul class="level"> <li><span><mono>theme_gray()</mono></span></li> <li><span><mono>theme_classic()</mono></span></li> <li><span><mono>theme_void()</mono></span></li> <li><span><mono>theme_minimal()</mono></span></li> <li><span><mono>theme_excel() (<mono>ggthemes</mono>)</mono></span></li> <li><span><mono>theme_economist() (<mono>ggthemes</mono>)</mono></span></li> </ul> </span></li> </ul> ] .pull-right45[ <br> ```r my_plot + theme_minimal() ``` <img src="styling_files/figure-html/unnamed-chunk-9-1.png" style="display: block; margin: auto;" /> ] --- # `theme()` .pull-left45[ <ul> <li class="m1"><span>With <high>96 arguments</high> <mono>theme()</mono> permits specification of all aesthetic details.</span></li> <li class="m2"><span>Makes uses of helper functions:</span></li> <ul class="level"> <li><span><mono>element_rect()</mono> | for rectangles</span></li> <li><span><mono>element_line()</mono> | for lines</span></li> <li><span><mono>element_text()</mono> | for text</span></li> <li><span><mono>element_blank()</mono> | for removals</span></li> </ul> </ul> <br> ```r # Using theme my_plot + theme(argument = element_*(), argument = element_*(), ...) ``` ] .pull-right45[ <p align="center"> <img src="image/theme.png"> </p> ] --- .pull-left45[ # `theme()` <ul> <li class="m1"><span>With <high>96 arguments</high> <mono>theme()</mono> permits specification of all aesthetic details.</span></li> <li class="m2"><span>Makes uses of helper functions:</span></li> <ul class="level"> <li><span><mono>element_rect()</mono> | for rectangles</span></li> <li><span><mono>element_line()</mono> | for lines</span></li> <li><span><mono>element_text()</mono> | for text</span></li> <li><span><mono>element_blank()</mono> | for removals</span></li> </ul> </ul> <br> ```r # Fixing the legend my_plot + theme_minimal() + # move legend to bottom theme(legend.position = "bottom") ``` ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-12-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # `theme()` <ul> <li class="m1"><span>With <high>96 arguments</high> <mono>theme()</mono> permits specification of all aesthetic details.</span></li> <li class="m2"><span>Makes uses of helper functions:</span></li> <ul class="level"> <li><span><mono>element_rect()</mono> | for rectangles</span></li> <li><span><mono>element_line()</mono> | for lines</span></li> <li><span><mono>element_text()</mono> | for text</span></li> <li><span><mono>element_blank()</mono> | for removals</span></li> </ul> </ul> <br> ```r # Fixing the legend my_plot + theme_minimal() + theme(legend.position = "bottom", # remove legend title legend.title = element_blank()) ``` ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-14-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # `theme()` <ul> <li class="m1"><span>With <high>87 arguments</high> <mono>theme()</mono> permits specification of all aesthetic details.</span></li> <li class="m2"><span>Makes uses of helper functions:</span></li> <ul class="level"> <li><span><mono>element_rect()</mono> | for rectangles</span></li> <li><span><mono>element_line()</mono> | for lines</span></li> <li><span><mono>element_text()</mono> | for text</span></li> <li><span><mono>element_blank()</mono> | for removals</span></li> </ul> </ul> <br> ```r # Fixing the legend my_plot + theme_minimal() + theme( legend.position = "bottom", legend.title = element_blank(), # reduce legend text size legend.text = element_text(size = 7)) ``` ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-16-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # `theme` <ul> <li class="m1"><span><mono>theme</mono>s can be stored in an object.</span></li> <li class="m2"><span><mono>theme</mono> objects are not functions.</span></li> </ul> <br> ```r # save my theme my_theme <- theme( legend.position = "bottom", legend.title = element_blank(), legend.text = element_text(size = 7)) # Add my theme my_plot + theme_minimal() + my_theme ``` ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-18-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # `scale_*()` <ul> <li class="m1"><span>Various <mono>scale_*()</mono> permit specification of all <high>dimensions</high>, including axes, colors, sizes, etc.</span></li> <li class="m2"><span>Groups of <mono>scale_*()</mono> functions:</span></li> <ul class="level"> <li><span><mono>scale_xy_*</mono> | Scales axes</span></li> <li><span><mono>scale_color_*</mono> | Scales colors</span></li> <li><span><mono>scale_size_*</mono> | Scales sizes</span></li> <li><span><mono>scale_alpha_*</mono> | Scales opacity</span></li> </ul> </ul> ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-19-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # `scale_*()` <ul> <li class="m1"><span>Various <mono>scale_*()</mono> permit specification of all <high>dimensions</high>, including axes, colors, sizes, etc.</span></li> </ul> ```r # Fixing the legend my_plot + theme_minimal() + theme( legend.position = "bottom", legend.title = element_blank(), legend.text = element_text(size=7)) + # color using viridis scale_color_viridis_d() ``` ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-21-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # Wrangling <ul> <li class="m1"><span>Again, wrangling can help with plotting.</span></li> <li class="m2"><span>The order of discrete variables can be controlled using <highm>factors</highm>.</span></li> </ul> ```r # change data basel_order <- basel %>% # factor ordered by income in 2001 arrange(year, income_median) %>% mutate(quarter = as_factor(quarter)) # show data basel_order ``` ] .pull-right45[ <br><br><br> ``` # A tibble: 357 × 10 year quarter quarter_no N <dbl> <fct> <dbl> <dbl> 1 2001 Altstadt Klei… 12 1659 2 2001 Clara 13 2416 3 2001 Matthäus 17 9089 4 2001 Rosental 16 2499 5 2001 Klybeck 18 4053 6 2001 St. Johann 11 10493 7 2001 Kleinhüningen 19 1363 8 2001 Iselin 10 9853 9 2001 Gundeldingen 6 11224 10 2001 Breite 4 5433 # ℹ 347 more rows # ℹ 6 more variables: # income_mean <dbl>, # income_median <dbl>, # income_gini <dbl>, # wealth_mean <dbl>, # wealth_median <dbl>, … ``` ] --- .pull-left45[ # Wrangling <ul> <li class="m1"><span>Colors are assigned according to the <high>order of factor levels</high>.</span></li> </ul> ```r basel_order %>% # original code ggplot(aes(x = year, y = income_median, col = quarter)) + geom_line() + geom_point() + theme_minimal() + theme( legend.position = "bottom", legend.title = element_blank(), legend.text = element_text(size=7)) + # ordered implicitly scale_color_viridis_d() ``` ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-26-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # <mono>viridis</mono> <ul> <li class="m1"><span><mono>viridis</mono> includes several preset color sets that can <high>useful for different scenarios</high>.</span></li> </ul> ```r basel_order %>% # original code ggplot(aes(x = year, y = income_median, col = quarter)) + geom_line() + geom_point() + theme_minimal() + theme( legend.position = "bottom", legend.title = element_blank(), legend.text = element_text(size=7)) + # palette: Magma scale_color_viridis_d(option = "A") ``` ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-28-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # <mono>viridis</mono> <ul> <li class="m1"><span><mono>viridis</mono> includes several preset color sets that can <high>useful for different scenarios</high>.</span></li> </ul> ```r basel_order %>% # original code ggplot(aes(x = year, y = income_median, col = quarter)) + geom_line() + geom_point() + theme_minimal() + theme( legend.position = "bottom", legend.title = element_blank(), legend.text = element_text(size=7)) + # palette: Inferno scale_color_viridis_d(option = "B") ``` ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-30-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # <mono>viridis</mono> <ul> <li class="m1"><span><mono>viridis</mono> includes several preset color sets that can <high>useful for different scenarios</high>.</span></li> </ul> ```r basel_order %>% # original code ggplot(aes(x = year, y = income_median, col = quarter)) + geom_line() + geom_point() + theme_minimal() + theme( legend.position = "bottom", legend.title = element_blank(), legend.text = element_text(size=7)) + # palette: Plasma scale_color_viridis_d(option = "C") ``` ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-32-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # <mono>viridis</mono> <ul> <li class="m1"><span><mono>viridis</mono> includes several preset color sets that can <high>useful for different scenarios</high>.</span></li> </ul> ```r basel_order %>% # original code ggplot(aes(x = year, y = income_median, col = quarter)) + geom_line() + geom_point() + theme_minimal() + theme( legend.position = "bottom", legend.title = element_blank(), legend.text = element_text(size=7)) + # palette: Cividis scale_color_viridis_d(option = "E") ``` ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-34-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # <mono>viridis</mono> <ul> <li class="m1"><span><mono>viridis</mono> includes several preset color sets that can <high>useful for different scenarios</high>.</span></li> </ul> ```r basel_order %>% # original code ggplot(aes(x = year, y = income_median, col = quarter)) + geom_line() + geom_point() + theme_minimal() + theme( legend.position = "bottom", legend.title = element_blank(), legend.text = element_text(size=7)) + # palette: Viridis default scale_color_viridis_d(option = "D") ``` ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-36-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # `labs()` <ul> <li class="m1"><span>Various annotations can be added using <mono>labs()</mono>.</span></li> <li class="m2"><span>Key arguments:</span></li> <ul class="level"> <li><span><mono>x,y</mono> | Axes</span></li> <li><span><mono>title, subtitle</mono> | Title and Subtitle</high></span></li> <li><span><mono>caption</mono> | Caption</high></span></li> </ul> </ul> <br> ```r my_plot + labs(x = "Year", y = "Median income", title = "Inequality in Basel", subtitle = "Income development...", caption = "Source: Open Data...") ``` ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-39-1.png" style="display: block; margin: auto;" /> ] --- # Aggregates .pull-left45[ <ul> <li class="m1"><span>To visualize aggregates and error, first generate them using <highm>dplyr</highm>.</span></li> </ul> ```r basel_agg <- basel %>% # get income mean in 2001 arrange(year, quarter) %>% group_by(quarter) %>% mutate(inc01 = first(income_med.)) %>% # group by year and quarter group_by(year, hi = inc01 > median(inc01)) %>% summarize(income = mean(income_med.)) %>% # remove grouping ungroup() # show data basel_agg ``` ] .pull-right45[ ``` # A tibble: 34 × 3 year hi income <dbl> <lgl> <dbl> 1 2001 FALSE 43813 2 2001 TRUE 55790. 3 2002 FALSE 44467. 4 2002 TRUE 56225 5 2003 FALSE 43926. 6 2003 TRUE 56088. 7 2004 FALSE 43518. 8 2004 TRUE 56011 9 2005 FALSE 43028. 10 2005 TRUE 55973. # ℹ 24 more rows ``` ] --- .pull-left45[ # Aggregates <ul> <li class="m1"><span>To visualize aggregates and error, first generate them using <highm>dplyr</highm>.</span></li> </ul> ```r basel_agg %>% # plot code ggplot(aes(x = year, y = income, col = hi)) + geom_line() + geom_point() + theme_minimal() + theme(legend.position = "none") + scale_color_viridis_d() ``` ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-44-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # Error <ul> <li class="m1"><span>To visualize aggregates and error, first generate them using <highm>dplyr</highm>.</span></li> </ul> ```r # confidence interval function ci = function(x) { n = length(x) sd(x) / sqrt(n) * qt(.975, n-1)} # new data with error basel_agg <- basel %>% # get income mean in 2001 arrange(year, quarter) %>% group_by(quarter) %>% mutate(inc01 = first(income_median)) %>% # group by year and quarter group_by(year, hi = inc01 > median(inc01)) %>% summarize(inc_m = mean(income_median), inc_ci = ci(income_median)) ``` ] .pull-right45[ <br><br><br><br> ``` # A tibble: 34 × 4 year hi inc_m inc_ci <dbl> <lgl> <dbl> <dbl> 1 2001 FALSE 43813 1747. 2 2001 TRUE 55790. 4435. 3 2002 FALSE 44467. 1673. 4 2002 TRUE 56225 4309. 5 2003 FALSE 43926. 1922. 6 2003 TRUE 56088. 4311. 7 2004 FALSE 43518. 1853. 8 2004 TRUE 56011 4658. 9 2005 FALSE 43028. 2176. 10 2005 TRUE 55973. 4549. # ℹ 24 more rows ``` ] --- .pull-left45[ # <mono>geom_errorbar()</mono> <ul> <li class="m1"><span><mono>geom_errorbar()</mono> can be used to visualize <high>standard statistical error bars</high>.</span></li> </ul> ```r basel_agg %>% # plot code ggplot(aes(x = year, y = income, col = hi, fill = hi)) + # error bar geom inserted geom_errorbar(aes(ymin = inc_m - inc_ci, ymax = inc_m + inc_ci)) + ... ``` ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-49-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # <mono>geom_ribbon()</mono> <ul> <li class="m1"><span><mono>geom_ribbon()</mono> can be a replacement for <high>standard statistical error bars</high> for line charts.</span></li> </ul> ```r basel_agg %>% # plot code ggplot(aes(x = year, y = inc_m, col = hi, fill = hi)) + # ribbon geom inserted geom_ribbon(aes(ymin = inc_m - inc_ci, ymax = inc_m + inc_ci), alpha = .2) + ... ``` ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-51-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # Labels and annotations <ul> <li class="m1"><span><mono>labs()</mono> allow for the addition of titles, subtitles, axis labels and captions.</span></li> <li class="m2"><span>Within a canvas <mono>annotation()</mono> adds further elements to a plot.</span></li> </ul> ```r basel_agg %>% # plot code ggplot(aes(x = year, y = inc_m, col = hi, fill = hi)) + # ribbon geom inserted geom_ribbon(aes(ymin = inc_m - inc_ci, ymax = inc_m + inc_ci), alpha = .2) + # annotation labs(title = "Inequality in Basel", subtitle = "Difference between...", x = "Year", y = "Income") + ... ``` ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-53-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # <mono>annotations()</mono> <ul> <li class="m1"><span><mono>annotate()</mono> can be used to <high>add any type of plot elements</high> (layers) using vector specification.</span></li> </ul> ```r basel_agg %>% # plot code ggplot(aes(x = year, y = inc_m, col = hi)) + # annotate annotate('line', x = 2008, y = c(37500,62500)) + annotate('text', x = 2010, y = 63000, label = 'Financial crisis', fontface = "italic") + ... ``` ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-55-1.png" style="display: block; margin: auto;" /> ] --- .pull-left45[ # <mono>annotations()</mono> <ul> <li class="m1"><span><mono>annotate()</mono> can be used to <high>add any type of plot elements</high> (layers) using vector specification.</span></li> </ul> ```r basel_agg %>% # plot code ggplot(aes(x = year, y = inc_m, col = hi)) + # annotate annotate("rect", alpha = .1, xmin = 2007, xmax = 2009, ymin = 41000, ymax = 60000)+ annotate('text', x = 2010, y = 63000, label = 'Financial crisis', fontface = "italic") + ... ``` ] .pull-right45[ <br> <img src="styling_files/figure-html/unnamed-chunk-57-1.png" style="display: block; margin: auto;" /> ] --- # `ggsave()` .pull-left45[ <ul> <li class="m1"><span>Saves plots to the hard drive.</span></li> <li class="m2"><span>Key arguments:</span></li> <ul class="level"> <li><span><mono>file name</mono> | File name/path</span></li> <li><span><mono>device</mono> | e.g., <mono>".pdf"</mono> or <mono>".png"</mono></span></li> <li><span><mono>path</mono> | Path to folder</span></li> <li><span><mono>height, width</mono> | Height, Width</span></li> <li><span><mono>unit</mono> | Unit for Height, Width</span></li> <li><span><mono>dpi</mono> | Resolution</span></li> </ul> </ul> ] .pull-right45[ ```r # Save as pdf ggsave(filename = "my_plot.pdf", plot = my_plot, device = "pdf", path = "3_Figures", width = 7, height = 7) # Save as png ggsave(filename = "my_plot.png", plot = my_plot, device = "png", path = "3_Figures", width = 7, height = 7) ``` ] --- class: middle, center <h1><a href="">Practical</a></h1>