class: center, middle, inverse, title-slide # Themes ### Derek Ogle, May 2020 --- class: inverse, center, middle # Today's Goal <font size="7">Learn how to provide specific control over all elements of a plot.</font> --- # Today's Goal - Demonstrate built-in themes. -- - Demonstrate how to modify aspects of a plot with `theme()`. -- - Show how to create your own theme. -- - Demonstrate how to set a default theme for each plot. --- class: inverse, center, middle # What is a Theme? --- # What is a theme? - Aspects of the graph not directly related to data. -- - Background color. - Grid line color and type. - Label font size, type, and margin. - Legend position, orientation, and margin. - Facet label, position, and margin. - etc. --- class: inverse, center, middle # Built-in Themes --- # Built-in Themes - ggplot2 has 9 built-in themes. - `theme_gray()` (default) - `theme_bw()` - `theme_classic()` - `theme_minimal()` - `theme_dark()` - etc. -- - Other full themes are available in other packages; e.g., - `theme_half_open()` from `cowplot` package. - `theme_tufte()` from `ggthemes` package. - `theme_excel()` from `ggthemes` package. - `theme_gdocs()` from `ggthemes` package. --- <img src="Lecture_Themes_files/figure-html/unnamed-chunk-1-1.png" width="100%" /> --- # Built-in Themes - All built-in themes have four arguments. -- - `base_size=`: "base size" of fonts (default is 11). - `base_family=`: "base family" of fonts (default depends on OS). - `base_line_size=`: "base size" of lines (default is 1/22nd of `base_size=`). - `base_rect_size=`: "base size" of rectangles (default is 1/22nd of `base_size=`). -- - Probably only ever change `base_size=` and `base_family=`. --- class: split-50 count: false .column[.content[ ```r p ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/bases_non_seq_1_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r p + * theme_bw( ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/bases_non_seq_2_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r p + theme_bw( * base_size=18, ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/bases_non_seq_3_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r p + theme_bw( base_size=18, * base_family="serif", ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/bases_non_seq_4_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r p + theme_bw( base_size=18, base_family="serif", * base_rect_size=18/11 ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/bases_non_seq_5_output-1.png" width="100%" /> ]] --- class: inverse, center, middle # Controlling Specific Aspects of a Theme --- # Theme Elements - Each theme is made up of many *elements*, organized into groups. -- - **Plot Elements**: effect the whole plot (e.g., title). - **Axis Elements**: effect the plot axes (e.g., ticks). - **Legend Elements**: effect legends (e.g., margin). - **Panel Elements**: effect plotting panels (e.g., gridlines). - **Facet Elements**: effect facets (e.g., "strip" color). -- - Elements are set using "element" or "setter" functions. --- # Element (or Setter) Functions - `element_text()`: Draws labels and headings. -- - Can control font `family=`, `face=` (e.g., bold and italic), `color=`, and `size=`; `hjust=`, `vjust=`, `angle=` (in degrees), `lineheight=`, and `margin=`. -- - `element_line()`: Draws lines. -- - Can control line `color=`, `size=`, and `linetype=`. -- - `element_rect()`: Draws rectangles (mostly used for backgrounds). -- - Can control `fill=`, `color=`, `size=`, and `linetype=`. --- # Element (or Setter) Functions - `element_blank()`: Draws nothing AND allocates no space to that object. -- - `margin()`: Sets margins around items. -- - Uses `t=` (top), `r=` (right), `b=` (bottom), `l=` (left). - Can set units with `unit=` (defaults to `pt`). <br> -- - `unit()`: Sets spacing or size. -- - Value in first argument. - Type of units in `units=` or second argument ... can be `"in"`, `"mm"`, `"cm"`, `"points"`, etc. -- - Which element/setter function to use depends on the theme element. --- # Plot Elements Element | Setter | Notes -------------------|------------------|------------ `plot.background=` | `element_rect()` | background of entire plot area `plot.title=` | `element_text()` | `plot.margin=` | `margin()` | margins around plot --- class: split-50 count: false .column[.content[ ```r pb ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_plots_non_seq_1_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + * theme( * plot.background=element_rect(fill="linen",color="blue"), ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_plots_non_seq_2_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + theme( plot.background=element_rect(fill="linen",color="blue"), * plot.title=element_text(color="red",face="bold",size=24), ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_plots_non_seq_3_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + theme( plot.background=element_rect(fill="linen",color="blue"), plot.title=element_text(color="red",face="bold",size=24), * plot.margin=margin(b=1.5,r=1,unit="cm") ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_plots_non_seq_4_output-1.png" width="100%" /> ]] --- # Axis Elements Element | Setter | Notes ---------------------|------------------|--------------------------- `axis.line=` | `element_line()` | line parallel to axis (may be hidden by `panel.border=`) `axis.text=` | `element_text()` | tick labels (all) `axis.text.x=` | `element_text()` | tick labels (x-axis) `axis.text.y=` | `element_text()` | tick labels (y-axis) `axis.title=` | `element_text()` | label for axis (all) `axis.title.x=` | `element_text()` | label for axis (x-axis) `axis.title.y=` | `element_text()` | label for axis (y-axis) `axis.ticks=` | `element_line()` | axis tick marks `axis.ticks.length=` | `unit()` | axis tick mark lengths --- class: split-50 count: false .column[.content[ ```r pb ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_axis_non_seq_1_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + * theme( * axis.text=element_text(color="blue",size=14), ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_axis_non_seq_2_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + theme( axis.text=element_text(color="blue",size=14), * axis.title.x=element_text(color="red",face="bold",size=24), ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_axis_non_seq_3_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + theme( axis.text=element_text(color="blue",size=14), axis.title.x=element_text(color="red",face="bold",size=24), * axis.title.y=element_text(color="green3",face="bold",size=36), ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_axis_non_seq_4_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + theme( axis.text=element_text(color="blue",size=14), axis.title.x=element_text(color="red",face="bold",size=24), axis.title.y=element_text(color="green3",face="bold",size=36), * axis.ticks.length=unit(5,unit="mm") ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_axis_non_seq_5_output-1.png" width="100%" /> ]] --- # Panel Elements Element | Setter | Description ----------------------|------------------|------------------------------- `panel.background=` | `element_rect()` | panel background (under data) `panel.border=` | `element_rect()` | panel border (over data) `panel.grid.major=` | `element_line()` | major grid lines `panel.grid.major.x=` | `element_line()` | major grid lines (x-axis; vertical) `panel.grid.major.y=` | `element_line()` | major grid lines (y-axis; horizontal) `panel.grid.minor=` | `element_line()` | minor grid lines `panel.grid.minor.x=` | `element_line()` | minor grid lines (x-axis; vertical) `panel.grid.minor.y=` | `element_line()` | minor grid lines (y-axis; horizontal) `aspect.ratio=` | numeric | width:height ratio (of panel only) --- class: split-50 count: false .column[.content[ ```r pb ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_panels_non_seq_1_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + * theme( * panel.background=element_rect(fill="orange"), ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_panels_non_seq_2_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + theme( panel.background=element_rect(fill="orange"), * panel.grid.major=element_line(color="gray30",linetype="dashed"), ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_panels_non_seq_3_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + theme( panel.background=element_rect(fill="orange"), panel.grid.major=element_line(color="gray30",linetype="dashed"), * panel.grid.minor.x=element_line(color="gray70",size=0.5), ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_panels_non_seq_4_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + theme( panel.background=element_rect(fill="orange"), panel.grid.major=element_line(color="gray30",linetype="dashed"), panel.grid.minor.x=element_line(color="gray70",size=0.5), * panel.grid.minor.y=element_line(color="steelblue",size=0.5), ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_panels_non_seq_5_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + theme( panel.background=element_rect(fill="orange"), panel.grid.major=element_line(color="gray30",linetype="dashed"), panel.grid.minor.x=element_line(color="gray70",size=0.5), panel.grid.minor.y=element_line(color="steelblue",size=0.5), * panel.border=element_rect( * color="red",size=2, ) * ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_panels_non_seq_6_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + theme( panel.background=element_rect(fill="orange"), panel.grid.major=element_line(color="gray30",linetype="dashed"), panel.grid.minor.x=element_line(color="gray70",size=0.5), panel.grid.minor.y=element_line(color="steelblue",size=0.5), panel.border=element_rect( color="red",size=2, * fill="black" ) ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_panels_non_seq_7_output-1.png" width="100%" /> ]] --- # Legend Elements Element | Setter | Description ----------------------|------------------|------------------------------- `legend.background=` | `element_rect()` | background of entire legend `legend.key=` | `element_rect()` | background of legend keys `legend.key.size=` | `unit()` | `legend.key.height=` | `unit()` | `legend.key.width=` | `unit()` | `legend.margin=` | `unit()` | margin within legend `legend.text=` | `element_text()` | labels within legend `legend.text.align=` | 0-1 | 0=right, 1=left `legend.title=` | `element_text()` | legend name `legend.title.align=` | 0-1 | 0=right, 1=left --- class: split-50 count: false .column[.content[ ```r pb ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_legends1_non_seq_1_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + * theme( * legend.background=element_rect(fill="orange"), ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_legends1_non_seq_2_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + theme( legend.background=element_rect(fill="orange"), * legend.text=element_text(color="blue",size=18), ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_legends1_non_seq_3_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + theme( legend.background=element_rect(fill="orange"), legend.text=element_text(color="blue",size=18), * legend.title=element_text(color="red",size=24), ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_legends1_non_seq_4_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + theme( legend.background=element_rect(fill="orange"), legend.text=element_text(color="blue",size=18), legend.title=element_text(color="red",size=24), * legend.key=element_rect(fill="yellow",color="black"), ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_legends1_non_seq_5_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + theme( legend.background=element_rect(fill="orange"), legend.text=element_text(color="blue",size=18), legend.title=element_text(color="red",size=24), legend.key=element_rect(fill="yellow",color="black"), * legend.key.size=unit(2,"mm") ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_legends1_non_seq_6_output-1.png" width="100%" /> ]] --- # Legend Elements (Positioning) - Legend positioned with `legend.position=`. -- - Outside of panel region ... use `right` (default), `top`, `left`, or `bottom`. -- - Inside of panel region ... use `c(#,#)` ... with lower-left being `c(0,0)` and upper-right being `c(1,1)`. -- - Set "anchor point" of legend with `legend.justification=c(#,#)`. -- - Use in conjunction with `legend.position=c(#,#)`. - Values have same meaning ... lower-left is `c(0,0)`, upper-right is `c(1,1)`. --- <img src="Lecture_Themes_files/figure-html/demo_legends2-1.png" width="95%" /> --- # Facet Elements Element | Setter | Notes --------------------|------------------|------------------------------------ `strip.background=` | `element_rect()` | `strip.text=` | `element_text()` | `strip.text.x=` | `element_text()` | horizontal strip text `strip.text.y=` | `element_text()` | vertical strip text (only w/ `facet_grid()`) `panel.spacing=` | `unit()` | all margins between panels `panel.spacing.x=` | `unit()` | vertical margin between panels `panel.spacing.y=` | `unit()` | horizontal margin between panels --- class: split-50 count: false .column[.content[ ```r pb ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_facets_non_seq_1_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + * facet_wrap(vars(grp)) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_facets_non_seq_2_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + facet_wrap(vars(grp)) + * theme( * legend.position="none", ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_facets_non_seq_3_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + facet_wrap(vars(grp)) + theme( legend.position="none", * strip.background=element_rect(fill="black",color="gray50"), ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_facets_non_seq_4_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + facet_wrap(vars(grp)) + theme( legend.position="none", strip.background=element_rect(fill="black",color="gray50"), * strip.text=element_text( * color="white",face="italic",size=18, ), * ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_facets_non_seq_5_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + facet_wrap(vars(grp)) + theme( legend.position="none", strip.background=element_rect(fill="black",color="gray50"), strip.text=element_text( color="white",face="italic",size=18, * margin=margin(t=2,b=2,r=2,l=2) ), ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_facets_non_seq_6_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + facet_wrap(vars(grp)) + theme( legend.position="none", strip.background=element_rect(fill="black",color="gray50"), strip.text=element_text( color="white",face="italic",size=18, margin=margin(t=2,b=2,r=2,l=2) ), * panel.spacing=unit(0,unit="mm") ) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/demo_facets_non_seq_7_output-1.png" width="100%" /> ]] --- class: inverse, center, middle # Some Help for Remembering All of This --- .center[ <img src="https://derekogle.com/NCGraphing/modules/zimgs/theme_elements.png" width="99%" /> ] --- class: inverse, center, middle # Creating Your Own Theme --- # Creating Your Own Theme - Start with an existing theme. - i.e., it has most of what you want. -- - Add `theme()` to it with the modifications that you want. -- - Assign to an object. -- - Add this object to a plot when you want to use it. --- # Creating Your Own Theme ```r theme_DHO <- theme_bw() + theme( plot.title=element_text(face="bold",size=rel(1.5)), axis.title=element_text(face="bold",size=rel(1.25)), panel.grid.major=element_line(color="gray90",linetype="dashed",size=rel(0.25)), panel.grid.minor=element_blank(), legend.margin=margin(t=1,r=1,b=1,l=1,unit="mm"), legend.key.size=unit(2,units="mm"), panel.spacing=unit(1,unit="mm"), strip.background=element_rect(fill="black",color="black"), strip.text=element_text(color="white",face="bold",size=rel(1.5),margin=margin(t=1,b=1,r=1,l=1,unit="mm")) ) ``` --- class: split-50 count: false .column[.content[ ```r *pb ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/DHO1_auto_1_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + * theme_DHO ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/DHO1_auto_2_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r *pb ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/DHO2_auto_1_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + * facet_wrap(vars(grp)) ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/DHO2_auto_2_output-1.png" width="100%" /> ]] --- class: split-50 count: false .column[.content[ ```r pb + facet_wrap(vars(grp)) + * theme_DHO ``` ]] .column[.content[ <img src="Lecture_Themes_files/figure-html/DHO2_auto_3_output-1.png" width="100%" /> ]] --- class: inverse, center, middle # Setting a Theme for all Plots --- # Setting a Theme for all Plots - It is irritating to always do `theme_bw()` or `theme_DHO`. -- - You can set a default theme at the beginning of your session with `theme_set()`, with the name of the theme as the first argument. -- - e.g., `theme_set(theme_BW())` - e.g., `theme_set(theme_DHO)` --- class: inverse, center, middle # Next Time <font size="7">We will have guest speakers demonstrate case studies.</font>