How to plot counts stackbar in ggplot2 R? - r

Dataset contains "two friends" and coded "interaction" (all factors). I want to plot the frequency of type of interactions between two friends using a stacked bar. I tried the following code.
Friend1 <- c("A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B")
Friend2 <- c("1","1","2","2","1","1","2","2","1","1","2","2","1","1","2","2")
Interaction <- c("O","X","D","D","D","X","X","D/R","O","X","D","D","D","X","X","D/R")
df <- data.frame(Friend1, Friend2, Interaction)
df$Friend1 <- as.factor(as.character(df$Friend1))
df$Friend2 <- as.factor(as.character(df$Friend2))
df$Interaction <- as.factor(as.character(df$Interaction))
ggplot(df, aes(fill=Interaction, y=count(Interaction), x=Friend2)) +
geom_bar(position="fill", stat="identity", color = "white") + theme_classic() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_rect(colour = "black", size=1)) + theme(strip.background = element_blank()) + facet_grid(.~Friend1)
Erorr: Error in UseMethod("count") :
no applicable method for 'count' applied to an object of class "character"
How do I "count" these factors to visualize frequency of interactions?

The issue is that dplyr::count expects a dataframe as its first argument and returns a dataframe. However, there is no reason to compute the counts as geom_bar will do that by default, i.e. get rid of y=... and stat="identity":
library(ggplot2)
ggplot(df, aes(fill = Interaction, x = Friend2)) +
geom_bar(position = "fill", color = "white") +
theme_classic() +
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_rect(colour = "black", size = 1)
) +
theme(strip.background = element_blank()) +
facet_grid(. ~ Friend1)

An alternative visualization using facets per "friends" column may make your counts clearer than a standard stacked bar:
ggplot(df, aes(x = 1, fill = Interaction)) +
geom_bar(width = 1, color = "white", size = 1, alpha = 0.8) +
geom_text(stat = "count", aes(label = after_stat(count)), size = 7,
position = position_stack(vjust = 0.5), color = "white",
fontface = 2) +
facet_grid(Friend1 ~ Friend2, switch = "both") +
scale_fill_brewer(palette = "Set1") +
coord_polar(theta = "y") +
labs(x = "Friend1", y = "Friend2") +
theme_bw(base_size = 20) +
theme(panel.grid = element_blank(),
strip.background = element_blank(),
strip.placement = "outside",
axis.text.x = element_blank(),
panel.border = element_rect(color = "gray90", fill = NA),
panel.spacing = unit(0, "mm"),
axis.text = element_blank(),
axis.ticks = element_blank())

Related

Can you shift the position of a facet label or strip bar in ggplot?

