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 <- 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.
# 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")
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
# 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()`).
# 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'
# 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?
# 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))
# 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'
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/