Add same gradient to each rectangle in ggplot - r

I am trying to display color gradient in below created ggplot2. So with using following data and code
vector <- c(9, 10, 6, 5, 5)
Names <- c("Leadership", "Management\n", "Problem Solving",
"Decision Making\n", "Social Skills")
# add \n
Names[seq(2, length(Names), 2)] <- paste0("\n" ,Names[seq(2, length(Names), 2)])
# data.frame, including a grouping vector
d <- data.frame(Names, vector, group=c(rep("Intra-capacity", 3), rep("Inter-capacity", 2)))
# correct order
d$Names <- factor(d$Names, levels= unique(d$Names))
d$group_f = factor(d$group, levels=c('Intra-capacity','Inter-capacity'))
# plot the bars
p <- ggplot(d, aes(x= Names, y= vector, group= group, fill=vector, order=vector)) +
geom_bar(stat= "identity") +
theme_bw()+
scale_fill_gradient(low="white",high="blue")
# use facet_grid for the groups
#p + facet_grid(.~group_f, scales= "free_x", space= "free_x")
p+ theme(text = element_text(size=23),plot.background = element_rect(fill = "white"),
strip.background = element_rect(fill="Dodger Blue")) +
facet_grid(.~group_f, scales= "free_x", space= "free_x") + xlab("") +ylab("") +
theme(strip.text.x = element_text(size = 18, colour = "white" )) +
geom_text(size=10, aes(label=vector))
My output is this:
But now I would like to insert color gradient so each rectangle would look like picture below (my desired output):
I've also looked at this:
R: gradient fill for geom_rect in ggplot2
create an arrow with gradient color
http://www.computerworld.com/article/2935394/business-intelligence/my-ggplot2-cheat-sheet-search-by-task.html
Color Gradients With ggplot
Label minimum and maximum of scale fill gradient legend with text: ggplot2
How can I apply a gradient fill to a geom_rect object in ggplot2?
And also tried using:
scale_fill_gradient(low="white",high="blue") or
scale_fill_gradientn(colours = c("blue","white","red"),
values = c(0,5,10),
guide = "colorbar", limits=c(0,10))
But I am clearly doing something wrong.

I'm with #RomanLustrik here. However, if you can't use Excel (= prly much easier), maybe just adding a white rectangle with an alpha-gradient is already enough:
ggplot(d, aes(x= Names, y= vector, group= group,order=vector)) +
geom_bar(stat= "identity", fill="blue") +
theme_bw() +
scale_fill_gradient(low="white",high="blue") +
annotation_custom(
grid::rasterGrob(paste0("#FFFFFF", as.hexmode(1:255)),
width=unit(1,"npc"),
height = unit(1,"npc"),
interpolate = TRUE),
xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=5
) +
geom_text(aes(label=vector), color="white", y=2, size=12)

Related

plot_grid function removes axis breaks from ggbreak in plots

I'm struggling with a problem:
I created two volcano plots in ggplot2, but due to the fact that I had one outlier point in both plot, I need to add y axis break for better visualization.
The problem arises when I WANT TO plot both in the same page using plot_grid from cowplot::, because it visualizes the original plot without the breaks that I set.
p<- c1 %>%
ggplot(aes(x = avg_log2FC,
y = -log10(p_val_adj),
fill = gene_type,
size = gene_type,
alpha = gene_type)) +
geom_point(shape = 21, # Specify shape and colour as fixed local parameters
colour = "black") +
geom_hline(yintercept = 0,
linetype = "dashed") +
scale_fill_manual(values = cols) +
scale_size_manual(values = sizes) +
scale_alpha_manual(values = alphas) +
scale_x_continuous(limits=c(-1.5,1.5), breaks=seq(-1.5,1.5,0.5)) +
scale_y_continuous(limits=c(0,110),breaks=seq(0,110,25))+
labs(title = "Gene expression",
x = "log2(fold change)",
y = "-log10(adjusted P-value)",
colour = "Expression \nchange") +
theme_bw() + # Select theme with a white background
theme(panel.border = element_rect(colour = "black", fill = NA, size= 0.5),
panel.grid.minor = element_blank(),
panel.grid.major = element_blank())
p1 <- p + scale_y_break(breaks = c(30, 100))
p1
p plot without breaks:
and p1 plot with breaks:
The same I did for the second plot. But this is the result using plot_grid(p1,p3, ncol = 2)
Can you help me understanding if I'm doing something wrong? or it is just a limitation of the package?
OP, it seems in that ggbreak is not compatible with functions that arrange multiple plots, as indicated in the documentation for the package here. There does seem to be a workaround via either print() (I didn't get this to work) or aplot::plot_list(...), which did work for me. Here's an example using built-in datasets.
# setting up the plots
library(ggplot2)
library(ggbreak)
library(cowplot)
p1 <-
ggplot(mtcars, aes(x=mpg, disp)) + geom_point() +
scale_y_break(c(200, 220))
p2 <-
ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width, color=Species)) +
geom_point() + scale_y_break(c(3.5, 3.7))
Plots p1 and p2 yield breaks in the y axis like you would expect, but plot_grid(p1,p2) results in the plots placed side-by-side without the y axis breaks.
The following does work to arrange the plots without disturbing the y axis breaks:
aplot::plot_list(p1,p2)

