Merging two plots into one, each with a separate legend using R - r

I'm have made two separate scatter plots using ggplot2 and I need to combine them into one single plot. Each plot is for a population of lizards under three different treatments (backgrounds).
for each plot I have the following:
csMS = data.frame()
ellMS = data.frame()
centroidsMS = data.frame()
csplotMS = ggplot(csMS, aes(x = RG, y = GB, colour = Background)) + geom_point(size = 3, shape = 17) + #colour by background, circles size 3
geom_path(data = ell.AS, aes(x = RG, y = GB ,colour = Background), size = 1, linetype = 2) + #adding the ellipses
geom_point(data = centroidsMS, size = 3, shape = 17) + #added centroids
geom_errorbar(data = centroidsMS, aes(ymin = GB - se.GB, ymax = GB + se.GB), width = 0) + #add y error bars
geom_errorbarh(data = centroidsMS, aes(xmin = RG - se.RG, xmax = RG + se.RG), height = 0) +
theme_bw() + #white background
theme(axis.title.y = element_text(vjust = 2), axis.title.x = element_text(vjust = -0.3)) + #distance of axis titles from axis
theme(panel.border = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), #no grids
axis.line = element_line(colour = "black")) + #black axes
theme(text = element_text(size = 30)) + #font size
ylab("(G-B)/(G+B)") + xlab("(R-G)/(R+G)") + # Set text for axes labels
scale_colour_manual(values = c("black","#FF6600", "yellow1")) + #changed default colours
labs(colour = "Murray Sunset NP") +
theme(legend.title = element_text(size = "20")) + #changes the legend title
theme(legend.text = element_text(size = "20")) + #changes the legend title
theme(legend.key = element_blank()) + #removed little squares around legend symbols
theme(legend.direction = "horizontal", legend.position = c(.5, .85))
I tried
csASMS = csplotAS + csplotMS
but I get an error message: "Error in p + o : non-numeric argument to binary operator In addition: Warning message: Incompatible methods ("+.gg", "Ops.data.frame") for "+" "
I also tried
csASMS = grid.arrange(csplotAS, csplotMS)
but this places one plot on top of the other, but I need to combine both plots so that they are basically just one plot but with two separate legends as each plot has different conventions to indicate the different lizard populations.
Any help will be greatly appreciated.
****EDIT**** Dec 12/ 2014
I have managed to combine the two plots into one but still have the problem of the separate legends. To try to simplify the question and as per cdeterman's request I'm adding a simpler form of the code with some sample data:
data frames: p1 and p2
> p1
treatment x y
1 Black 1 1
2 Orange 2 2
3 Yellow 3 3
> p2
treatment x y
1 Black 4 4
2 Orange 5 5
3 Yellow 6 6
I used the following code to make a plot that includes both data frames:
plot = ggplot(p1, aes(x = x, y = y, colour = treatment)) + geom_point(size = 3) + #colour by background, circles size 3
theme_bw() + #white background
theme(axis.title.y = element_text(vjust = 2), axis.title.x = element_text(vjust = -0.3)) + #distance of axis titles from axis
theme(panel.border = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), #no grids
axis.line = element_line(colour = "black")) + #black axes
theme(text = element_text(size = 30)) + #font size
scale_colour_manual(values = c("black","#FF6600", "yellow1")) + #changed default colours
labs(colour = "p1") +
theme(legend.title = element_text(size = "20")) + #changes the legend title
theme(legend.text = element_text(size = "20")) + #changes the legend title
theme(legend.key = element_blank()) + #removed little squares around legend symbols
theme(legend.direction = "horizontal", legend.position = c(.33, 1)) +
# Now to add the second plot/ No need to code for axis titles, titles positions,etc b/c it's already coded in the first plot
geom_point(data = p2, aes(x = x, y = y, colour = treatment), size = 3, shape = 17)
This produces a graph with each data frame represented in a different symbol (circles for p1 and triangles for p2) but with only one combined legend with triangles superimposed over circles). How can I get two separate legends, one for each data frame?
Thank you!

