How do I adjust the scale of a geom_tile in ggplot2? - r

I am trying to adjust the colour scale of a geom_tile plot.
A short version of my data (in data.frame format) is:
mydat <-
Sc K n minC
A 2 1 NA
A 2 2 37.453023
A 2 3 23.768316
A 2 4 17.628376
A 3 1 NA
A 3 2 12.693124
A 3 3 8.884226
A 3 4 7.436250
A 10 1 2.128121
A 10 2 2.116539
A 10 3 2.737923
A 10 4 3.509773
A 20 1 1.104592
A 20 2 1.840195
A 20 3 2.717198
A 20 4 3.616501
B 2 1 NA
B 2 2 25.090085
B 2 3 15.924186
B 2 4 11.811022
B 3 1 NA
B 3 2 8.827183
B 3 3 6.179484
B 3 4 5.175331
B 10 1 2.096934
B 10 2 2.064984
B 10 3 2.662373
B 10 4 3.407246
B 20 1 1.096871
B 20 2 1.802418
B 20 3 2.649153
B 20 4 3.517776
My code to prepare the data to plot is the following:
mydat$Sc <- factor(mydat$Sc, levels =c("A", "B"))
mydat$K <- factor(mydat$K, levels =c("2", "3","10","20"))
mydat.m <- melt(pmydat,id.vars=c("Sc","K","n"), measure.vars=c("minC"))
I want to plot with geom_tile the value of minC with K and n as axis and different facets for Sc with the following:
mydat.m.p <- ggplot(mydat.m, aes(x=n, y=K))
mydat.m.p +
geom_tile(data=mydat.m, aes(fill=value)) +
scale_fill_gradient(low="palegreen", high="lightcoral") +
facet_wrap(~ Sc, ncol=2)
This gives me a plot for each Sc factor. However, the colour scale does not reflect want I want to portray, because a few high values making low values all equal.
I want to adjust to a relevant scale in 4 breaks, i.e., 1-2, 2-3, 3-5, >5.
Looking at other questions there was a suggestion to use the cut function and scale fill manual as:
mydat.m$value1 <- cut(mydat.m$value, breaks = c(1:5, Inf), right = FALSE)
Then use the following in geom_tile:
scale_fill_manual(breaks = c("\[1,2)", "\[2, 3)", "\[3, 5)", "\[5, Inf)"),
values = c("darkgreen", "palegreen", "lightcoral", "red"))
However, I am not sure how this can be applied to a data.frame with other factors and in long format.

You're almost there. Simply use cut before melting:
mydat$minC.cut <- cut(mydat$minC, breaks = c(1:3, 5, Inf), right = FALSE)
mydat.cut <- melt(mydat, id.vars=c("Sc", "K", "n"), measure.vars=c("minC.cut"))
Now, you don't need to specify breaks since we took care of that already.
ggplot(mydat.cut, aes(x=n, y=K)) +
geom_tile(aes(fill=value)) +
facet_wrap(~ Sc, ncol=2) +
scale_fill_manual(values = c("darkgreen", "palegreen", "lightcoral", "red"))

Related

Changing fill color in geom_density beyond threshold in facet_grid plot

I want to accentuate the area in the faceted density plots above the measure threshold of 2 (e.g., red shading for x=>2). This solution works well for a single facet factor, but I have two factors. How do I specify the levels for the two factors when using ggplot_build? Or do I need to use a different approach?
Here's a bit of the dataframe (the dataframe is 750 rows):
mode.f task.f mgds
1 1 A 1.1413636
2 1 A 0.9105000
3 2 A 1.0320000
4 2 A 1.1811429
14 1 C 1.4646000
15 1 C 1.7505000
16 2 C 1.3968000
17 1 D 1.0668333
18 1 D 1.0084000
19 1 D 1.1622500
20 2 D 1.3452500
21 2 D 1.0132000
22 3 C 0.6960000
23 3 C 0.9180000
24 3 D 1.0128000
25 3 D 0.6670000
26 2 E 2.9190000
27 2 E 1.3755000
28 2 E 1.4080000
29 1 E 1.3878000
30 1 E 1.4816667
Here's the code that works for a single facet factor:
mp <- ggplot(df,aes(x=mgds))+
geom_density(color=NA,fill="gray30",alpha=.4)+
facet_wrap(~mode.f)+
theme_bw()+
theme(strip.background =
element_rect(fill="gray95",color="gray60"),
strip.text = element_text(colour="black",size=10),
panel.border = element_rect(color="gray60"))+
labs(x="MGD (s)",y="Density")
to_fill <- data_frame(
x = ggplot_build(mp)$data[[1]]$x,
y = ggplot_build(mp)$data[[1]]$y,
mode.f = factor(ggplot_build(mp)$data[[1]]$PANEL, levels =
c(1,2,3), labels = c("1","2","3")))
mp + geom_area(data = to_fill[to_fill$x >= 2, ],
aes(x=x, y=y), fill = "red")
Here's the code for the facet_grid plots that I want to have the area beyond the x=2 threshold be a different color 2
ggplot(df,aes(x=mgds))+
geom_density(color=NA,fill="gray30",alpha=.4)+
facet_grid(~mode.f~task.f)+
theme_bw()+
theme(strip.background = element_rect(fill="gray95",color="gray60"),
strip.text = element_text(colour="black",size=10),
panel.border = element_rect(color="gray60"))+
geom_vline(xintercept=2,linetype="longdash",color="gray50")+
labs(x="Measure",y="Density")

