Helpful resources for plotting:

Cookbook for R: http://www.cookbook-r.com/Graphs/

R color names: http://www.stat.columbia.edu/~tzheng/files/Rcolor.pdf

Viz Palette: https://projects.susielu.com/viz-palette

Super intense ggplot tutorial (WAY beyond the basics): https://www.cedricscherer.com/2019/08/05/a-ggplot2-tutorial-for-beautiful-plotting-in-r/

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.2     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.2     ✔ tidyr     1.3.0
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

data

data <- read_csv("/Users/jackcavanaugh/Desktop/Lab 07 - Data Viz/Filbert___Flynn_2010.csv")
## Rows: 97 Columns: 8
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (8): Gender, Age, CumulRisk, CultAsset, DevAsset, ProSoc, GenSelfEst, Be...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

part 1 - making basic ggplots pretty

titles and labels

# let's make a basic scatterplot using ggplot's default settings

ggplot(data, aes(x=ProSoc, y=GenSelfEst)) +
  geom_point()

# now let's add a title and axis labels
ggplot(data, aes(x=ProSoc, y=GenSelfEst)) +
  geom_point() +
  labs(title="Prosocial Behavior and Self Esteem in Early Adolescents", x="Prosocial Behavior", y="General Self Esteem")

# looks great! let's save this as an object so that we can edit it without re-writing all of the code again later

scatterplot <- ggplot(data, aes(x=ProSoc, y=GenSelfEst)) +
  geom_point() +
  labs(title="Prosocial Behavior and Self Esteem in Early Adolescents", x="Prosocial Behavior", y="General Self Esteem")

themes

pre-set themes

There are a handful of pre-set theme options available that you can use as starting points.

scatterplot + theme_bw() # a simple black-and-white theme

scatterplot + theme_classic() # an even more minimalist theme

### adjusting the theme

scatterplot # let's remind ourselves what we're starting with

scatterplot + theme(panel.background = element_rect(fill="lightblue"))

scatterplot + theme(panel.background = element_rect(fill="white", color="red")) # in ggplot, remember that "fill" sets the fill color and "color" sets the OUTLINE color of a shape

scatterplot + theme(panel.grid.minor = element_blank()) # removes the "minor" grid lines, which were spaced on the 0.5 marks in the original scatterplot

using color

# let's use the same scatterplot code, but add color to the aes() function
scatterplot2 <- ggplot(data, aes(x=ProSoc, y=GenSelfEst, color=factor(Gender))) +
  geom_point() +
  labs(title="Prosocial Behavior and Self Esteem in Early Adolescents", x="Prosocial Behavior", y="General Self Esteem") +
  theme_classic()
#aes, vary based on specific data and variables, so in this example the color points will vary based on gender
scatterplot2 # hmm. ggplot is treating gender as a continuous variable. let's fix that.

data$Gender <- as.factor(data$Gender)

scatterplot2 # much better! but let's give the genders descriptive labels. let's say we want to change the labels in the plot WITHOUT editing the values in the data.

scatterplot2 + scale_color_discrete(labels=c("0"="Girls","1"="Boys"))

# what if you want to select your own colors?
my_gender_colors <- c("violet","darkblue")

scatterplot3 <- scatterplot2 + scale_color_manual(labels=c("0"="Girls","1"="Boys"), values=my_gender_colors) # let's save it

scatterplot3

## adjusting the axes It’s important to pay attention to your axes when making data visualizations because it can impact the perception of the data. Let’s say the Prosocial behavior measure and general self esteem measure both a minimum possible scores of 0. Maybe we would want to reflect that full range of possibility in our plot.

scatterplot3 +
  scale_x_continuous(limits = c(0,10)) + # sets the x axis range
  scale_y_continuous(limits = c(0,15)) # sets the y axis range
## Warning: Removed 1 row containing missing values or values outside the scale range
## (`geom_point()`).

trend lines

# let's start with our basic scatterplot - the one that does not show gender

scatterplot + theme_classic() + geom_smooth(method="lm", fill="pink", color="red") # geom_smooth with method="lm" produces a linear regression line with the equation you would get using the lm() function to calculate the model statistics. the shaded regions surrounding the line represent the 95% confidence interval
## `geom_smooth()` using formula = 'y ~ x'

scatterplot + theme_classic() + geom_smooth(method="loess", fill="pink", color="red") # method = "loess" produces a trend line with a variable slope. not very useful for our purposes in this class, but potentially useful someday.
## `geom_smooth()` using formula = 'y ~ x'

# what if you don't want to show the confidence interval?
scatterplot + theme_classic() + geom_smooth(method="lm", alpha=0, color="red") # just make it transparent (alpha=0)
## `geom_smooth()` using formula = 'y ~ x'

# now let's add trendlines to the scatterplot with gender

scatterplot3 + geom_smooth(method="lm", alpha=.2) # since gender is in the plot's aes() function, ALL the geoms will show up in two different colors, one for each gender! This makes moderation plots super easy to make.
## `geom_smooth()` using formula = 'y ~ x'

error bars

# let's make a plot that compares behavioral difficulties between girls and boys
ggplot(data, aes(x=Gender, y=BehavDiff)) +
  geom_bar(stat="summary", position="dodge") + # add bars that represent the mean value of BehavDiff within each group, and position them so that they are next to each other (dodge) not stacked on top of each other
  labs(title="Behavioral Difficulties by Gender", x="Gender", y="Behavioral Difficulties") +
  theme_classic() 
## No summary function supplied, defaulting to `mean_se()`

# now let's add the error bars

## first we need to calculate the means and sds for each group (girls and boys) separately
descriptives <- data %>%
  group_by(Gender) %>%
  summarise(
    mean_BehavDiff = mean(BehavDiff),
    sd_BehavDiff = sd(BehavDiff)
  )
