This is our central hub! Access slides, textbook, worksheets, assignments and other resources here.
💡 Tip: press S while viewing the slides to open the speaker notes.
Schedule
When
Topic
Preparation / Worksheets / Assignments
Session 1. Tue 29/9, 15.00–18.00 GS.11
Fundamentals of DV
Read: DV ch. 1; ch. 3 Worksheet: ggplot recap
Session 2. Fri 2/10, 12.00–15.00 HvA
Exploratory viz
Worksheet: ggplotly Worksheet: working with AI, pt. 1 🚨 Sun 4/10, 23.59 Deadline Assignment 1 (individual) + Assignment 2, Part 1 (group)
Session 3. Tue 6/10, 15.00–18.00 GS.11
Explanatory viz
Worksheet: working with AI, pt. 2 Read: DV ch. 8
Session 4. Fri 9/10, 12.00–15.00 HvA
Pitches & Q&A
🚨 Sun 11/10, 23.59 Deadline Assignment 2, Part 2 (group)
Friday sessions: time to work on group project!
Bring a (charged) laptop! 💻
Session 1Tuesday, Sept. 29Fundamentals of Data Visualization
Today
What is Data Visualization?
Why visualize data?
What makes a plot good (and bad)?
Guiding principles
Data Visualization Project
Data visualization = Data thinking
There are many skills involved in producing a good data visualization:
Technical(how to use particular tools)
Design(how to make visual representations that are engaging and appeal aesthetically)
Perception(how do certain notions of visual perception and cognition affect data communication)
Data visualization = Data thinking
Most important is to be able to derive reliable information from data using visual representations.
Data visualization = Data thinking
Your data visualization is effective only if it helps you, and your audience, understand the real world better
This requires data thinking skills:
Understandingof what the data represents (and what it doesn’t)
Transparencyabout the transformations and aggregations done to the data to produce the visualization
Awarenessabout how different visual representations affect the interpretation of the data, and an ability to justify which choice is most appropriate for your data and audience
Knowledgeabout the context from which the data is taken, and later presented.
Data visualization = Data thinking
Especially in our age of AI, these skills are invaluable
Why visualize data? 👀
💬 Discussion
Why visualize data?
Communicating with the public
…or boss, or stakeholder, or client
Why visualize data?
Anscombe’s quartet
Code
library("datasauRus")library(scales)datasaurus_dozen |> ggplot2::ggplot(aes(x = x, y = y, color = dataset)) + ggplot2::geom_point() + ggplot2::theme_void() + ggplot2::geom_smooth(method ="lm",color ="gray",fill ="gray",alpha = .5 ) + ggplot2::theme(legend.position ="none", text =element_text(size =30)) + ggplot2::facet_wrap(~dataset, ncol =4)
💬 Discussion
What is more important? An eye or an algorithm?
What are the consequences of overrelying on statistical techniques? What are the consequences of overrelying on visualizations?
it contains multiple plots: show that you analysed your variable from at least 2 different perspectives.
Has a theme and color-scheme. Although not necessary for exploratory viz, this gives me a chance to give feedback on your styling choices for Part 2.
it highlights some interesting data points, for example using color or text. While this is also not necessary for exploratory viz, do this to show me the direction you will take your final visualization in, so I can give feedback.
it contains a short description outlining your workflow: what exploration choices led to this visualization? did you use AI? if so, how and with which model? what did you learn about the data and how can you use this to inform the final, explanatory data visualization?
your code runs, and the html can be downloaded and viewed on any laptop.
your code is lintr-proof.
Now
In your groups:
AI worksheet, part 1. This should help set you up for your assignment. In 30 minutes we have a short discussion about your findings
Continue with Assignment 2, part 1.
Session 3Tuesday, Oct. 6Explanatory Data Visualization
Today
Better plots 🥇
General feedback assignments
Going from exploratory to explanatory
Advanced DV features
Using AI for explanatory DVs
Feedback on Assignment 2, Part 1
Use informative titles: state your conclusion in the title or subtitle in a declarative manner
Text: Increase font size, use bold-face in main statements
Visualize reliability: show sample size, confidence intervals, etc. Especially if using bins/groupings.
What is the added value of a boxplot?
Go from exploratory to explanatory! the audience should get the main conclusion without reading the description
You can try it yourself with geom_image() from ggimage
Code
library(ggimage)# aggregate to totalspizza_totals <- pizza_season |>group_by(type) |>summarise(total =sum(n), .groups ="drop") |>mutate(n_icons =round(total /1000)) # 1 pizza = 1000 sales# expand data: one row per pizza icon# this is a trick so that each pizza icon can be plotted separately (essentially# using geom_point but appearing as a bar)chart_junk_data <- pizza_totals |>rowwise() |>mutate(icon_id =list(1:n_icons)) |>unnest(icon_id)# plot with 🍕pizza_plot <-ggplot(chart_junk_data, aes(x = icon_id, y = type)) +geom_image(aes(image ="images/pizza.png"), size =0.2) +# add white rectangle to cover up excess icons (taken from pizza_totals data)geom_rect(data = pizza_totals,aes(xmin = total /1000, xmax = total /1000+2,ymin =as.numeric(factor(type)) -0.5,ymax =as.numeric(factor(type)) +0.5 ),inherit.aes =FALSE,fill ="white" ) +labs(title ="Total Pizza Sales in 2015",x ="Sales (Scale 1:1000)",y =NULL ) +theme_minimal(base_size =14) +theme(panel.grid.minor.y =element_blank(),panel.grid.major.y =element_blank(),panel.grid.minor.x =element_blank(),axis.ticks =element_blank() )pizza_plot
Themes
Code
fig_season_2 +theme_cowplot()
Code
my_theme <-theme_cowplot() +theme(panel.grid.major =element_line(color ="gray90"),axis.ticks =element_line(color ="gray20"),axis.text =element_text(color ="gray20", face ="italic", size =16),axis.title =element_text(color ="gray20", face ="bold", size =16),plot.title =element_text(hjust =0.5, size =20, face ="bold"),plot.subtitle =element_text(hjust =0.5, size =18),legend.position ="top",legend.title =element_text(size =16, face ="bold"),legend.text =element_text(size =16) )fig_season_2 + my_theme
Facets
theme_cowplot and theme_bw() format facets nicely.
Change facet format manually with theme(strip.text = element_text(...)) and theme(strip.background = element_rect(...)).
fig_season_2 +geom_line(linetype ="solid", color ="gray30", linewidth =0.5) +facet_wrap(~type) +theme_minimal(12) +theme(legend.position ="none",strip.text =element_text(face ="bold", color ="plum4"),strip.background =element_rect(fill ="thistle2", color =NA) ) # fill for background; color for border
Combining plots: patchwork
Combine plots with +
Add a shared title, subtitle, and caption with plot_annotation()
Style them with plot_annotation(theme = theme(...))
Code
library(patchwork)p1 <-ggplot(mtcars, aes(x = hp, y = mpg)) +geom_point(color ="steelblue", size =3, alpha =0.7) +theme_minimal() +labs(title ="Fuel efficiency vs Horsepower")p2 <-ggplot(mtcars, aes(x =factor(cyl), y = mpg)) +geom_boxplot(fill ="steelblue", alpha =0.7) +theme_minimal() +labs(title ="MPG by Number of Cylinders")p1 + p2 +plot_annotation(title ="Analysis of mtcars dataset",caption ="Data source: mtcars",theme =theme(plot.title =element_text(face ="bold", size =16)) )
Color scales
Code
fig_quarter <- pizza_season |>mutate(quarter =case_when( month %in%c("Jan", "Feb", "Mar") ~"Q1", month %in%c("Apr", "May", "Jun") ~"Q2", month %in%c("Jul", "Aug", "Sep") ~"Q3", month %in%c("Oct", "Nov", "Dec") ~"Q4" )) |>ggplot(aes(x = quarter, y = n, group = type)) +geom_bar(aes(fill = type), stat ="identity", position ="dodge") +labs(title ="Pizza Season", y ="Number of pizzas sold", x ="")fig_quarter +labs(subtitle ="Qualitative color scale") +scale_fill_brewer(type ="qual")
qualitative categorical data
Code
fig_quarter +labs(subtitle ="Sequential color scale") +scale_fill_brewer(type ="seq")
sequential ordered data, from low to high
Code
fig_quarter +labs(subtitle ="Diverging color scale") +scale_fill_brewer(type ="div")
diverging ordered data with a critical midpoint, e.g. 0
Color blindness
Code
# colorblindr is installed from GitHub (clauswilke/colorblindr)colorblindr::cvd_grid(fig_quarter)
The package MetBrewer has many colorblind-friendly palettes, e.g. scale_fill_manual(values = MetBrewer::met.brewer("VanGogh3", n = 4))
Sample sizehow many schools (or students) is each group based on?
Spread:is it informative to show the distribution, or error bars / intervals, not just the mean?
Missing datahow did you handle them, and does it matter? If yes, add a note in the caption.
Confidence intervals(+ explain them in a way your audience understands.)
Putting it together
Consider your audience:
Code
pizza_plot
Putting it together
Consider your audience:
Code
sysfonts::font_add_google("Lobster")sysfonts::font_add_google("Lexend")showtext::showtext_auto()pizza_plot +# add a geom_rect element with opacity on top of pizza bars, to highlight the# biggest bargeom_rect(data = pizza_totals |>mutate(highlight =ifelse(type =="classic", TRUE, FALSE)),aes(xmin =0, xmax = total /1000,ymin =as.numeric(factor(type)) -0.5,ymax =as.numeric(factor(type)) +0.5,alpha = highlight ),inherit.aes =FALSE,fill ="white" ) +scale_alpha_manual(values =c("TRUE"=0, "FALSE"=0.3), guide ="none") +labs(title ="The classic is a classic for a reason.",subtitle ="Total Pizza Sales in 2015",caption ="Source: pizzaplace dataset" ) +theme(text =element_text(family ="Lexend", color ="gray30"),plot.title =element_text(family ="Lobster", size =20, color ="tomato3"),plot.subtitle =element_text(family ="Lexend", size =16),axis.title.x =element_text(family ="Lobster", size =16),axis.text.y =element_text(family ="Lobster", size =16, color ="tomato3") )
Putting it together
Consider your audience:
Code
max_sales <-max(pizza_totals$total)best_seller <- pizza_totals$type[pizza_totals$total == max_sales]plot_data <- pizza_totals |>mutate(is_max = total == max_sales) |>mutate(type = forcats::fct_reorder(type, total, .desc =TRUE))# the best seller is colored in the subtitle, like its bar (needs ggtext)main_conclusion <-paste0("The <span style='color:tomato3;'>", best_seller, " pizza</span> ","is the clear leader with ", scales::comma(max_sales), " units sold.")ggplot(plot_data, aes(x = type, y = total, fill = is_max)) +geom_col(width =0.7) +geom_text(aes(label = scales::comma(total)),vjust =-0.5,size =4,fontface ="bold" ) +# highlight color for the best seller, neutral gray for the restscale_fill_manual(values =c("TRUE"="tomato3", "FALSE"="grey70"),guide ="none" ) +labs(title ="Total Sales by Pizza Type",subtitle = main_conclusion,x ="Pizza Type",y ="Total Units Sold" ) +theme_cowplot() +theme(plot.title.position ="plot",plot.title =element_text(size =16, face ="bold"),plot.subtitle = ggtext::element_markdown(size =16, color ="grey30"),# the values are already on the bars, so the y-axis can goaxis.line.y =element_blank(),axis.ticks.y =element_blank(),axis.text.y =element_blank(),axis.title.y =element_blank() ) +scale_y_continuous(expand =expansion(mult =c(0, 0.15)))
Final considerations
Are all visual elements necessary? (borders, gridlines, etc.)
Are names informative and adapted to the audience?
Is text big enough and legible at all plot sizes?
Can the plot render nicely on a presentation screen?
Render it in an html or pdf file and upload it to Canvas. The draft is not graded, but the further along it is, the more useful the feedback. No slides needed!
4-5 minutes pitch research question, approach, conclusion, open questions
3-4 minutes discussion bring the questions you would like input on
AI use how did you use it, what did you learn, which obstacles or risks did you run into?
Handing in Assignment 2, Part 2
Deadline: Sunday, October 11th, 23:59
Hand in, on Canvas:
The link to your group’s (public) GitHub repository, with all your code pushed
Your report, as:
.Rmd with all code (lintr-proof!) to produce your final DV and report. (A quarto document as .qmd is also fine.)
.html compiles only the final DV and report text. Hide your code by setting code_folding = TRUE in the preamble. make sure it knits correctly; we will not compile your .Rmd for you
And make sure I can clone your Github repo and completely reproduce your results.
Handing in Assignment 2, Part 2
Grading
Aesthetics 30%
Clear and legible, no unnecessary clutter; color, labels and scales enhance readability
Communication 30%
Can the main point be understood quickly, with minimal explanation?
Description 20%
Research question, what you wanted to communicate, why this visualization, what you can conclude. AI statement
Creativity and Complexity 10%
ex. Going beyond a default chart type, where it adds value without obscuring the message; adding consistent themes and styling matching the target audience / context.