Default panel layout of ggplot2::facet_wrap()?

I'm trying to understand the default behavior of ggplot2::facet_wrap(), in terms of how the panel layout is decided as the number of facets increases.
I've read the ?facet_wrap help file, and also googled this topic with limited success. In one SO post, facet_wrap() was said to "return a symmetrical matrix of plots", but I did not find anything that explained what exactly the default behavior would be.
So next I made a series of plots which had increasing numbers of facets (code shown further down).
The pattern in the image makes it seem like facet_wrap() tries to "make a square"...
Questions
Is that correct? Does facet_wrap try to render the facet
panels so in totality they are most like a square, in terms of the
number of elements in the rows and columns?
If not, what is it actually doing? Do graphical parameters factor in?
Code that made the plot
# load libraries
library(ggplot2)
library(ggpubr)
# plotting function
facetPlots <- function(facets, groups = 8){
# sample data
df <- data.frame(Group = sample(LETTERS[1:groups], 1000, replace = T),
Value = sample(1:10000, 1000, replace = T),
Facet = factor(sample(1:facets, 1000, replace = T)))
# get means
df <- aggregate(list(Value = df$Value),
list(Group = df$Group, Facet = df$Facet), mean)
# plot
p1 <- ggplot(df, aes(x= Group, y= Value, fill = Group))+
geom_bar(stat="identity", show.legend = FALSE)+
facet_wrap(. ~ Facet) +
theme_bw()+
theme(strip.text.x = element_text(size = 6,
margin = margin(.1, 0, .1, 0, "cm")),
axis.text.x=element_blank(),
axis.ticks=element_blank(),
axis.title.x=element_blank(),
axis.text.y=element_blank(),
axis.title.y=element_blank(),
plot.margin = unit(c(3,3,3,3), "pt"))
p1
}
# apply function to list
plot_list <- lapply(c(1:25), facetPlots)
# unify into single plot
plot <- ggpubr::ggarrange(plotlist = plot_list)
Here is how the default number of rows and columns are calculated:
ncol <- ceiling(sqrt(n))
nrow <- ceiling(n/ncol)
Apparently, facet_wrap tends to prefer wider grids, since "most displays are roughly rectangular" (according to the documentation). Hence, the number of columns would be greater than or equal to the number of rows.
For your example:
n <- c(1:25)
ncol <- ceiling(sqrt(n))
nrow <- ceiling(n/ncol)
data.frame(n, ncol, nrow)
Here are the computed numbers of rows/cols:
# n ncol nrow
# 1 1 1
# 2 2 1
# 3 2 2
# 4 2 2
# 5 3 2
# 6 3 2
# 7 3 3
# 8 3 3
# 9 3 3
# 10 4 3
# 11 4 3
# 12 4 3
# 13 4 4
# 14 4 4
# 15 4 4
# 16 4 4
# 17 5 4
# 18 5 4
# 19 5 4
# 20 5 4
# 21 5 5
# 22 5 5
# 23 5 5
# 24 5 5
# 25 5 5

R ggplot2, is there a simple way to use colors for geom_point from strings in one of the coloumns? [duplicate]