I'm using ggplot to graph a forest plot. I have used facet labels to label groups (in example below Test1, Test2, Test3). Is there a way to slightly shift the actual position of the facet label/strip to the left (as indicated by the arrows in my picture below)?
I can shift the position of the text within the facet label but I think I have done that as much as possible. Thus, I think I need to shift the actual facet label (strip bar/rectangle) itself. Is this possible?
Would be very grateful if anyone could help me or point out a way to get a similar effect!
Please find reproducible code here:
library(dplyr)
library(ggplot2)
library(ggforce)
library(tidyverse)
# Reproducible dataset
df <- data.frame(outcome = c('outcome1', 'outcome1', 'outcome2','outcome2','outcome3','outcome3','outcome4','outcome4','outcome5','outcome5'),
type = c('Test1','Test1','Test2','Test2', 'Test3', 'Test3', 'Test3','Test3', 'Test3', 'Test3'),
Coef = c(0.10026935, 0.10026935, 0.13713358, 0.13713358,0.07753188,0.07753188,0.09193794,0.09193794,0.06170916,0.06170916),
CIr_low = c(0.070955475,0.070955475,0.108705781,0.108705781,0.052595474,0.052595474,0.056340327,0.056340327,0.036185918,0.036185918),
CIr_high = c(0.12958323,0.12958323,0.16556139,0.16556139,0.10246828,0.10246828,0.12753555,0.12753555,0.08723240,0.08723240),
model = c(1,2,1,2,1,2,1,2,1,2))
# Set type as factor
df <- df %>% mutate(type = fct_relevel(type, "Test1","Test2","Test3"))
# Plot with ggplot
ggplot(df, aes(x = outcome, y = Coef, ymin = CIr_low,ymax =CIr_high,fill = as.factor(type))) +
geom_errorbar(aes(x= outcome, ymin=CIr_low, ymax=CIr_high), width=0.2,cex=0.5)+
geom_point(shape = 18, size = 5)+
facet_grid(type ~ ., scales = "free", space = "free") +
geom_hline(yintercept = 0, linetype = 'dashed', col = 'black') +
scale_y_continuous(limits = c(-0.1, 0.25)) +
ggforce::facet_col(facets = type ~ ., scales = "free_y", space = "free", strip.position = "top")+
theme_bw()+
coord_flip() +
xlab('Group')+
ylab(expression("Standardized" ~ beta *" (95%CI)"))+
theme(line = element_line(colour = "black", size = 0.5),
plot.margin = margin(0.5, 0.5, 0.5, 0.5, unit = "cm"),
strip.background = element_rect(colour = "white", fill="white"),
strip.text = element_text(colour = "black",face="italic"),
strip.text.x = element_text(size = 12,angle = 0,hjust = 0,face="bold.italic", color="darkblue"),
legend.position ="none",
axis.line.x = element_line(colour = "black"),
axis.line.y = element_blank(),
panel.border= element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
panel.spacing = unit(2, "lines"),
axis.ticks = element_blank(),
axis.title.x = element_text(colour = "black"),
axis.title.y = element_blank(),
axis.text=element_text( color = "black")
)
You can try:
ggplot(df, aes(x = outcome, y = Coef, ymin = CIr_low,ymax =CIr_high,fill = as.factor(type))) +
geom_errorbar(aes(x= outcome, ymin=CIr_low, ymax=CIr_high), width=0.2,cex=0.5)+
geom_point(shape = 18, size = 5, show.legend = F)+
geom_hline(yintercept = 0, linetype = 'dashed', col = 'black') +
scale_y_continuous(expression("Standardized" ~ beta *" (95%CI)"),limits = c(-0.1, 0.25)) +
xlab("")+
coord_flip() +
facet_grid(type~., scales = "free", space = "free_y", switch = "y") +
theme_minimal() +
theme(strip.placement = "outside",
strip.text.y.left = element_text(angle = 0,vjust = 1,size=12))
Or use a cowplot approach with ggtitle
plots <- df %>%
split(.$type) %>%
map2(.,names(.), ~ggplot(.x, aes(x = outcome, y = Coef, ymin = CIr_low,ymax =CIr_high,fill = as.factor(type))) +
geom_errorbar(aes(x= outcome, ymin=CIr_low, ymax=CIr_high), width=0.2, size=0.5)+
geom_point(shape = 18, size = 5, show.legend = F)+
geom_hline(yintercept = 0, linetype = 'dashed', col = 'black') +
scale_y_continuous(limits = c(-0.1, 0.25))+
coord_flip() +
xlab('')+
ylab(expression("Standardized" ~ beta *" (95%CI)"))+
ggtitle(.y)+
theme_minimal(base_size = 12)+
theme( panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
plot.title.position = "plot"))
cowplot::plot_grid(plots$Test1 + theme(axis.title.x = element_blank(), axis.ticks.x = element_blank(), axis.text.x = element_blank()),
plots$Test2 + theme(axis.title.x = element_blank(), axis.ticks.x = element_blank(), axis.text.x = element_blank()),
plots$Test3, ncol = 1)

gghighlight prints label_key

I am plotting a bar graph using ggplot2 and highlighting particular bars using gghighlight.
But using gghighlight prints some label_key also in the output.
I want to remove the label_key printed on top plot.
Please help.
ggplot(data=plot, aes(x=subdomain_name, y=mean)) +
geom_bar(stat="identity", color="blue", fill="blue",width = nrow(plot)/10)+
geom_text(aes(label=format(round(mean,2))),hjust=0)+
coord_flip() + theme(axis.line = element_blank(),axis.line.x = element_blank(),
axis.line.y = element_blank(),plot.margin=unit(c(-0.6,1,1,1),"cm"),
panel.background=element_blank(),panel.border=element_blank(),
axis.title.x = element_blank(),axis.title.y = element_blank() )
+ylim(0,max+(0.05*max)) + gghighlight(grepl('Domain',subdomain_name),
unhighlighted_colour = alpha("red",1),
label_key = NULL))
In this case, you need use_direct_label = FALSE.
library(ggplot2)
library(gghighlight)
plot <- data.frame(
subdomain_name = c(paste("Domain ", letters[1:3]), "foo"),
mean = 1:4
)
max <- 4
ggplot(data = plot, aes(x = subdomain_name, y = mean)) +
geom_bar(stat = "identity", color = "blue", fill = "blue", width = nrow(plot) / 10) +
geom_text(aes(label = format(round(mean, 2))), hjust = 0) +
coord_flip() +
theme(
axis.line = element_blank(), axis.line.x = element_blank(),
axis.line.y = element_blank(), plot.margin = unit(c(-0.6, 1, 1, 1), "cm"),
panel.background = element_blank(), panel.border = element_blank(),
axis.title.x = element_blank(), axis.title.y = element_blank()
) +
ylim(0, max + (0.05 * max)) +
gghighlight(grepl("Domain", subdomain_name),
unhighlighted_colour = alpha("red", 1),
use_direct_label = FALSE
)
Created on 2018-12-23 by the reprex package (v0.2.1)
You should set label_key to F like this: You can also try using ?guides
library(gghighlight)
ggplot(data=plot, aes(x=subdomain_name, y=mean)) +
geom_bar(stat="identity", color="blue", fill="blue",width = nrow(plot)/10)+
geom_text(aes(label=format(round(mean,2))),hjust=0)+
coord_flip() + theme(axis.line = element_blank(),axis.line.x = element_blank(),
axis.line.y = element_blank(),plot.margin=unit(c(-0.6,1,1,1),"cm"),
panel.background=element_blank(),panel.border=element_blank(),
axis.title.x = element_blank(),axis.title.y = element_blank() )
+ylim(0,max+(0.05*max)) + gghighlight(grepl('Domain',subdomain_name),
unhighlighted_colour = alpha("red",1),
label_key = F))