In R ggplot2: How to assign colors in scale_fill_manual to a factor?

I have a sample dataset which I want to plot in ggplot, assigning with scale_fill_manual an individual color for each factor in the variable group. However, the individual assignment does not work properly, as you can see the factors a and b do not get a different color.
Here is my code and the resulting plot.
#data
trt<-c("trt1","trt2","trt3","trt4","trt5","trt6","trt7")
emmean<-c(7.75,7.5,5.75,7,6,8,4)
group<-c("c","c","b","bc","b","c","a")
#specify color vector to get as many colors as group levels
library(RColorBrewer)
color_pallete_function <- colorRampPalette(
colors = brewer.pal(8,"Dark2"),
space = "Lab")
dat<-data.frame(trt,emmean,group)
dat$group<-as.factor(dat$group)
num_colors <- nlevels(dat$group)
diamond_color_colors <- color_pallete_function(num_colors)
#letter display plot
ggplot(data=dat, aes(x=reorder(trt,emmean),y=emmean,fill=group)) +
geom_bar( stat="identity", width=0.8) +
scale_fill_manual(values =diamond_color_colors[dat$group])+
#geom_errorbar(aes(ymin=lower.CL, ymax=upper.CL), width=0.4) +
geom_text(aes(y=8, label=group, angle=90)) +
theme(legend.position = "none",
axis.text.x = element_text(angle = 45,hjust=1)) +
annotate(geom="label", y=1, x=length(rownames(dat))-1, size=3, color="black", fill="white",
label="Means with the same letter are according\n to Tukey test (alpha=5%) not significantly different.")
How can this be solved?
To assign colors to categories in a robust way name your color vector and use this named color vector inside scale_fill_manual. Try this:
library(ggplot2)
library(RColorBrewer)
trt<-c("trt1","trt2","trt3","trt4","trt5","trt6","trt7")
emmean<-c(7.75,7.5,5.75,7,6,8,4)
group<-c("c","c","b","bc","b","c","a")
#specify color vector to get as many colors as group levels
color_pallete_function <- colorRampPalette(
colors = brewer.pal(8,"Dark2"),
space = "Lab")
dat<-data.frame(trt,emmean,group)
dat$group<-as.factor(dat$group)
num_colors <- nlevels(dat$group)
diamond_color_colors <- color_pallete_function(num_colors)
# Name your color vector
diamond_color_colors <-setNames(diamond_color_colors, levels(dat$group))
#letter display plot
ggplot(data=dat, aes(x=reorder(trt,emmean),y=emmean,fill=group)) +
geom_bar( stat="identity", width=0.8) +
scale_fill_manual(values = diamond_color_colors)+
geom_text(aes(y=8, label=group, angle=90)) +
theme(legend.position = "none",
axis.text.x = element_text(angle = 45,hjust=1)) +
annotate(geom="label", y=1, x=length(rownames(dat))-1, size=3, color="black", fill="white",
label="Means with the same letter are according\n to Tukey test (alpha=5%) not significantly different.")

How to fix: when overlaying two scatter plots with using reorder of aes, the reorder gets lost