After doing some research and trying different things I was able to solve PART of my problem. To add two plots together one needs to be plotter first and the other one on top of the first one using
geom.point()
my new code looks like this:
csplotASMS = ggplot(csAS, aes(x = RG, y = GB, colour = Background)) + geom_point(size = 3) + #colour by background, circles size 3
geom_path(data = ell.AS, aes(x = RG, y = GB ,colour = Background), size = 1, linetype = 1) + #adding the ellipses
geom_point(data = centroidsAS, size = 4) + #added centroids
geom_errorbar(data = centroidsAS, aes(ymin = GB - se.GB, ymax = GB + se.GB), width = 0) + #add y error bars
geom_errorbarh(data = centroidsAS, aes(xmin = RG - se.RG, xmax = RG + se.RG), height = 0) +
theme_bw() + #white background
theme(axis.title.y = element_text(vjust = 2), axis.title.x = element_text(vjust = -0.3)) + #distance of axis titles from axis
theme(panel.border = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), #no grids
axis.line = element_line(colour = "black")) + #black axes
theme(text = element_text(size = 30)) + #font size
ylab("(G-B)/(G+B)") + xlab("(R-G)/(R+G)") + # Set text for axes labels
scale_colour_manual(values = c("black","#FF6600", "yellow1")) + #changed default colours
labs(colour = "Alice Springs") +
theme(legend.title = element_text(size = "20")) + #changes the legend title
theme(legend.text = element_text(size = "20")) + #changes the legend title
theme(legend.key = element_blank()) + #removed little squares around legend symbols
theme(legend.direction = "horizontal", legend.position = c(.33, 1)) +
# Now to add the second plot/ No need to code for axis titles, titles positions,etc b/c it's already coded in the first plot
geom_point(data = csMS, aes(x = RG, y = GB, colour = Background), size = 3, shape = 17) +
geom_path(data = ell.MS, aes(x = RG, y = GB ,colour = Background), size = 1, linetype = 2) + #adding the ellipses
geom_point(data = centroidsMS, size = 4, shape = 17) + #added centroids
geom_errorbar(data = centroidsMS, aes(ymin = GB - se.GB, ymax = GB + se.GB), width = 0) + #add y error bars
geom_errorbarh(data = centroidsMS, aes(xmin = RG - se.RG, xmax = RG + se.RG), height = 0) #add x error bars
and the graph depicts a scatterplot for two populations, each with three treatments. Because tratments are the same for both populations I want to use the same colours but different symbols to denote the differences in populations. One population is circles and the other one is triangles.
Now, the part I can't answer yet is how to have two separate legends, one for each "plot". i.e. one for the circles and one for the triangles. At the moments there is a "combined legend showing triangles superimposed on circles. Each legend should have its own title.

Related

Dodge failing in violin plot

I would like to plot the congruence effects (incongruent minus congruent) as a violin plot per combination of stimulus age and response type. This is what my code looks like so far. I am not yet satisfied with the representation. How can I change it so that for each of the four conditions (adult frown, adult smile, child frown, child smile) I get the corresponding violin plot horizontally next to each other? Thanks in advance for the help. Attached is the code and an excerpt from the data frame.
violin plot
dataset$congruency_effect <- ifelse(dataset$congruency == "congruent", dataset$avgAmplitude, -dataset$avgAmplitude)
p <- ggplot(dataset, aes(x = stimulusResponse, y = congruency_effect, fill = congruency_effect, group = stimulusAge)) +
geom_violin() +
geom_point(position = position_dodge(width = 0.75), size = 3, stat = "summary", fun.y = "mean") +
scale_fill_manual(values = c("#F8766D", "#00BFC4")) +
ggtitle("Conventional EEG 350-450 ms") +
scale_y_continuous(limits = c(-5, 5)) +
facet_wrap(~stimulusAge, scales = "free_x")
EEG_Conventional450_age_response <- p + theme(
# Set the plot title and axis labels to APA style
plot.title = element_text(face = "bold", size = 16),
axis.title = element_text(face = "bold", size = 14),
# Set the axis tick labels to APA style
axis.text = element_text(size = 12),
# Set the legend title and labels to APA style
legend.title = element_text(face = "bold", size = 14),
legend.text = element_text(size = 12),
# Set the plot and panel backgrounds to white
panel.background = element_rect(fill = "white"),
plot.background = element_rect(fill = "white")
)
EEG_Conventional450_age_response
excerpt data frame
several permutations of arguments in ggplot
This has to do with the grouping aesthetic. Remove it, and your plot works.
library(ggplot2)
set.seed(42)
dataset <- data.frame(stimulusResponse = rep(c("frown", "smile"), each = 20),
congruency_effect = rnorm(40),
stimulusAge = rep(c("baby", "adult"), 20))
## removed group = stimulusAge
ggplot(dataset, aes(x = stimulusResponse, y = congruency_effect)) +
geom_violin() +
geom_point(position = position_dodge(width = 0.75), size = 3, stat = "summary") +
facet_wrap(~stimulusAge, scales = "free_x")