descriptives
## # A tibble: 2 × 3
##   Gender mean_BehavDiff sd_BehavDiff
##   <fct>           <dbl>        <dbl>
## 1 0                12.2        0.716
## 2 1                12.4        0.986
## now we need to add these mean and sd values to the dataset as new columns

data <- data %>% left_join(descriptives, by="Gender") # this merges the descriptives dataset with the data, matching up the values based on Gender

head(data) # looks good!
## # A tibble: 6 × 10
##   Gender   Age CumulRisk CultAsset DevAsset ProSoc GenSelfEst BehavDiff
##   <fct>  <dbl>     <dbl>     <dbl>    <dbl>  <dbl>      <dbl>     <dbl>
## 1 1       11.4      6.49      1.56     28.5   8.3        13.9      12.1
## 2 1       13.1      5.44      0.98     27.5   6.48       10.7      13.5
## 3 1       12.4      6.07      1.84     28.8   7.11       12.1      12.5
## 4 1       13.5      6.57      2.08     27.9   8.36       12.8      11.2
## 5 0       12.2      3.92      1.71     28.2   6.46       11.6      12.5
## 6 0       14.2      6.98      1.64     26.8   8.75       12.9      12.4
## # ℹ 2 more variables: mean_BehavDiff <dbl>, sd_BehavDiff <dbl>
# now let's add the error bars

barplot <- ggplot(data, aes(x=Gender, y=BehavDiff)) +
  geom_bar(stat="summary", position="dodge") +
  geom_errorbar(aes(
    ymin=mean_BehavDiff-sd_BehavDiff,
    ymax=mean_BehavDiff+sd_BehavDiff, width=.2
  )) +
  labs(title="Behavioral Difficulties by Gender", x="Gender", y="Behavioral Difficulties") +
  theme_classic()

barplot
## No summary function supplied, defaulting to `mean_se()`

# Review: how would we make the gender groups show up in different colors?

part 2 - leveling up your plots

violin/density plots

# a violin plot serves the same purpose as a bar plot but it provides more information about the distribution of the variable

violin <- ggplot(data, aes(x=Gender, y=BehavDiff)) +
  geom_violin(fill="lightblue",color="lightblue",alpha=.6) +
  theme_classic()
violin

# you can also add dots to show individual datapoints
violin + geom_point(position="jitter",alpha=.5)

# you can also add error bars, just like in a bar plot

violin + geom_errorbar(aes(ymin=mean_BehavDiff-sd_BehavDiff, ymax=mean_BehavDiff+sd_BehavDiff, width=.2))

facets

# let's return to our scatterplot. say we want to graph the genders on different panels.

scatterplot + facet_grid(. ~ Gender) # horizontal direction

scatterplot + facet_grid(Gender ~ .) # vertical direction

# you can still add elements to ALL facets with a single line of code

scatterplot + facet_grid(. ~ Gender) +
  geom_smooth(method="lm") # this adds regression lines to both facets
## `geom_smooth()` using formula = 'y ~ x'

Lab Activity

Explore the resources at the top of this page (and other online resources, ChatGPT, etc.) Learn at least one new data visualization skill. This can be a new kind of plot, or a new way of formatting your plots. Write code below and include #comments so that someone else reading the code would be able to understand how to use it. Be sure to cite your sources. Your results will be compiled and shared with all PSYC 611 students to create a new data visualization resource for our class.

# Install and load necessary packages
#install.packages("htmltools") #if your htmmltools is outdated youll need to run this first to update it
#install.packages("plotly") #install this package for using interactive plots
library(ggplot2)
library(plotly) #For interactive plots, this allows you to hover over data points and see more information
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
library(readr)
df <- read_csv("/Users/jackcavanaugh/Desktop/Lab 07 - Data Viz/Filbert___Flynn_2010.csv")  # Read the CSV file into an R dataframe
## Rows: 97 Columns: 8
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (8): Gender, Age, CumulRisk, CultAsset, DevAsset, ProSoc, GenSelfEst, Be...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# Convert Gender column from numeric (0,1) to categorical (Female, Male)
df$Gender <- factor(df$Gender, levels = c(0,1), labels = c("Female", "Male"))

# Create an interactive scatter plot using plotly
p <- plot_ly(
  data = df, 
  x = ~Age,  # Set x-axis to Age
  y = ~CumulRisk,  # Set y-axis to Cumulative Risk
  type = "scatter",  # Define as scatter plot
  mode = "markers",  # Use markers instead of lines
  color = ~Gender,  # Assign colors based on Gender
  colors = c("red", "blue"),  # Female = Red, Male = Blue
  size = ~DevAsset,  # Size represents Developmental Assets
  text = ~paste("Age:", Age, "<br>Risk:", CumulRisk, "<br>Gender:", Gender, "<br>Dev Assets:", DevAsset),
  hoverinfo = "text"  # Show custom text in hover tooltips
)

# Apply layout separately
p <- p %>% layout(
  title = list(text = "Interactive Scatter Plot: Age vs. Cumulative Risk"),
  xaxis = list(title = "Age"),
  yaxis = list(title = "Cumulative Risk"),
  legend = list(title = list(text = "Gender"))
)

# Display the interactive plot
p
## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

[CITE YOUR SOURCES, INCLUDING CHATGPT AND OTHER AI] OpenAI. (2025, February 21). Response to a question about using interactive plots in R. ChatGPT. https://chat.openai.com

Scherer, C. (2019, August 5). A ggplot2 tutorial for beautiful plotting in R. Cedric Scherer. https://www.cedricscherer.com/2019/08/05/a-ggplot2-tutorial-for-beautiful-plotting-in-r/