geom_text labelling bars incorrectly

I am trying to create a graph in R with ggplot. The graph is fine until I try to add labels with geom_text.
Data:
year <-c(2016,2017,2016,2017,2016,2017,2016,2017,2016,2017,2016,2017,2016,2017)
age <- c("0-15","0-15","16-25","16-25","26-35","26-35","36-45","36-45","46-55","46-55","56-65","56-65","66+","66+")
deaths <- c(10,4,40,33,38,28,23,22,18,22,13,16,44,33)
age_group <- factor(age)
fyear <- factor(year)
ideaths <- data.frame(fyear,age_group,deaths)
This is the code I have so far
ggplot(data = ideaths,mapping = aes(x = age_group, y=deaths,
fill=fyear)) +
geom_bar(position = "dodge", stat="identity", width=0.5) +
geom_text(label=deaths,vjust=-0.5) + ggtitle("Figure 8.") +
scale_fill_manual(values=c("#7F7F7F","#94D451")) +
scale_y_continuous(breaks=seq(0,55,5)) + theme_light() +
theme(panel.border = element_blank(), panel.grid.major.x =
element_blank(), panel.grid.minor.y =
element_blank(),panel.grid.major.y = element_line( size=.1,
color="grey"), axis.title = element_blank(), legend.position
= "bottom", legend.title=element_blank(), plot.title
=element_text(size=10))
Which gives me this graph:
I searched for how to align the labels with the bars and found position=position_dodge(width=0.9)
However, this puts the label over the wrong bar for me.
If anyone has any idea of how to fix this, or what is causing it in the first place it would be greatly appreciated!
You need to put label = deaths inside aes() so ggplot knows that it needs to use the deaths column inside ideaths data frame not the standalone deaths vector
library(ggplot2)
ggplot(data = ideaths, aes(x = age_group, y = deaths, fill = fyear)) +
geom_col(position = position_dodge(width = 0.9)) +
geom_text(aes(x = age_group, y = deaths + 3, label = deaths),
position = position_dodge(width = 0.9)) +
ggtitle("Figure 8.") +
scale_fill_manual(values = c("#7F7F7F", "#94D451")) +
scale_y_continuous(breaks = seq(0, 55, 5)) +
theme_light() +
theme(
panel.border = element_blank(),
panel.grid.major.x = element_blank(),
panel.grid.minor.y = element_blank(),
panel.grid.major.y = element_line(size = .1, color = "grey"),
axis.title = element_blank(), legend.position = "bottom",
legend.title = element_blank(), plot.title = element_text(size = 10)
)
Created on 2018-11-19 by the reprex package (v0.2.1.9000)

change line type in ggplot2 in r

I have a data frame like this.
df <- data.frame(date = c('2015-11-23','2015-11-24','2015-11-25','2015-11-23','2015-11-24','2015-11-25'),
variable = c('LCNB', 'LCNB','LCNB','LCDEF','LCDEF','LCDEF'),
value = c(1,2,3,3,2,1))
I want to plot two lines in the same plot, with different color and line types. my current code is:
library(scales)
ggplot(df, aes(x=as.Date(date), y=value, color=variable)) + geom_line(size=1.07) +
scale_color_manual(labels = c("Nb",'Def'), values = c("#E69F00", "#0072B2")) +
scale_x_date(labels = date_format("%Y-%m-%d"), breaks = date_breaks("2.8 month")) +
theme(axis.text.x = element_text(angle = 0, vjust = 0.5, hjust=1))+labs(x="Dates",y="%") +
theme_bw()+
theme( panel.grid.major = element_blank(),panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"),plot.margin=unit(c(0,1,0.3,1), "cm")) +
labs(colour = "LC") + theme(legend.position = c(0.95,0.85))
my code so far only makes two lines different color, how can i make them differnt line types as well.
Thank you for the help,
You just need to take the same steps with line type as you did with color, but for linetype:
ggplot(df, aes(x=date, y=value, color=variable, linetype = variable)) +
geom_line(size=1.07,) +
scale_color_manual(
labels = c("Nb",'Def'),
values = c("#E69F00", "#0072B2")
) +
scale_linetype(labels = c("Nb", "Def")) +
scale_x_date(labels = date_format("%Y-%m-%d"), breaks = date_breaks("2.8 month")) +
theme(axis.text.x = element_text(angle = 0, vjust = 0.5, hjust=1)) +
labs(x="Dates",y="%", colour = "LC", linetype = "LC") +
theme_bw()+
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.line = element_line(colour = "black"),
plot.margin=unit(c(0,1,0.3,1), "cm"),
legend.position = c(0.95,0.85))