This question already has answers here:
How to conditionally highlight points in ggplot2 facet plots - mapping color to column
(2 answers)
Closed 5 years ago.
I have a dataframe where a color is given for each point in a column:
d<-data.frame(x=1:10,y=1:10,col=c(rep("red",n=5),rep("green",n=5)))
d$col<-as.character(d$col)
ggplot(data=d,aes(x=x,y=y,colour=col))+geom_point()
As you can see, the colour is not interpreted as a colour, but a group,
can ggplot handle such cases?
This question has probably been asked and answered before. However, there is another issue in setting up the data.
The OP is creating the data by
d <- data.frame(x = 1:10,
y = 1:10,
col = c(rep("red", n = 5), rep("green", n = 5)))
This results in an alternation of the two colours
d
# x y col
#1 1 1 red
#2 2 2 green
#3 3 3 red
#4 4 4 green
#5 5 5 red
#6 6 6 green
#7 7 7 red
#8 8 8 green
#9 9 9 red
#10 10 10 green
Reason is that n is not a defined parameter to the rep() function. According to ?rep, valid parameters are times, lenght.out, and each.
Probably, the OP has meant
d <- data.frame(x = 1:10,
y = 1:10,
col = c(rep("red", 5), rep("green", 5)))
which results in successive rows being coloured in the same colour:
d
# x y col
#1 1 1 red
#2 2 2 red
#3 3 3 red
#4 4 4 red
#5 5 5 red
#6 6 6 green
#7 7 7 green
#8 8 8 green
#9 9 9 green
#10 10 10 green
By the way,
col = c(rep("red", 5), rep("green", 5))
can be written more clearly as
col = rep(c("red", "green"), each = 5)
With this, the following plot statements
library(ggplot2)
# variant 1 (OP's own answer)
ggplot(data = d, aes(x = x, y = y)) + geom_point(colour = d$col)
# variant 2 (aosmith' comment, more "ggplot2-like")
ggplot(data = d, aes(x = x, y = y, colour = col)) + geom_point() +
scale_colour_identity()
produce the same chart:
Just found out how:
color should be given as a separate vector, and not related to the data
ggplot(data=d,aes(x=x,y=y))+geom_point(colour=d$col)

ggplot 2 heatmap with varing axis

I want to draw a heatmap, but the size of units on the x (and y) Axis should vary. Here an example code:
users = rep(1:3,3)
Inst = c(rep("A",3),rep("B",3),rep("C",3))
dens = rnorm(9)
n_inst = c(3,3,3,2,2,2,1,1,1)
df <- data.frame( users, Inst, dens, n_inst )
1 1 A 1.2521487 3
2 2 A -0.1013088 3
3 3 A 1.5770535 3
4 1 B 1.1093957 2
5 2 B 1.1059166 2
6 3 B 0.6884662 2
7 1 C -0.3864710 1
8 2 C -1.0216373 1
9 3 C 0.4500778 1
z <- ggplot(df, aes(Inst, users)) + geom_tile(aes(fill = dens))
z + scale_x_discrete(breaks = n_inst)
So this draws a heatmap, but all units of Inst have the same size. I want A to be 3 times the width of C and B two times the width of C. So I want n_inst to give the width of units.
I tried scale_discret, but that doesn't do it
Thank you in advance.
You can try this:
ggplot(df, aes(Inst, users)) + geom_tile(aes(fill = dens, width=n_inst))

ggplot2 issue with y axis

I have the following means table:
Sex Trait Average
1 1 -N 9.042735
2 2 -N 3.529577
3 1 E 8.111111
4 2 E 9.447887
5 1 O 17.196580
6 2 O 16.311800
7 1 A 12.213680
8 2 A 13.449440
9 1 C 12.025640
10 2 C 14.529580
From where I run the following graph:
library(ggplot2)
plot <- ggplot(meansMatrix, aes(Trait, Average, colour= Sex,group= Sex)) +
geom_line(aes(linetype=Sex),size=1) +
geom_point(size=3,fill="white") +
scale_color_manual(values = c("black", "grey50")) +
scale_y_discrete(limits=c(0,18),breaks=seq(2,18,2.5),labels=seq(2,18,2.5)) +
scale_x_discrete(limits=c("-N","E","O","A","C")); plot
There is visible a problem with the y axis. After setting the variable Average as numeric, I have tried with different combinations by changing the arguments (limits, breaks and labels) with no success. This is graph is the only that pops up else than error messages.
Any input of how to re-locate the plot and show the corresponding breaks will be highly appreciated!
Use scale_y_continuous:
meansMatrix <- read.table(text=" Sex Trait Average
1 1 -N 9.042735
2 2 -N 3.529577
3 1 E 8.111111
4 2 E 9.447887
5 1 O 17.196580
6 2 O 16.311800
7 1 A 12.213680
8 2 A 13.449440
9 1 C 12.025640
10 2 C 14.529580", header=TRUE)
meansMatrix$Sex <- factor(meansMatrix$Sex)
library(ggplot2)
p <- ggplot(meansMatrix, aes(Trait, Average, colour= Sex,group= Sex)) +
geom_line(aes(linetype=Sex),size=1) +
geom_point(size=3,fill="white") +
scale_color_manual(values = c("black", "grey50")) +
scale_y_continuous(limits=c(0,18),breaks=seq(2,18,2.5),labels=seq(2,18,2.5)) +
scale_x_discrete(limits=c("-N","E","O","A","C"))
print(p)

Resources