I have been trying to access the value of ..count.. in ggplot2 is there anyway to access this value? At the moment I'm getting the following error:
Error: Aesthetics must be valid computed stats. Problematic
aesthetic(s): label = ..count... Did you map your stat in the wrong
layer?
How can I access that value that has been computed before? Here's the code:
transfusion %>%
mutate(Group = ifelse(whether.he.she.donated.blood.in.March.2007 == 0, "Didn't donate", "Donated")) %>%
ggplot(aes(x=Group, fill = Group)) +
scale_y_continuous(breaks = seq(0, 500, by = 100)) +
ylab("Count of people") +
ggtitle("People who donated blood in march 2007") +
geom_bar(aes(y = (..count..))) +
geom_label(aes(label = ..count..))
This is a solution using ..count... All you have to do is to ask geom_label to compute it.
library(dplyr)
library(ggplot2)
transfusion %>%
mutate(Group = ifelse(whether.he.she.donated.blood.in.March.2007 == 0, "Didn't donate", "Donated")) %>%
ggplot(aes(x = Group, fill = Group)) +
geom_bar(position = "dodge") +
geom_label(stat = 'count', aes(label = ..count..),
vjust = -0.1,
show.legend = FALSE) +
scale_y_continuous(breaks = seq(0, 500, by = 100)) +
ylab("Count of people") +
ggtitle("People who donated blood in march 2007") +
theme(plot.margin = margin(2, 0.8, 2, 0.8))
Data
set.seed(1234)
transfusion <- data.frame(
whether.he.she.donated.blood.in.March.2007 = rbinom(800, 1, prob = c(0.3, 0.7))
)
Using mtcars as example data this can be achieved by using stat = "count" inside geom_label and using after_stat (new in ggplot2 3.3.0) to map count on label
library(ggplot2)
#mutate(Group = ifelse(whether.he.she.donated.blood.in.March.2007 == 0, "Didn't donate", "Donated")) %>%
ggplot(mtcars, aes(x = factor(cyl), fill = factor(cyl))) +
#scale_y_continuous(breaks = seq(0, 500, by = 100)) +
#ylab("Count of people") +
#ggtitle("People who donated blood in march 2007") +
geom_bar() +
geom_label(aes(label = after_stat(count)), stat = "count")
Created on 2020-04-15 by the reprex package (v0.3.0)
Related
I have this code:
as_tibble(earlyCiliated[[]]) %>%
ggplot(aes(x="", y=Phase, fill=Phase)) + geom_col() +
coord_polar("y", start=0) +
geom_text(aes(label = paste0(Phase, "%")))
and my output looks like this:
What am I doing wrong that's causing the labels to all be on top of each other?
I can't completely recreate your plot because I do not have your data. That being said, you can try this:
install.packages("ggrepel")
library(ggrepel)
as_tibble(earlyCiliated[[]]) %>%
ggplot(aes(x="", y=Phase, fill=Phase)) + geom_col() +
coord_polar("y", start=0) +
geom_label_repel(data = earlyCiliated[[]],
aes(y = Phase, label = paste0(Phase, "%")),
size = 4.5, nudge_x = 1, show.legend = FALSE)
This is what it will look like (using other data because none was provided)
library(ggplot2)
library(ggrepel)
library(tidyverse)
df <- data.frame(value = c(15, 25, 32, 28),
group = paste0("G", 1:4))
# Get the positions
df2 <- df %>%
mutate(csum = rev(cumsum(rev(value))),
pos = value/2 + lead(csum, 1),
pos = if_else(is.na(pos), value/2, pos))
ggplot(df, aes(x = "" , y = value, fill = fct_inorder(group))) +
geom_col(width = 1, color = 1) +
coord_polar(theta = "y") +
scale_fill_brewer(palette = "Pastel1") +
geom_label_repel(data = df2,
aes(y = pos, label = paste0(value, "%")),
size = 4.5, nudge_x = 1, show.legend = FALSE) +
guides(fill = guide_legend(title = "Group")) +
theme_void()
I've made a ggplot, coloured by the hours of incubation. When I add significance bars using geom_signif, they are all coloured by the first colour, here pink. Ideally I'd like to be able to choose the colour of the significance bars, so i can indicate which incubation time they refer to. Or if that's not possible, how would I make them black?
ggplot(data = data, mapping = aes(y = Fluorescence, x = Treatment, colour = Hours)) +
geom_boxplot(outlier.shape = NA) +
geom_jitter(position = position_jitterdodge(jitter.width = 0.3, jitter.height = 0), alpha = 0.4) +
theme(axis.text.x = element_text(angle = 60, hjust = 1)) +
xlab("Treatment") +
ylab("Mean fluorescence") +
ggtitle("C6/36") +
geom_signif(y_position = c(5.8,6.3,2.5,2,1.5,0.5,1),
xmin = c(2,3,2,2.8,1.8,1.8,2.8),
xmax = c(3,4,4,10,3.8,2.8,3.8),
annotations = c("****","****","ns","****","****","ns","**"),
textsize=3.5)
If you set the color mapping only to the boxplot geom, coloring will only applied to this particular geom:
library(tidyverse)
library(ggsignif)
iris %>%
mutate(group = Species %in% c("setosa", "versicolor")) %>%
ggplot(aes(group, Sepal.Length)) +
geom_boxplot(aes(color = Species)) +
geom_jitter(aes(color = Species)) +
geom_signif(comparisons = list(c("TRUE", "FALSE")))
Created on 2021-09-14 by the reprex package (v2.0.1)
I have the following ggplot code that renders the box plot show below.
ggplot(comparisonData, aes(Group,score)) +
geom_boxplot(notch = TRUE, varwidth = TRUE, aes(colour = Group)) +
geom_jitter(width = 0.2, aes(colour = Group)) +
theme(legend.position = "none") +
labs(title="User Engagement Score", x="Condition", y="Score (max 140)")
In this plot I want the groups 1 and 2 on the x-axis to be renamed as "Stealth" and "Non-stealth", but I am not able to find a way to do so. Is it possible without changing the group names in data?
You can change the labels via the scale, e.g.
library(tidyverse)
library(palmerpenguins)
penguins %>%
na.omit() %>%
mutate(species = factor(ifelse(species == "Adelie", 1, 2))) %>%
ggplot(aes(x = species, y = bill_length_mm)) +
geom_boxplot(aes(colour = species), notch = TRUE, varwidth = TRUE) +
geom_jitter(width = 0.2, aes(colour = species)) +
theme(legend.position = "none") +
labs(title="User Engagement Score", x="Condition", y="Score (max 140)") +
scale_x_discrete(label = c("Stealth", "Non-stealth"))
I would like to change the colour of one of my ggrepel labels to black. I have tried to override the inheritance by specifying ...geom_text_repel(...colour='black') but that doesn't seem to work.
My attempt at a fix to the problem is in the second geom_text_repel function (below).
N.B. If there is a way to control the colour of individual geom_text_repel elements, rather than having to call the function twice, I would prefer that.
library("tidyverse")
library("ggthemes")
library("ggrepel")
df1 <- gather(economics, variable_name, observation, -date) %>%
rename(period = date) %>%
filter(variable_name == 'psavert')
df2 <- gather(economics, variable_name, observation, -date) %>%
rename(period = date) %>%
filter(variable_name == 'uempmed')
ggplot(df1, aes(x = period, y = observation, colour = variable_name)) +
geom_line() +
geom_line(data = df2, colour = 'black', size = .8) +
geom_text_repel(
data = subset(df1, period == max(as.Date(period, "%Y-%m-%d"))),
aes(label = variable_name),
size = 3,
nudge_x = 45,
segment.color = 'grey80'
) +
geom_text_repel(
data = subset(df2, period == max(as.Date(period, "%Y-%m-%d"))),
aes(label = variable_name, colour = 'black'), #How do I set the colour of the label text to black?
size = 3,
nudge_x = 45,
segment.color = 'grey80'
) +
scale_y_continuous(labels = scales::comma) +
theme_minimal(base_size = 16) +
scale_color_tableau() +
scale_fill_tableau() +
theme(legend.position = 'none') +
labs(x="", y="", title = "Economic Data") +
scale_x_date(limits = c(min(df1$period), max(df1$period) + 1200))
Do the same thing you did in your geom_line() layer. You want to set a color, not a mapping. Make colour = 'black' an argument to geom_text_repel(), not aes().
ggplot(df1, aes(x = period, y = observation, colour = variable_name)) +
geom_line() +
geom_line(data = df2, colour = 'black', size = .8) + # just like this layer
geom_text_repel(
data = subset(df1, period == max(as.Date(period, "%Y-%m-%d"))),
aes(label = variable_name),
size = 3,
nudge_x = 45,
segment.color = 'grey80'
) +
geom_text_repel(
data = subset(df2, period == max(as.Date(period, "%Y-%m-%d"))),
aes(label = variable_name) # don't assign it here,
size = 3,
nudge_x = 45,
segment.color = 'grey80',
colour = "black" # assign it here
) +
scale_y_continuous(labels = scales::comma) +
theme_minimal(base_size = 16) +
scale_color_tableau() +
scale_fill_tableau() +
theme(legend.position = 'none') +
labs(x="", y="", title = "Economic Data") +
scale_x_date(limits = c(min(df1$period), max(df1$period) + 1200))
Note that now the first line AND text are now both set manually to "black", so the automatic variable assignment will start over with next line (and text). If you want to set that manually to a different color, you can use the same strategy (set it as an argument to the geom, not as an argument to aes
Using mtcars as an example, I've produced some violin plots. I wanted to add two things to this chart:
for each group, list n
for each group, sum a third variable (e.g. wt)
I can do (1) with the geom_text code below although (n) is actually plotted on the x axis rather than off to the side.
But I can't work out how to do (2).
Any help much appreciated!
library(ggplot2)
library(gridExtra)
library(ggthemes)
result <- mtcars
ggplot(result, aes(x = gear, y = drat, , group=gear)) +
theme_tufte(base_size = 15) + theme(line=element_blank()) +
geom_violin(fill = "white") +
geom_boxplot(fill = "black", alpha = 0.3, width = 0.1) +
ylab("drat") +
xlab("gear") +
coord_flip()+
geom_text(stat = "count", aes(label = ..count.., y = ..count..))
You can add both of these annotations by creating them in your dataframe temporarily prior to graphing. Using the dplyr package, you can create two new columns, one with the count for each group, and one with the sum of wt for each group. This can then be piped directly into your ggplot using %>% (alternatively, you could save the new dataset and insert it into ggplot the way you have it). Then with some minor edits to your geom_text call and adding a second one, we can create the plot you want. The code looks like this:
library(ggplot2)
library(gridExtra)
library(ggthemes)
library(magrittr)
library(dplyr)
result <- mtcars
result %>%
group_by(gear) %>%
mutate(count = n(), sum_wt = sum(wt)) %>%
ggplot(aes(x = gear, y = drat, , group=gear)) +
theme_tufte(base_size = 15) + theme(line=element_blank()) +
geom_violin(fill = "white") +
geom_boxplot(fill = "black", alpha = 0.3, width = 0.1) +
ylab("drat") +
xlab("gear") +
coord_flip()+
geom_text(aes(label = paste0("n = ", count),
x = (gear + 0.25),
y = 4.75)) +
geom_text(aes(label = paste0("sum wt = ", sum_wt),
x = (gear - 0.25),
y = 4.75))
The new graph looks like this:
Alternatively, if you create a summary data frame named result_sum, then you can manually add that into the geom_text calls.
result <- mtcars %>%
mutate(gear = factor(as.character(gear)))
result_sum <- result %>%
group_by(gear) %>%
summarise(count = n(), sum_wt = sum(wt))
ggplot(result, aes(x = gear, y = drat, , group=gear)) +
theme_tufte(base_size = 15) +
theme(line=element_blank()) +
geom_violin(fill = "white") +
geom_boxplot(fill = "black", alpha = 0.3, width = 0.1) +
ylab("drat") +
xlab("gear") +
coord_flip()+
geom_text(data = result_sum, aes(label = paste0("n = ", count),
x = (as.numeric(gear) + 0.25),
y = 4.75)) +
geom_text(data = result_sum, aes(label = paste0("sum wt = ", sum_wt),
x = (as.numeric(gear) - 0.25),
y = 4.75))
This gives you this:
The benefit to this second method is that the text isn't bold like in the first graph. The bold effect occurs in the first graph due to the text being printed over itself for all observations in the dataframe.
Thanks to those who helped.... I used this in the end which plots the calculated values, one set of classes being text based so using vjust to position the vertical offset.
thanks again!
library(ggplot2)
library(gridExtra)
library(ggthemes)
results <- mtcars
results$gear <- as.factor(as.character(results$gear)) #Turn 'gear' to text to simulate classes, then factorise
result_sum <- results %>%
group_by(gear) %>%
summarise(count = n(), sum_wt = sum(wt))
ggplot(results, aes(x = gear, y = drat, group=gear)) +
theme_tufte(base_size = 15) + theme(line=element_blank()) +
geom_violin(fill = "white") +
geom_boxplot(fill = "black", alpha = 0.3, width = 0.1) +
ylab("drat") +
xlab("gear") +
coord_flip()+
geom_text(data = result_sum, aes(label = paste0("n = ", count), x = (gear), vjust= 0, y = 5.25)) +
geom_text(data = result_sum, aes(label = paste0("sum wt = ", round(sum_wt,0)), x = (gear), vjust= -2, y = 5.25))