ggplot2 scale_fill_gradient() function not changing point colors R

I'm using ggplot2 in R to create maps. In the past, I have been able to successfully use the scale_fill_gradient() function to control geom_point fills. However, when I run the code below (with example table provided), I simply get a map of all black points. The legend appears correct, but the points never change color. I think my desired variable is not mapping to the fill aesthetic, but I cannot figure out why. Thank you in advance!
(if it matters, I am using tibble package to define tables)
table = tibble(long = c(15.28, 15.29, 15.3, 15.31, 15.32), lat = c(-4.4, -4.39, -4.38, -4.37, -4.36), consumption = c(NA, 3, 54, 6, 8))
mapping = aes_string(x = 'long', y = 'lat', fill = 'consumption')
# define breaks, limits, colors
low = 'seashell'
high = 'tan3'
breaks = c(0, max(na.omit(table)[['consumption']]))
limits = breaks
# plot
p <- ggplot() +
# points
geom_point(mapping = mapping, data = table, alpha = 0.7, size = 4) +
# point colors
scale_fill_gradient(low = low, high = high, na.value = 'darkgrey', guide = 'colorbar', aesthetics = 'fill'
, breaks = breaks, limits = limits) +
# title
ggtitle('consumption') +
# title formatting
theme(plot.title = element_text(color = "red", size = 10, face = "bold", hjust=0),
legend.position="bottom",
legend.text=element_text(size=9),
legend.title=element_text(size=9)) +
# legend
guides(fill=guide_colorbar(title='consumption')) +
# get rid of axes, etc.
theme(axis.line = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank()) +
xlab('') +
ylab('') +
# make legend correct
theme(legend.box = 'vertical') +
# add max/min corresponding to map
xlim(c(15.28, 15.38)) +
ylim(c(-4.41, -4.30))
As mentioned in the comments you have to change the fill to color. Here is how I achieved it:
library(tidyverse)
table = tibble(long = c(15.28, 15.29, 15.3, 15.31, 15.32), lat = c(-4.4, -4.39, -4.38, -4.37, -4.36), consumption = c(NA, 3, 54, 6, 8))
##Changed here to color
mapping = aes_string(x = 'long', y = 'lat', color = 'consumption')
# define breaks, limits, colors
low = 'seashell'
high = 'tan3'
breaks = c(0, max(na.omit(table)[['consumption']]))
limits = breaks
# plot
ggplot() +
# points
geom_point(mapping = mapping,
data = table, alpha = 0.7, size = 4) +
# point colors
#Change here to aesthetics = color
scale_color_gradient(low = low, high = high, na.value = 'darkgrey', guide = 'colorbar', aesthetics = 'color'
, breaks = breaks, limits = limits) +
# title
ggtitle('consumption') +
# title formatting
theme(plot.title = element_text(color = "red", size = 10, face = "bold", hjust=0),
legend.position="bottom",
legend.text=element_text(size=9),
legend.title=element_text(size=9)) +
# legend
guides(fill=guide_colorbar(title='consumption')) +
# get rid of axes, etc.
theme(axis.line = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank()) +
xlab('') +
ylab('') +
# make legend correct
theme(legend.box = 'vertical') +
# add max/min corresponding to map
xlim(c(15.28, 15.38)) +
ylim(c(-4.41, -4.30))

ggplot removes data when trying to change point colors and /or shapes

