I want to give each facet an alpha code, from A to H since there are eight facets, and draw each code on the top-left of each facet:
ggthemr('dust', layout = 'scientific',
spacing = 1, type = 'inner', line_weight = 0.6,
)
ptitles <- c('A' = "Total mass (g)", 'B' = "Root mass (g)", 'C' = "Stem mass (g)",
'D' = "Leaf mass (g)", 'E' = "Number of nodes",
'F' = "Number of leaves", 'G' = "Total stem length (cm)", 'H' = "RDI")
ggplot(gtr, aes(sediment, value)) +
geom_boxplot(aes(fill = nitrogen)) +
geom_text(aes(label = trait, group = trait)) +
facet_wrap(~trait, scales = "free_y", ncol = 2,
labeller = as_labeller(ptitles),
strip.position = "left"
) +
theme(legend.position = "bottom",
legend.title = element_text(size = 12),
legend.key.size = unit(2, "lines"),
legend.text = element_text(size = 12),
strip.text.x = element_text(size = 12, margin = margin(0, 0, 0, 10)),
strip.text.y = element_text(size = 14),
strip.placement = "outside",
axis.title.y = element_text(size = 14),
axis.title.x = element_text(size = 14),
axis.text.x = element_text(size = 14),
panel.spacing.x = unit(0.5, "lines"),
panel.spacing.y = unit(0.3, "lines"),
aspect.ratio = 2 / 3
) +
xlab("Effects of sediment type and nitrogen deposition") +
ylab(NULL)
I tried to use geom_text():
geom_text(aes(label = trait, group = trait))
(Here the variable trait stores factors from A to H to distinguish each facet)
But it did not work like what I expected:
Is there a simple way to such a thing?
UPDATE:
According to baptiste's answer, I changed my geom_text() code above to below:
geom_text(aes(x = -Inf, y = Inf, label = trait, group = trait),
size = 5,
hjust = -0.5,
vjust = 1.4,
inherit.aes = FALSE)
inherit.aes = FALSE here seems to do nothing, how does this parameter work?.
Now my plot looks good:
library(ggplot2)
d <- data.frame(x=rep(1:3, 4), f=rep(letters[1:4], each=3))
labels <- data.frame(f=letters[1:4], label=LETTERS[1:4])
ggplot(d, aes(x,x)) +
facet_wrap(~f) +
geom_point() +
geom_label(data = labels, aes(label=label),
x = Inf, y = -Inf, hjust=1, vjust=0,
inherit.aes = FALSE)
Related
I have a dataset and I want to plot the heat map for them. my problem is: I want a vertical legend and also I want to put the title of legend in the middle of legend.
My data is a text file with is like the attached figure.
Here is the code that I am using( when I change the horizontal to the vertical, the legend moves up and also the title is not in the center of legend).
# Heatmap
ggplot(heat, aes(Samples, Gene, fill= log(Folded_Change_of_Expression))) +
geom_tile()+
theme(axis.text.x = element_text(angle = 90))+ theme(axis.text.y =
element_text(size = 12)) +
coord_fixed(ratio = 4)+theme(panel.background = element_blank()) +
theme(axis.title = element_text(size = 16)) +
guides(fill = guide_colourbar(barwidth = 5, barheight = 1, title = "log(Folded
Change of Expression)",
title.position = "top", direction = "horizontal"))
However, the output figure for me is not the thing that I want. Could you please help me with that?
Thank you
Legend that I want is same as this:
Here is one suggestion:
New added last 3 lines remove existent guides lines:
library(tidyverse)
ggplot(heat, aes(Samples, Gene, fill= log(Folded_Change_of_Expression))) +
geom_tile()+
theme(axis.text.x = element_text(angle = 90))+
theme(axis.text.y = element_text(size = 12)) +
coord_fixed(ratio = 4)+
theme(panel.background = element_blank()) +
theme(axis.title = element_text(size = 16)) +
scale_fill_continuous(guide = "colourbar") +
theme(legend.title = element_text(angle = 90, hjust = 0.5, vjust = 0.5)) +
guides(fill = guide_legend(title.position = "right",
title = "log(Folded Change \n of Expression)"))
Perhaps the only way to 'center' the colourbar and title is for the colourbar to be larger than the legend title, e.g.
library(tidyverse)
heat <- data.frame(Samples = rep(c(paste("Control", 1:10, sep = "_"),
paste("Treat", 1:10, sep = "_")), each = 2),
Gene = c("Occludin", "Claudin"),
Folded_Change_of_Expression = runif(20, -4, 4))
ggplot(heat, aes(x = Samples, y = Gene, fill = log(abs(Folded_Change_of_Expression)))) +
geom_tile() +
coord_fixed(ratio = 4) +
theme(axis.text.x = element_text(angle = 90),
axis.text.y = element_text(size = 12),
panel.background = element_blank(),
axis.title = element_text(size = 16),
legend.direction = "vertical",
legend.box = "vertical",
legend.title = element_text(angle = 90,
hjust = 0.5,
vjust = 0.5),
legend.justification = c(0.5, 0.5)) +
guides(fill = guide_colourbar(title = "log(Fold Change in Gene Expression)",
title.position = "right",
title.hjust = 0.5,
title.vjust = 0.5,
legend.title.align = 0.5,
barheight = 14))
When the legend title is longer than the colourbar it appears to 'fall back' on a default justification. I've had a look at the source code for guide_colourbar (https://rdrr.io/github/SahaRahul/ggplot2/src/R/guide-colorbar.r) but it's not clear to me why this is the case. If you make the legend title smaller, it is positioned as expected:
library(tidyverse)
heat <- data.frame(Samples = rep(c(paste("Control", 1:10, sep = "_"),
paste("Treat", 1:10, sep = "_")), each = 2),
Gene = c("Occludin", "Claudin"),
Folded_Change_of_Expression = runif(20, -4, 4))
ggplot(heat, aes(x = Samples, y = Gene, fill = log(abs(Folded_Change_of_Expression)))) +
geom_tile() +
coord_fixed(ratio = 4) +
theme(axis.text.x = element_text(angle = 90),
axis.text.y = element_text(size = 12),
panel.background = element_blank(),
axis.title = element_text(size = 16),
legend.direction = "vertical",
legend.box = "vertical",
legend.title = element_text(angle = 90,
hjust = 0,
vjust = 0,
size = 8),
legend.justification = c(0, 0.5)) +
guides(fill = guide_colourbar(title = "log(Fold Change in Gene Expression)",
title.position = "right",
title.vjust = 0.5,
barheight = 10))
Created on 2022-06-30 by the reprex package (v2.0.1)
I have the following bubble plot that shows the abundance percentage of microbes across different samples. However, I want to remove the tick labels called "Archaea" and "Other taxa" (located at either ends of the bubble plot) since the labels for both can be placed in the x-axis strip text instead. I used the following code to produce the plot:
ggplot(En.TaxMisc.NoC.RelAb.filtered.tidy$CombinedMisc,
aes(x = factor(Taxonomy, levels = En.TaxMisc.order$Taxonomy),
y = SampleSource, size = RelAb)) +
geom_point(colour = '#abd9e9') +
facet_grid(SampleType ~ Level,
labeller = labeller(SampleType = SampleType.NoC.labels),
scale = 'free', space = 'free') +
scale_x_discrete(name = NULL) +
scale_y_discrete(position = 'left', name = NULL) +
scale_size_continuous(name = str_wrap('Relative abundances (%)', width = 10),
breaks = c(1:8), range = c(0.75, 20)) +
guides(size = guide_legend(nrow = 1)) +
theme(legend.position = 'bottom',
legend.background = element_rect(colour = 'grey70'),
legend.title = element_text(size = 8, hjust = 1),
legend.text = element_text(size = 7, hjust = 0),
legend.spacing.x = unit(2.5, 'mm'),
legend.box = 'horizontal',
strip.background = element_rect(colour = 'grey55'),
strip.text.x = element_text(size = 8),
strip.text.y = element_text(size = 8),
axis.text.x.bottom = element_text(angle = 90, hjust = 1,
vjust = 0.3, size = 8),
axis.text.y.left = element_text(size = 8),
axis.ticks = element_blank(),
panel.grid.major.x = element_line(linetype = 1),
panel.border = element_rect(linetype = 1, fill = NA),
panel.background = element_blank())
I had tried to use scale_x_discrete(labels = c("Archaea" = NULL, "Other taxa" = NULL) but this resulted in all the tick labels being removed. I had also looked into using the rremove() function and the axis_ticks theme components, but neither appear to possess arguments for specifying tick labels.
I'd appreciate suggestions or advice anyone can give me!
There's a fair bit of extraneous detail in the question, but if you're just looking to remove (or customize!) tick labels, all you need is to add a labels argument to scale_x_discrete.
Self-contained example:
library(ggplot2)
ds = data.frame(
xVar = as.factor(rep(LETTERS[1:5],10)),
y = rnorm(50)
)
my_custom_labels = c("","level B","level C","level D!","")
ggplot(data = ds) +
geom_point(aes(x = xVar,y = y)) +
scale_x_discrete(labels = my_custom_labels)
I've got a dataframe I imported from SPSS into R, and I'm having trouble properly formatting the y axis in a ggplot2 percentage bar chart.
I need to constrain the axis range to a smaller amount and also lengthen those bars. This is what I keep getting:
Here's the code for the above visualization:
#import packages
library(foreign)
library(ggthemes)
library(stringr)
library(ggplot2)
library(scales)
#read in data
WBGC <- read.spss("2019.07.14_Cleaned.Data.sav", use.value.label=TRUE, to.data.frame=TRUE)
#define member/non-member datasets
WBGC_members <- subset(WBGC, Freq.Of.Attendance == 'Once a month' | Freq.Of.Attendance == 'A few times a month' | Freq.Of.Attendance == 'Once or twice a week' | Freq.Of.Attendance == '3-5 days a week')
#visualization of race
student_race <- ggplot(data = WBGC_members, aes(x = Race, fill = Gender))
+ theme_hc()
+ geom_bar(colour = "black", stat = "count", aes(y = prop.table(stat(count))), position = position_dodge(), size = 0.5)
+ labs(title = "Student Race", y = "Frequency")
+ scale_y_continuous(labels = percent)
+ geom_label(data = WBGC_members, stat = 'count', aes(label = scales::percent(prop.table(stat(count))), vjust = -0.4, fontface = 'bold'), size = 6, position = position_dodge(0.9), alpha = 1.0, show.legend = FALSE)
+ theme(
plot.title = element_text(size = 16, face = 'bold', family = '', color = 'black', hjust = 0.5, lineheight = 1.2),
axis.title.x = element_blank(),
axis.text.x = element_text(size = 12, angle = 45, vjust = 0.5),
axis.title.y = element_text(size = 14, margin = margin(t = 0, r = 8, b = 0, l = 0)),
axis.text.y = element_text(size = 12),
legend.title = element_text(size = 14, color = "black", face="bold", hjust = 1, lineheight = 4),
legend.text = element_text(size = 13),
legend.position = 'right',
legend.box.background = element_rect(colour = 'black')
)
student_race
Since it looks like the labels are doing OK, I added scales::percent to the aes y= argument in geom_bar and had to delete the scale_y_continuous function. I wound up with this:
Any help is much appreciated. Thanks!
Fixed by adding y = prop.table(stat(count)) to the geom_label function call.
Here's the result:
And final code for reference:
student_race <- ggplot(data = WBGC_members, aes(x = Race, fill = Gender)) +
theme_hc()+
geom_bar(colour = "black", stat = "count", aes(y = prop.table(stat(count))), position = position_dodge(), size = 0.5) +
geom_label(data = WBGC_members, stat = 'count', aes(label = scales::percent(prop.table(stat(count))), y = prop.table(stat(count)), vjust = -0.4, fontface = 'bold'), size = 6, position = position_dodge(0.9), alpha = 1.0, show.legend = FALSE) +
labs(title = "Student Race", y = "Frequency") +
scale_y_continuous(labels = scales::percent, limits = c(0,0.2)) +
theme(plot.title = element_text(size = 16, face = 'bold', family = '', color = 'black', hjust = 0.5, lineheight = 1.2),
axis.title.x = element_blank(),
axis.text.x = element_text(size = 12, angle = 45, vjust = 0.5),
axis.title.y = element_text(size = 14, margin = margin(t = 0, r = 8, b = 0, l = 0)),
axis.text.y = element_text(size = 12),
legend.title = element_text(size = 14, color = "black", face="bold", hjust = 1, lineheight = 4),
legend.text = element_text(size = 13),
legend.position = 'right',
legend.box.background = element_rect(colour = 'black')
)
student_race
I am trying to move the legend text and legend boxes further apart (horizontally) on a box and jitter plot. The complicating factor is the coord_flip I used to make the boxplot horizontal. In theme I tried using both legend.spacing.x and legend.spacing.y but neither had any effect on the distance between legend text and legend boxes.
Here is the graph with fake data. More complex than necessary I know but I need to be able to make it work with all the complications.
library(dplyr)
library(ggplot2)
set.seed(01234)
# make some data
totDays <- data.frame(id = 1:80,
group = rep(c("Placebo", "Drug"), each = 40),
total84 = c(pmin(abs(round(rnorm(40, 55, 30))),84), pmin(abs(round(rnorm(40, 38, 30))),84)))
# get some descriptives
(groupDF <- totDays %>% group_by(group) %>%
dplyr::summarise(m = mean(total84, na.rm = T),
sd = sd(total84, na.rm = T),
count = n()) %>%
mutate(se = sd/sqrt(count)))
# now for the box and scatter plot
(g <- ggplot(totDays, aes(group, total84, colour = group)) +
geom_jitter(size = 1, width = 0.1) + # so points aren't overlaid, width controls how much jitter
geom_point(stat = "summary", fun.y = "mean", shape = 3, size = 3, colour = "black") + # crosses for mean
geom_boxplot(alpha = 0, width = 0.5, lwd = 1, size = 0.5) +
scale_color_manual(values = c("#00AFBB", "#E7B800")) +
scale_y_continuous(breaks = seq(0,84,14), minor_breaks = seq(0, 84, 14)) + # changes minor break line
coord_flip() +
labs(y = "Score") +
geom_hline(yintercept = c(groupDF$m), linetype = "dotted") +
geom_segment(x = 2.38, xend = 2.38, y = groupDF$m[2] + .1, yend = groupDF$m[1] - .1, size = .7, arrow = arrow(end = "both", type = "open", length = unit(0.15, "cm")), colour = "#696969") +
annotate("text", x = 2.46, y = mean(groupDF$m), label = paste0("italic(p) == ", 0.02), parse = T) +
theme_bw() +
theme(axis.title.y = element_blank(),
axis.ticks.y = element_blank(),
axis.text.y = element_blank(),
axis.text.x = element_text(size = 13),
axis.title.x = element_text(size = 13, face = "bold", margin = margin(t = 0, r = 0, b = 10, l = 0), vjust = -2), # note the use of margin to move the title away from the axis text
legend.title = element_blank(),
legend.position = "top",
legend.spacing.y = unit(.1, "cm"),
legend.box.spacing = unit(.1, "cm"), # adjusts distance of box from x-axis
legend.key.size = unit(1, "cm"),
legend.text = element_text(size = 13, face = "bold"),
strip.text = element_text(size = 13, face = "bold"),
panel.grid.major.y = element_blank(),
panel.grid.major.x = element_line(size=.4, color="#F7F7F7")))
Use either stringr::str_pad() or theme(legend.spacing.x = ...) or both
g <- ggplot(totDays, aes(group, total84, colour = group)) +
geom_jitter(size = 1, width = 0.1) + # so points aren't overlaid, width controls how much jitter
geom_point(stat = "summary", fun.y = "mean", shape = 3, size = 3, colour = "black") + # crosses for mean
geom_boxplot(alpha = 0, width = 0.5, lwd = 1, size = 0.5) +
scale_color_manual(values = c("#00AFBB", "#E7B800"),
### added
labels = stringr::str_pad(c("Drug", "Placebo"), 10, "right")) +
scale_y_continuous(breaks = seq(0,84,14), minor_breaks = seq(0, 84, 14)) + # changes minor break line
coord_flip() +
labs(y = "Score") +
geom_hline(yintercept = c(groupDF$m), linetype = "dotted") +
geom_segment(x = 2.38, xend = 2.38, y = groupDF$m[2] + .1, yend = groupDF$m[1] - .1, size = .7,
arrow = arrow(end = "both", type = "open", length = unit(0.15, "cm")), colour = "#696969") +
annotate("text", x = 2.46, y = mean(groupDF$m), label = paste0("italic(p) == ", 0.02), parse = T) +
theme_bw() +
theme(axis.title.y = element_blank(),
axis.ticks.y = element_blank(),
axis.text.y = element_blank(),
axis.text.x = element_text(size = 13),
axis.title.x = element_text(size = 13, face = "bold",
margin = margin(t = 0, r = 0, b = 10, l = 0), vjust = -2),
legend.title = element_blank(),
legend.position = "top",
### added
legend.spacing.x = unit(0.25, 'cm'),
legend.spacing.y = unit(.1, "cm"),
legend.box.spacing = unit(.1, "cm"), # adjusts distance of box from x-axis
legend.key.size = unit(1, "cm"),
legend.text = element_text(size = 13, face = "bold"),
strip.text = element_text(size = 13, face = "bold"),
panel.grid.major.y = element_blank(),
panel.grid.major.x = element_line(size=.4, color="#F7F7F7"))
Created on 2019-03-11 by the reprex package (v0.2.1.9000)
(The images are too be because of my 3k screen, sorry about that)
I've made a plot like below:
For some reasons, I need my ticks on y-axis to start from 0, but omit all ticks in the range from 0 to 40 in the upper one, and start from 0, omit all ticks in the range from 0 to 0.5 in the lower one
For example:
I don't know how to tweak my code in ggplot2, can anyone help?
Here is my code if needed:
ggthemr('fresh', layout = 'scientific',
spacing = 1, type = 'inner', line_weight = 0.6,
)
ggplot(tmb, aes(invasion, mean, color = sediment, linetype = nitrogen)) +
geom_ribbon(
aes(ymin = mean - standard.error, ymax = mean + standard.error, `group = pair),`
alpha = 0.3,
color = NA,
fill = "gray"
) +
geom_line(size = 1) +
geom_point(show.legend = TRUE) +
facet_wrap(~type, scales = "free_y", ncol = 1, strip.position = "left") +
scale_x_discrete(breaks = NULL, expand = c(0, 0.10)) +
scale_color_discrete("Sediment",
labels = c("No", "Yes")
) +
scale_linetype_discrete("Nitrogen",
labels = c("No", "Yes")
) +
theme(legend.position = "bottom",
legend.title = element_text(size = 14),
legend.key.size = unit(2.5, "lines"),
legend.text = element_text(size = 14),
panel.spacing.x = unit(0.5, "lines"),
panel.spacing.y = unit(0.5, "lines"),
axis.text = element_text(size = 14),
strip.text.x = element_text(size = 10),
strip.text.y = element_text(size = 18, margin = margin(0, 0, 0, 5)),
strip.placement = "outside",
axis.title.y = element_text(size = 18),
axis.title.x = element_text(size = 18),
aspect.ratio = 1 / 1) +
xlab("From not invaded to invaded") +
ylab(NULL)
Many thanks.