I've been working with this code for a while but this is the first time I've only had two categories on my x-axis. For some reason, R will not space out the bins and instead bunches them at the beginning. How do I evenly spread them along the x-axis?
xlabels<-c("A","B")
CTplot <- ggplot(CTsum, aes(x=Treatment, y=FI)) +
geom_col(fill="lightsteelblue") +
scale_x_discrete(labels= xlabels)+xlab("")+ylab("")+
theme(panel.background = element_blank(),axis.line = element_line(colour = "black"),axis.text.x = element_text(size=20,color="black"), axis.text.y = element_text(size=20, color="black"), axis.title.x = element_text(size=25), axis.title.y = element_text(size=25))+
geom_errorbar(aes(ymin = FI - meanse, ymax = FI + meanse, width=0.2))+
annotate("text",x=1,y=0.84, label="A",size=5)+
annotate("text",x=2,y=0.62, label="B",size=5)+
annotate("text",x=3,y=0.29, label="",size=5)+
annotate("text",x=4,y=0.26, label="",size=5)+
annotate("text",x=0.65,y=0.5, label="",size=15)
CTplot
When you plot categorical data on the x axis, you are "really" plotting at integer values x = 1, x = 2, etc, but with the text labels used in place of numbers. This is what allows you to put text annotations at x = 1 and x = 2.
However, the bars are bunched at the left because you have added two empty text annotations over to the right (at position x = 3 and x = 4). The plot has expanded right to accommodate them. Since they are empty anyway, you don't need them. Here is the plot without them:
CTplot <- ggplot(CTsum, aes(Treatment, FI)) +
geom_col(fill = "lightsteelblue") +
geom_errorbar(aes(ymin = FI - meanse, ymax = FI + meanse, width = 0.2)) +
scale_x_discrete(labels = xlabels) +
xlab("") +
ylab("") +
theme(panel.background = element_blank(),
axis.line = element_line(colour = "black"),
axis.text.x = element_text(size=20,color="black"),
axis.text.y = element_text(size=20, color="black"),
axis.title.x = element_text(size=25),
axis.title.y = element_text(size=25))+
annotate("text",x=1,y=0.84,label="A",size = 5) +
annotate("text",x=2,y=0.62,label="B",size = 5)
CTplot
And here it is with an empty annotation at x = 4:
CTplot + annotate("text",x = 4, y = 0.29, label = "", size = 5)
To emphasise the point, let's see an empty annotation at x = 20:
CTplot + annotate("text",x = 20, y = 0.29, label = "", size = 5)
As you can see, the x axis has had to expand to accommodate the invisible text annotation at x = 20.
If you want the bars a bit more spread out, you can do something like:
CTplot <- ggplot(CTsum, aes(Treatment, FI)) +
geom_col(fill = "lightsteelblue", width = 0.6) +
geom_errorbar(aes(ymin = FI - meanse, ymax = FI + meanse, width = 0.2)) +
scale_x_discrete(labels = xlabels, expand = c(0.75, 0)) +
xlab("") +
ylab("") +
theme(panel.background = element_blank(),
axis.line = element_line(colour = "black"),
axis.text.x = element_text(size=20,color="black"),
axis.text.y = element_text(size=20, color="black"),
axis.title.x = element_text(size=25),
axis.title.y = element_text(size=25))+
annotate("text",x=1,y=0.84,label="A",size = 5) +
annotate("text",x=2,y=0.62,label="B",size = 5)
CTplot
Data used (approximated from image in OP)
CTsum <- data.frame(Treatment = c("A", "B"), FI = c(0.71, 0.48), meanse = 0.1)
Related
How can I increase vertical spacing between legend keys:
p1 <- ggplot(data = HSS, mapping = aes(x = EVENT, y = HSS, fill = TIME)) +
geom_bar(stat = "identity",width=0.7, colour = "black", position = position_dodge(0.7)) +
scale_fill_manual("HSS", values = c("deepskyblue3", "indianred2"),
labels = c("1200 UTC (0.049)", "0000 UTC (0.031)")) + theme_bw()
p1 <- p1 + scale_y_continuous(expand = expansion(mult = c(0.0085, -0.085)),
limits = c(-0.03,0.5), breaks = c(-0.03,-0.01, 0.01, 0.03, 0.05, 0.07,0.09,0.11,0.13,0.15,0.17,
0.19, 0.21,0.23,0.25,0.27,0.29,0.31,0.33,0.45),
labels = c("-0.03","-0.01","0.01","0.03","0.05","0.07","0.09","0.11","0.13","0.15","0.17",
"0.19","0.21","0.23","0.25","0.27","0.29","0.31","0.33","0.45")) +
theme(axis.text.x=element_text(color = "black", size=12, face = "bold", angle=90, vjust=.5,
hjust=0.8)) +
theme(axis.text.y = element_text(color = "black", size=12, face = "bold"))
p1 <- p1 + theme( axis.line = element_line(colour = "black", size = 0.5, linetype = "solid")) +
labs( y = "HSS")
p1 <- p1 + theme(axis.title=element_text(colour = "blue2" ,size=14,face="bold", vjust = 0.1))
p1 <- p1 + theme(legend.position=c(0.98,0.98)) + theme(legend.title=element_blank(),
legend.text = element_text(face = "bold", size = "12"),
legend.box.background = element_rect(size=0.7, linetype="solid"),
legend.justification = c("right", "top"),
legend.box.margin = margin(1, 1, 1, 1)
)
p1
I tried using legend.key.height legend.spacing.y guide but it only stretched legend keys without adding space between them. Also how can I remove alternate lables (encircled) of Y-axis keeping tickmark with plot.
After browsing ggplot2's source code for a bit, I come to the conclusion that the legend.spacing.y is only applied when the byrow = TRUE as argument to the legend.
Simplied example below.
library(ggplot2)
ggplot(iris, aes(Sepal.Width)) +
geom_density(aes(fill = Species)) +
guides(fill = guide_legend(byrow = TRUE)) +
theme(legend.spacing.y = unit(1, "cm"))
With regards to the labels, just remove the values from the breaks argument in scale_y_continuous() that you don't want to show, you're already specifying them manually.
I made to build this chart with ggalluvial but I couldn't manage to put the labels in a proper way that is not overlapping. Does anyone know what I can do to make it better? I was thinking in make the space between the bars wider but I didn't manage to do it.
So far I did this:
ggplot(data = alluvialTransposedNA,
aes(x = x, stratum = stratum, alluvium = id,
y = Freq, fill = Agency, label = stratum)) +
scale_x_discrete(expand = c(.1, .1)) +
scale_y_continuous(expand = c(.2, .2)) +
geom_alluvium(aes(fill = Agency), width = 1/6) +
geom_stratum(width = 1/3, alpha = 1.5) + +
geom_label(stat = "stratum", aes(label = after_stat(stratum)),size=2) +
theme(legend.position = "bottom",
axis.text.x = element_text(angle = 45, vjust = 0.75, hjust=1),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
axis.ticks = element_blank(),
plot.title = element_text(hjust = 0.5)) +
guides(fill=guide_legend(override.aes = list(color=mycolors[1:2])))+
ggtitle("Evolution topics during covid-19")
Considering the following data, I am able to generate a plot which describes how the risk of a react over a time interval changes.
risk_1 <- c(0.121,0.226,0.333,0.167,0.200,0.273,0.138,0.323,0.394,0.250,0.200,0.545,0.190,0.355,0.515,0.333,0.300,0.818)
risk_minus_SE <- c(0.060,0.114,0.198,0.047,0.057,0.097,0.072,0.186,0.247,0.089,0.057,0.280,0.109,0.211,0.352,0.138,0.108,0.523)
risk_plus_SE <- c(0.229,0.398,0.504,0.448,0.510,0.566,0.249,0.499,0.563,0.532,0.510,0.787,0.309,0.531,0.675,0.609,0.603,0.949)
Status <- rep(c(rep('With placebo',3),rep('With drug',3)),3)
durtn <- rep(c('(3-15]','(15-30]','(30-46]'),6)
react <- c(rep("x\u226516",6),rep("x\u226509",6),rep("x\u226504",6))
df1 <- data.frame(risk_1, risk_minus_SE, risk_plus_SE, Status, durtn, react)
dodge <- position_dodge(width=0.45)
ggplot(df1,aes(colour=react, y=risk_1, x=durtn)) +
geom_point(aes(shape=durtn), shape=16, size = 5, position=dodge) +
geom_errorbar(aes(ymin=risk_minus_SE, ymax=risk_plus_SE), position = dodge, width=0.5, size=1, lty=1) +
scale_colour_manual(values = c('black','red','blue')) +
facet_grid(~Status) +
scale_shape_manual(values = c(8,19))+
theme_bw() +
scale_x_discrete(limits=c('(3-15]','(15-30]','(30-46]')) +
coord_cartesian(ylim = c(0, 0.8)) +
theme(legend.position = c(.1, .85), legend.background = element_rect(colour = "black"),
plot.title = element_text(lineheight=1.5, face="bold", size=rel(1.5), hjust = 0.5),
panel.grid.major.x = element_blank(),
axis.text.x = element_text(vjust=0.5, size=16),
axis.text.y = element_text(vjust=0.5, size=16),
axis.title.y = element_text(size=20),
axis.title.x = element_text(size=20),
legend.text = element_text(size = 16, face = "bold"),
strip.text = element_text(size=25)) +
xlab("\ntime (min)") + ylab("Risk")
What I want to do is overlay a series of points at given x and y coordinates.
That being at With drug & durtn==(3,15], manually insert points at.....
Risk==0.5 for react=x≥04 in black
Risk==0.2 for react=x≥09 in red
Risk==0.0 for react=x≥16 in blue
Such that the desired output should look like
How does one use the geom_point() in combination with a facet_grid and dodge
First, you have to create a separate data frame that contains the data for the additional points.
dat <- data.frame(risk_1 = c(0.5, 0.2, 0),
react = levels(df1$react),
durtn = '(3-15]',
Status = 'With drug')
This new data frame dat can be used with geom_point to add an additional layer to the existing plot.
+ geom_point(data = dat, position = dodge, shape = 4, size = 5, show.legend = FALSE)
I would like to know if it's possible to modify the ticks of x axis with a ggplot pie chart.
Here what I can do :
# Some colors
couleurs <- data.frame(
id=seq(1,17,1),
mix=c(c(rep(1,6),rep(2,7),rep(3,4))),
html=c("#A00020","#109618","#388EE4","#C484D1","#FFAA33","#CCCDD0","#004AC5","#F80094","#CB5023","#638995","#33CFCF","#95DC4E","#F7D633","#5C403C","#F72020","#00D96C","#FDE4C5")
)
couleurs$html <- factor(couleurs$html, levels = couleurs$html[order(couleurs$id, decreasing = FALSE)])
# Data
activite <- data.frame(label=c("B to B","B to C","B to B / B to C", "B to B"), cible=c(rep("Externe",3), "Interne"), nb=c(12,9,3,12))
activite$label <- factor(activite$label, levels = activite$label[order(activite$nb[activite$cible=="Externe"], decreasing = TRUE)])
library(plyr)
activite<-ddply(activite,.(cible),transform,pc=(nb/sum(nb))*100)
activite
# Pie chart
library(ggplot2)
ggplot(data = activite, aes(x = "", y = nb, fill = label )) +
geom_bar(stat = "identity", position = position_fill(), width = 1) +
coord_polar(theta= "y", start = 0, direction = -1) +
labs(fill="") +
scale_fill_manual(values=as.character(couleurs$html[1:nrow(activite)]), labels=paste(activite$label,"\t\t\t",sep="")) +
geom_text(aes(label = paste(pc,"%", sep=" ")), size=4, colour = "white", fontface = "bold", position = position_fill(vjust = 0.5)) +
theme(strip.text = element_text(size=20, face = "bold", ), strip.background = element_rect(fill="grey75")) +
theme(panel.background = element_rect(fill = "white")) +
theme(plot.background = element_rect(fill = "grey92")) +
theme(legend.position="bottom", legend.background = element_rect(fill="grey92")) +
theme(legend.key = element_blank()) +
theme(panel.grid.minor = element_blank(), panel.grid.major = element_line(colour = "grey75")) +
theme(axis.text.y = element_blank()) +
theme(axis.ticks.length = unit(0, "mm")) +
theme(axis.title.x = element_blank(),axis.title.y = element_blank()) +
theme(legend.box.spacing = unit(1, "mm")) +
facet_wrap(~ cible)
Here my result:
After several hours of serach, I didn't find a solution to create what I want. The exact same pie chart but with personalised ticks like that :
With these particular conditions :
- do not change the direction of the data in the pie chart, I want it like exactly this
- if possible (but if not possible, it's okay), I would like the ticks' labels not superposed with the axis.
If someone can help me, I would really appreciate.
Here's one solution:
ggplot(data = activite %>%
group_by(cible) %>%
arrange(desc(nb)) %>%
mutate(axis.label = cumsum(nb),
axis.position = cumsum(pc)/100) %>%
mutate(axis.label = ifelse(pc == min(pc),
paste(axis.label, "0", sep = "-"),
axis.label)),
aes(x = 1, y = nb, fill = label )) +
geom_segment(aes(x = 1, xend = 1.6, y = axis.position, yend = axis.position),
colour = "grey75") +
geom_vline(xintercept = 1.6, colour = "grey75") +
geom_bar(stat = "identity", position = position_fill(reverse = T), width = 1) +
coord_polar(theta= "y", start = 0, direction = 1) +
labs(fill="") +
scale_fill_manual(values=as.character(couleurs$html[1:nrow(activite)]), labels=paste(activite$label,"\t\t\t",sep="")) +
geom_text(aes(label = paste(pc,"%", sep=" ")), size=4, colour = "white",
fontface = "bold", position = position_fill(vjust = 0.5, reverse = T)) +
geom_text(aes(x = 1.7, label = axis.label), size = 3,
position = position_fill(reverse = T)) +
theme(strip.text = element_text(size=20, face = "bold", ), strip.background = element_rect(fill="grey75")) +
theme(panel.background = element_rect(fill = "white")) +
theme(plot.background = element_rect(fill = "grey92")) +
theme(legend.position="bottom", legend.background = element_rect(fill="grey92")) +
theme(legend.key = element_blank()) +
theme(panel.grid = element_blank()) +
theme(axis.text = element_blank()) +
theme(axis.ticks = element_blank()) +
theme(axis.title = element_blank()) +
theme(legend.box.spacing = unit(1, "mm")) +
facet_wrap(~ cible)
Explanation:
The sequence in your labels went clockwise, while the direction of the polar coordinates went counter-clockwise. That makes labelling rather troublesome. I switched the direction for polar coordinates, & added reverse = T inside the position adjustment calls for the geoms.
It's hard to assign different axis breaks to different facets of the same plot, so I didn't. Instead, I modified the data to include calculated axis labels / margin positions, added margins via geom_segment / geom_vline, & hid the axis text / ticks in theme().
I made horizontal barplot. I need to move x-axis up, so it is placed not under the last bar, but under some bar, picked based on other criterion.
I've tried some things, like gtable, but with no success. I would appreciate any help.
This is a picture that illustrats what I want to achieve:
Here is the code to produce sample horizontal barplot:
library("ggplot2")
library("RColorBrewer")
colours <- brewer.pal(11, "RdYlGn")[3:9]
no.names <- 4
name.percentage <- data.frame(name = paste0(LETTERS[1:no.names], letters[1:no.names], sample(LETTERS[1:no.names], size = no.names, replace = TRUE )), percentage = 0.85 + runif(no.names, 0, 0.15))
name.percentage <- rbind(
transform(name.percentage, type = 1, fill = cut(percentage, breaks = c(-Inf,(1:6 * 3 + 81)/100, Inf), right = T, labels = colours)),
transform(name.percentage, percentage = 1 - percentage, type = 2, fill = "#EEEEEE")
)
plot <- ggplot(data = name.percentage,
aes( x = name, y = percentage, fill = fill)) +
geom_bar(stat = "identity", position = "stack", width = 0.75) +
scale_fill_identity(guide = "none") +
labs(x = NULL, y = NULL) +
scale_y_continuous(expand = c(0,0)) +
scale_x_discrete(expand = c(0,0)) +
coord_flip() +
theme_classic() +
theme(axis.ticks.y = element_blank(),
axis.text.y = element_text(size = 11, colour = "black" ),
axis.text.x = element_text(size = 11, colour = "black" ),
axis.line = element_blank(),
plot.margin = grid::unit(c(5,5,5,5),"mm"),
aspect.ratio = ((no.names %% 30) / 30 ) * 1.70)
print(plot)
You could create two separate plots first, removing the axis ticks and labels in one of them entirely:
plot1 <- ggplot(data = subset(name.percentage, name=="AaC" | name=="BbA"),
aes( x = name, y = percentage, fill = fill)) +
geom_bar(stat = "identity", position = "stack", width = 0.75) +
scale_fill_identity(guide = "none") +
labs(x = NULL, y = NULL) +
scale_y_continuous(expand = c(0,0)) +
scale_x_discrete(expand = c(0,0)) +
coord_flip() +
theme_classic() +
theme(axis.ticks.y = element_blank(),
axis.text.y = element_text(size = 11, colour = "black" ),
axis.text.x = element_blank(),
axis.line=element_blank(),
axis.ticks=element_blank(),
axis.title.x=element_blank(),
axis.title.y=element_blank(),
aspect.ratio = ((no.names %% 30) / 30 ) * 1.70)
plot2 <- ggplot(data = subset(name.percentage, name=="CcA" | name=="DdD"),
aes( x = name, y = percentage, fill = fill)) +
geom_bar(stat = "identity", position = "stack", width = 0.75) +
scale_fill_identity(guide = "none") +
labs(x = NULL, y = NULL) +
scale_y_continuous(expand = c(0,0)) +
scale_x_discrete(expand = c(0,0)) +
coord_flip() +
theme_classic() +
theme(axis.ticks.y = element_blank(),
axis.text.y = element_text(size = 11, colour = "black" ),
axis.text.x = element_text(size = 11, colour = "black" ),
axis.line = element_blank(),
aspect.ratio = ((no.names %% 30) / 30 ) * 1.70)
Then you can use plot_grid from package cowplot to arrange the two plots, with align="h" aligning both plots horizontally:
library(cowplot)
plot_grid(plot2, plot1, align="h", ncol=1)