I'm trying to create a simple point estimate with confidence interval plot. I can get it to plot as I'd like until I try to change the point shape and/or the color. When I try to change either I get "Warning: Removed 4 rows containing missing values (geom_point)." and end up with a blank plot.
I've checked out and tried the suggestions on:
here
here
here
and here
and a couple other places but to no avail.
A Reproducible Example
library(ggplot2)
set.seed(1)
# Create some sample data
point_est <- 4:1
se <- runif(4)
df <- data.frame(point_est = point_est,
se = se,
lower = point_est - se,
upper = point_est + se,
year = c("c", "c", "p", "p"),
group = letters[1:4])
group_names <- paste0("Display Name for \n Group ", LETTERS[1:4])
names(group_names) <- letters[1:4]
legend_text <- c("Previous Year Rate with 95% Confidence Intervals",
"Current Year Rate with 95% Confidence Intervals")
names(legend_text) <- c("p", "c")
df$year = factor(df$year, levels = names(legend_text), labels = legend_text)
df$group = factor(df$group, levels = names(group_names), labels = group_names)
# Plot looks good except the colors and shape of the points need changing
ggplot(df, aes(x = group, y = point_est, color = year, label= year, shape = year)) +
geom_errorbar(aes(ymin=lower, ymax=upper), width=.3) +
geom_point(size = 3.2) +
scale_x_discrete(drop=FALSE) +
scale_y_continuous(sec.axis = sec_axis(~.*3, name = "This is my Right Axis")) +
labs(x = NULL,
y = "This is my Left Axis") +
theme(legend.title = element_blank(),
legend.position = "bottom",
legend.background = element_blank(),
legend.box.background = element_rect(colour = "black"),
panel.border = element_rect(colour = "black", fill=NA),
panel.background = element_blank())
# now change the shapes of the points and the colors of the error bars
shapes <- c(17, 15)
names(shapes) <- names(legend_text)
colors <- c("pink", "blue")
names(colors) <- names(legend_text)
ggplot(df, aes(x = group, y = point_est, color = year, label= year, shape = year)) +
geom_errorbar(aes(ymin=lower, ymax=upper), width=.3) +
geom_point(size = 3.2) +
scale_x_discrete(drop=FALSE) +
scale_y_continuous(sec.axis = sec_axis(~.*3, name = "This is my Right Axis")) +
scale_shape_manual(values = shapes) +
scale_color_manual(values = colors) +
labs(x = NULL,
y = "This is my Left Axis") +
theme(legend.title = element_blank(),
legend.position = "bottom",
legend.background = element_blank(),
legend.box.background = element_rect(colour = "black"),
panel.border = element_rect(colour = "black", fill=NA),
panel.background = element_blank())
#> Warning: Removed 4 rows containing missing values (geom_point).
# Blank plot now and warnings:(
This is happening because you used names(legend_text) rather than legend_text as the names of your shapes and colors vectors. legend_text is what matches the values in the year column of your data. Do names(colors) <- legend_text and likewise for shapes and the plot will work. Nothing was plotted because the names of the colors and shapes vectors did not match any of the levels of df$year, so no colors or shapes were assigned for the actual values in year.
It looks like maybe you got tripped up by levels vs. labels in the factor function. By default, the levels are the existing set of unique values in the data and the labels are set equal to the levels. However, if you include a labels argument in factor, the data values get relabeled to be the values in the labels argument.
To make this concrete, note in the code below that the names of the shapes and colors vectors are p and c, which is different from the values in df$year.
> df[ , "year", drop=FALSE]
year
1 Current Year Rate with 95% Confidence Intervals
2 Current Year Rate with 95% Confidence Intervals
3 Previous Year Rate with 95% Confidence Intervals
4 Previous Year Rate with 95% Confidence Intervals
> levels(df$year)
[1] "Previous Year Rate with 95% Confidence Intervals" "Current Year Rate with 95% Confidence Intervals"
> shapes
p c
17 15
> colors
p c
"pink" "blue"
If you put the vectors directly into the ggplot it will work.
For scale_shape_manual put c(17,15) for the values and for scale_color_manual put c("Pink","Blue") for the values. Or just do not assign names to the shapes and colors vectors. That is what it is throwing it off.
ggplot(df, aes(x = group, y = point_est, color = year, label= year, shape = year)) +
geom_errorbar(aes(ymin=lower, ymax=upper), width=.3) +
geom_point(size = 3.2) +
scale_x_discrete(drop=FALSE) +
scale_y_continuous(sec.axis = sec_axis(~.*3, name = "This is my Right Axis")) +
scale_shape_manual(values = c(17, 15)) +
scale_color_manual(values = c("pink", "blue")) +
labs(x = NULL,
y = "This is my Left Axis") +
theme(legend.title = element_blank(),
legend.position = "bottom",
legend.background = element_blank(),
legend.box.background = element_rect(colour = "black"),
panel.border = element_rect(colour = "black", fill=NA),
panel.background = element_blank())
######if you want to use the vectors do not name them
shapes <- c(17, 15)
colors <- c("pink", "blue")
ggplot(df, aes(x = group, y = point_est, color = year, label= year, shape = year)) +
geom_errorbar(aes(ymin=lower, ymax=upper), width=.3) +
geom_point(size = 3.2) +
scale_x_discrete(drop=FALSE) +
scale_y_continuous(sec.axis = sec_axis(~.*3, name = "This is my Right Axis")) +
scale_shape_manual(values = shapes) +
scale_color_manual(values = colors) +
labs(x = NULL,
y = "This is my Left Axis") +
theme(legend.title = element_blank(),
legend.position = "bottom",
legend.background = element_blank(),
legend.box.background = element_rect(colour = "black"),
panel.border = element_rect(colour = "black", fill=NA),
panel.background = element_blank())