I have two scatter plots obtained from two sets of data that I would like to overlay, when using the ggplo2 for creating single plot i am using log scale and than ordering the numbers sothe scatter plot falls into kind if horizontal S shape. Byt when i want to overlay, the information about reordering gets lost, and the plot loses its shape.
this is how the df looks like (one has 1076 entries and the other 1448)
protein Light_Dark log10
AT1G01080 1.1744852 0.06984755
AT1G01090 1.0710359 0.02980403
AT1G01100 0.4716955 -0.32633823
AT1G01320 156.6594802 2.19495668
AT1G02500 0.6406005 -0.19341276
AT1G02560 1.3381804 0.12651467
AT1G03130 0.6361147 -0.19646458
AT1G03475 0.7529015 -0.12326181
AT1G03630 0.7646064 -0.11656207
AT1G03680 0.8340107 -0.07882836
this is for single plot:
p1 <- ggplot(ratio_log_ENR4, aes(x=reorder(protein, -log10), y=log10)) +
geom_point(size = 1) +
#coord_cartesian(xlim = c(0, 1000)) +
geom_hline(yintercept=0.1, col = "red") + #check gene
geom_hline(yintercept=-0.12, col = "red") +#check gene
labs(x = "Protein")+
theme_classic()+
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank())+
labs(y = "ratio Light_Dark log10")+
labs(x="Protein")
image=p1
ggsave(file="p1_ratio_data_ENR4_cys.svg", plot=image, width=10, height=8)
and for over lay:
p1_14a <- ggplot(ratio_log_ENR1, aes(x=reorder(protein, -log10), y=log10)) +
geom_point(size = 1) +
#coord_cartesian(xlim = c(0, 1000)) +
geom_hline(yintercept=0.1, col = "red") + #check gene
geom_hline(yintercept=-0.12, col = "red") +#check gene
labs(x = "Protein")+
theme_classic()+
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank())+
labs(y = "ratio Light_Dark log10")+
labs(x="Protein")+
geom_point()+
geom_point(data=ratio_log_ENR4, color="red")
p=ggplot(ratio_log_ENR1, aes(x=reorder(protein, -log10), y=log10)) +
geom_point(size = 1) +
#coord_cartesian(xlim = c(0, 1000)) +
geom_hline(yintercept=0.1, col = "red") + #check gene
geom_hline(yintercept=-0.12, col = "red") +#check gene
labs(x = "Protein")+
theme_classic()+
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank())+
labs(y = "ratio Light_Dark log10")+
labs(x="Protein")
p = p + geom_point(data=ratio_log_ENR4, aes(x=reorder(protein, -log10), y=log10), color ="red" )
p
I tried to change classes... but it cant be the problem since for single plot its working like it is
The easiest solution I see for you is just binding together your two dataframes before plotting.
a$color <- 'red'
b$color <- 'blue'
ab <- a %>%
rbind(b)
ggplot(ab, aes(x = fct_reorder(protein, -log10), y = log10, color = color)) +
geom_point() +
scale_color_identity()
You can find a nice cheat-sheet for working with factors here: https://stat545.com/block029_factors.html

decrease size of dendogram (or y-axis) ggplot

I have this code for a dendrogram. How can I decrease the size of dendrogram (or y-axis)?
I am using this code as example. In my dataset, I have large labels so I do not have space enough to include it. For that reason, I would like to reduce the space used for y axis, decrease the distance between 0 and 150. Also, when I save the figure as tiff, most of figure is the dendogram and I can not see labels clearly.
df <- USArrests # really bad idea to muck up internal datasets
labs <- paste("sta_",1:50,sep="") # new labels
rownames(df) <- labs # set new row names
library(ggplot2)
library(ggdendro)
hc <- hclust(dist(df), "ave") # heirarchal clustering
dendr <- dendro_data(hc, type="rectangle") # convert for ggplot
clust <- cutree(hc,k=2) # find 2 clusters
clust.df <- data.frame(label=names(clust), cluster=factor(clust))
# dendr[["labels"]] has the labels, merge with clust.df based on label column
dendr[["labels"]] <- merge(dendr[["labels"]],clust.df, by="label")
# plot the dendrogram; note use of color=cluster in geom_text(...)
ggplot() +
geom_segment(data=segment(dendr), aes(x=x, y=y, xend=xend, yend=yend)) +
geom_text(data=label(dendr),
aes(x, y, label=label, hjust=0, color=cluster),
size=3) +
coord_flip() +
scale_y_reverse(expand=c(0.2, 0)) +
theme(axis.line.y=element_blank(),
axis.ticks.y=element_blank(),
axis.text.y=element_blank(),
axis.title.y=element_blank(),
panel.background=element_rect(fill="white"),
panel.grid=element_blank())
How can I decrease the size of dendogram similar than this heatmap?
(source: r-graph-gallery.com)
Thanks you so much
For flexibility, I recommend putting the dendrogram labels on the x-axis itself, rather than text labels within the plot. Otherwise no matter what values you choose for expand in the y-axis, part of the labels could be cut off for some image sizes / dimensions.
Define colour palette for the dendrogram labels:
library(dplyr)
label.colour = label(dendr)$cluster %>%
factor(levels = levels(.),
labels = scales::hue_pal()(n_distinct(.))) %>%
as.character()
For the purpose of illustration, make some labels very long:
label.values <- forcats::fct_recode(
label(dendr)$label,
sta_45_abcdefghijklmnop = "sta_45",
sta_31_merrychristmas = "sta_31",
sta_6_9876543210 = "sta_6")
Plot:
p <- ggplot(segment(dendr)) +
geom_segment(aes(x=x, y=y, xend=xend, yend=yend)) +
coord_flip() +
scale_x_continuous(breaks = label(dendr)$x,
# I'm using label.values here because I made
# some long labels for illustration. you can
# simply use `labels = label(dendr)$label`
labels = label.values,
position = "top") +
scale_y_reverse(expand = c(0, 0)) +
theme_minimal() +
theme(axis.title = element_blank(),
axis.text.y = element_text(size = rel(0.9),
color = label.colour),
panel.grid = element_blank())
p
# or if you want a color legend for the clusters
p + geom_point(data = label(dendr),
aes(x = x, y = y, color = cluster), alpha = 0) +
scale_color_discrete(name = "Cluster",
guide = guide_legend(override.aes = list(alpha = 1))) +
theme(legend.position = "bottom")
You can do this by adding a size parameter to axis.text.y like so:
theme(axis.line.y=element_blank(),
axis.ticks.y=element_blank(),
axis.text.y=element_text(size=12),
axis.title.y=element_blank(),
panel.background=element_rect(fill="white"),
panel.grid=element_blank())