Add legend to ggplot object (why two legends?)

I created a ggplot2 object:
a <- replicate(8,rnorm(100))
colnames(a) <- letters[1:8]
b < -melt(a,id.vars=1:1)
colnames(b) <- c("c","variable","value")
ggplot(b,aes(x = c,y = value, colour = variable, linetype = variable)) +
geom_line()+
geom_point(aes(shape = factor(variable)), size = 1.7) +
scale_x_continuous(limits = c(-1, 1),
breaks = seq(-1, 1, 0.1),
expand=c(0.01, 0.01)) +
scale_y_continuous(limits = c(-1, 1),
breaks = seq(-1, 1, 0.1),
expand = c(0.01, 0.01))+
theme_bw(base_size = 12, base_family = "Helvetica") +
theme(axis.text=element_text(size = 10),
axis.title=element_text(size = 10),
text = element_text(size = 10),
axis.line = element_line(size = 0.25),
axis.ticks=element_line(size = 0.25),
panel.grid.major = element_blank(),
#panel.grid.minor = element_blank(),
panel.border = element_rect(colour = "black", fill = NA, size = 0.5),
panel.background = element_blank(),
legend.position = "top" ,
legend.direction = "vertical",
legend.title = element_blank(),
legend.text = element_text(size = 13),
legend.background = element_blank(),
legend.key = element_blank()) +
labs(x = '', y = '', title = "") +
theme(plot.title = element_text(size=10)) +
theme(strip.text.x = element_text(size = 8,color="black"),
strip.background = element_blank()) +
theme(strip.text.x = element_text(size = 8, colour = "black"))
My problem is the following:
when I create the legend, there is a separate legend for the colors and a separate one for the points.
How can I create a single legend for each of the 8 variables?
Let me minimise your code and focus on the legend issue. This is what you have now.
ggplot(b,aes(x = c, y = value, colour = variable, linetype = variable)) +
geom_line() +
geom_point(aes(shape = factor(variable)),size=1.7)
Your data frame, b has variable as factor. You use this in two ways here; variable and factor(variable). You can simply use variable for shape in geom_point; make all variable identical.
ggplot(b,aes(x = c, y = value, colour = variable, linetype = variable)) +
geom_line()+
geom_point(aes(shape = variable),size = 1.7)
I saw some warning messages related to colours and other things. You may want to take care of them. But, for legend, this is one way to go.
Take from the ideas on this page: http://www.cookbook-r.com/Graphs/Legends_(ggplot2)/#modifying-the-text-of-legend-titles-and-labels
I edited your code to make the data visible (you had problems with your x-axis limits. Note the final three lines. These commands tell ggplot to create only one legend.
a<-replicate(6,rnorm(100))
colnames(a)<-letters[1:6]
b<-melt(a,id.vars=1:1)
colnames(b)<-c("c","variable","value")
ggplot(b,aes(x=c,y=value,colour=variable,linetype=variable)) +
geom_line() + geom_point(aes(shape=factor(variable)),size=1.7)+
scale_x_continuous(limits=c(0,100))+
scale_y_continuous(limits=c(-2,2),breaks=seq(-2,2,0.1),expand=c(0.01,0.01))+
theme_bw(base_size=12, base_family="Helvetica") +
theme(axis.text=element_text(size=10),
axis.title=element_text(size=10),
text = element_text(size=10),
axis.line = element_line(size=0.25),
axis.ticks=element_line(size=0.25),
panel.grid.major = element_blank(),
#panel.grid.minor = element_blank(),
panel.border = element_rect(colour="black",fill=NA,size=0.5),
panel.background = element_blank(),
legend.position="top" ,
legend.direction="vertical",
legend.title=element_blank(),
legend.text=element_text(size=13),
legend.background=element_blank(),
legend.key=element_blank())+
labs(x='', y='',title="")+
theme(plot.title=element_text(size=10))+
theme(strip.text.x = element_text(size = 8,color="black"),strip.background=element_blank())+
theme(strip.text.x = element_text(size = 8,color="black"))+
scale_colour_discrete(name ="Factor")+
scale_linetype_discrete(name ="Factor") +
scale_shape_discrete(name ="Factor")

Resources