Draw heatmap for a matrix using circle in R [duplicate]

Is it possible to draw a heatmap with circles instead of square in ggplot2? It would be neat to not only represent the values by a color gradient but also by the circle size.
I am thinking of a graph like this dot heatmap where also the circle sizes are alternated by their specific value. I already read myself into heatmapping with ggplot2 but couldn't find a solution. For heatmapping I alternated the example posted on learnr.wordpress.com to:
library(ggplot2)
library(plyr)
library(reshape2)
library(scales)
kreuz <- read.csv("http://datasets.flowingdata.com/ppg2008.csv")
kreuz.m <- melt(kreuz)
(p <- ggplot(kreuz.m, aes(Name, variable)) +
geom_tile(aes(fill = value), colour = "white") +
scale_fill_gradient2(breaks=waiver(), name="binding strength",
low ="white", mid= ("lightblue"), high = "steelblue", midpoint = 4))
base_size <- 10
p + theme_grey(base_size = base_size) +
theme(panel.grid.major = element_blank())+
labs(x = "Patient ID", y = "Phage Motives", title = "Cross Reactivity")+
scale_x_discrete(expand = c(0, 0)) +
scale_y_discrete(expand = c(0, 0)) +
theme(legend.position = "right", axis.ticks = element_blank(),
axis.text.x = element_text(size = base_size *0.8, angle = 270, hjust = 0,
colour = "grey50"))+
labs(x = "Patient ID", y = "Phagemotives", title = "cross reactivity")
I would be very greatful for some hints!
In this example size and colour both correspond with the variable value because it's the only variable numeric available in the kreuz.m dataset.
ggplot(kreuz.m, aes(Name, variable)) +
geom_point(aes(size = value, colour=value))

Is a heatmap in "sized dot style" possible in ggplot2?

Is it possible to draw a heatmap with circles instead of square in ggplot2? It would be neat to not only represent the values by a color gradient but also by the circle size.
I am thinking of a graph like this dot heatmap where also the circle sizes are alternated by their specific value. I already read myself into heatmapping with ggplot2 but couldn't find a solution. For heatmapping I alternated the example posted on learnr.wordpress.com to:
library(ggplot2)
library(plyr)
library(reshape2)
library(scales)
kreuz <- read.csv("http://datasets.flowingdata.com/ppg2008.csv")
kreuz.m <- melt(kreuz)
(p <- ggplot(kreuz.m, aes(Name, variable)) +
geom_tile(aes(fill = value), colour = "white") +
scale_fill_gradient2(breaks=waiver(), name="binding strength",
low ="white", mid= ("lightblue"), high = "steelblue", midpoint = 4))
base_size <- 10
p + theme_grey(base_size = base_size) +
theme(panel.grid.major = element_blank())+
labs(x = "Patient ID", y = "Phage Motives", title = "Cross Reactivity")+
scale_x_discrete(expand = c(0, 0)) +
scale_y_discrete(expand = c(0, 0)) +
theme(legend.position = "right", axis.ticks = element_blank(),
axis.text.x = element_text(size = base_size *0.8, angle = 270, hjust = 0,
colour = "grey50"))+
labs(x = "Patient ID", y = "Phagemotives", title = "cross reactivity")
I would be very greatful for some hints!
In this example size and colour both correspond with the variable value because it's the only variable numeric available in the kreuz.m dataset.
ggplot(kreuz.m, aes(Name, variable)) +
geom_point(aes(size = value, colour=value))

Resources