Vertical line in histogram in r

I'm struggeling a bit with a peace of code in R. I am trying to create 6 different histograms in the same figure. It works fine, but I need to place 1 vertical line in each of the 6 histograms. The code I am working with could look something like this:
require(ggplot2)
require(reshape2)
require(gdata)
MC_beta=rbind(rnorm(1000,-2,0.1),rnorm(1000,-1,0.1),rnorm(1000,0,0.1),rnorm(1000,0.5,0.1),rnorm(1000,1,0.1),rnorm(1000,2,0.1))
df <- data.frame(MC_beta[1,], MC_beta[2,], MC_beta[3,], MC_beta[4,],MC_beta[5,],MC_beta[6,])
names(df)[1:6]<-c("1", "2", "3", "4","5","6")
df2 = melt(df)
z=c(-2,-1,0,0.5,1,2)
ggplot(df2, aes(x=value, fill = variable)) + geom_vline(xintercept = z, colour="black") +geom_histogram(binwidth=0.03,colour = "black") + scale_fill_manual(name = "",values = c('red','blue',"red","blue","red","blue")) +
facet_wrap(~variable,nrow=6, ncol=1) + scale_x_continuous(breaks=seq(-2.5,2.5,0.5)) + guides(fill=FALSE) +
theme_bw() + theme(strip.background = element_blank(),axis.text=element_text(size=14.5),strip.text.x = element_text(size = 14.5)) + stat_function(fun = dnorm)
The problem is with the statement geom_vline(xintercept = z, colour = "black"). Apparently instead of placing one vertical line in each histogram, it places all 6 lines in each histogram. So instead, I want the first element in z to make a vertical line in the first histogram, the second element in z to make a vertical line in the second histogram and so fourth.
Thanks
Your z needs to be a data.frame with the corresponding xintercept for every value of the variable that defines the facet. Try these changes:
z <- data.frame(variable=levels(df2$variable),
mean=c(-2,-1,0,0.5,1,2))
ggplot(df2, aes(x=value, fill = variable))+
geom_vline(data=z, aes(xintercept = mean), colour="black") +
geom_histogram(binwidth=0.03,colour = "black") +
scale_fill_manual(name = "",values = c('red','blue',"red","blue","red","blue")) +
facet_wrap(~variable,nrow=6, ncol=1) +
scale_x_continuous(breaks=seq(-2.5,2.5,0.5))+ guides(fill=FALSE) +
theme_bw() +
theme(strip.background = element_blank(), axis.text=element_text(size=14.5), strip.text.x = element_text(size = 14.5)) +
stat_function(fun = dnorm)
I hope that helps.
You have z outside the data, so you will draw a vertical line in each facet. Use
df2 <- (merge(df2, cbind.data.frame(variable=names(df), z)))
and then
geom_vline(aes(xintercept = z), colour="black")

Resources