library(ggplot2)
library(tidyverse)
library(gganimate)
set.seed(321)
year <- 2001:2021
value <- runif(n = length(year))*100%>% round(digits = 2)
df <- data.frame(year, value) %>%
mutate(cumsum = cumsum(value))
df %>%
ggplot(aes(x = year)) +
geom_col(aes(y = value)) +
geom_line(aes(y = cumsum)) +
transition_states(year) +
shadow_mark()
How to get an animate for both bar and line plots along the years, there is an error with the code above.
Error in transform_path(all_frames, next_state, ease, params$transition_length[i], :
transformr is required to tween paths and lines
Install transformr() package
library(ggplot2)
library(tidyverse)
library(gganimate)
library(transformr)
set.seed(321)
year <- 2001:2021
value <- runif(n = length(year))*100%>% round(digits = 2)
df <- data.frame(year, value) %>%
mutate(cumsum = cumsum(value))
df %>%
ggplot(aes(x = year)) +
geom_col(aes(y = value)) +
geom_line(aes(y = cumsum)) +
transition_states(year) +
shadow_mark()
Related
I have the following data:
library(dplyr)
countries <- c('Austria', 'Belgium', 'Bulgaria', 'Croatia', 'Republic of Cyprus')
year <- rep(2009:2022, length(countries))
country <- as.data.frame(rep(countries, length(2009:2022)))
country <- country[order(country$`rep(countries, length(2009:2022))`),]
df<- cbind.data.frame(country, year)
df$year <- as.numeric(df$year)
df <- df %>%
group_by(country) %>%
mutate(n_obs = 1:n())
df <- df %>% group_by(country) %>%
mutate(gdp = rnorm(n = 1, mean = 3000, sd = 300) + 20.64*n_obs,
inflation = rnorm(n = 1, mean = 5, sd = 3) + 1.23*n_obs)
I want to make line plots for gdp and inflation one by one like so:
ggplot(df, aes(x = year, y = inflation, color = country)) + geom_line()
ggplot(df, aes(x = year, y = gdp, color = country)) + geom_line()
However, in the real data, I have a lot of variables that I want to plot, and I was wondering how I could use lapply to achieve that. I tried the following code:
lapply(df[,c(4,5)], function(var)
ggplot(data = df, aes(x = year, y = var, color = country))
+ geom_line() + labs(x = "year", y = var))
This works, but I cannot get the y variable label on the plot. Any help would be appreciated.
Regards
You can use the following code:
lapply(names(df)[4:5], function(var)
ggplot(data = df, aes(x = year, y = .data[[var]], color = country))
+ geom_line() + ylab(var))
Output gdp:
Output inflation:
I am having trouble placing the p-values in the correct position on the y axis of a ggplot using rstatix. I can get the example provided on the package author's blog to work fine, but when I change the values, the positions are incorrect. Here is the working version:
library(tidyverse)
library(rstatix)
##Example provided by the package author which works correctly
df <- ToothGrowth%>%
as_tibble()
#Check df
df
#Stats calculation
stat.test <- df %>%
group_by(dose) %>%
t_test(len ~ supp) %>%
adjust_pvalue(method = "bonferroni") %>%
add_significance()
# Make facet and add p-values
stat.test <- stat.test %>% add_xy_position(x = "supp", fun = "max")
#Check p value positions - y.position looks good
stat.test
#Plot
ggplot(df, aes(x = supp, y = len)) +
geom_boxplot() +
geom_jitter() +
facet_wrap( ~ dose, scales = "free") +
stat_pvalue_manual(stat.test, hide.ns = F,
label = "{p.adj}")
However, when I change the values, the position of the p values are too high.
## My example which plots incorrectly
##--- This is a very inelegant way to change the values!!
df <- ToothGrowth %>%
mutate(helper = paste0(supp, dose))
df$RecordingNo <- ave(seq.int(nrow(df)), df$helper, FUN = seq_along)
df <- df %>%
select(-helper) %>%
pivot_wider(names_from = c(dose), values_from = len) %>%
mutate(`0.5` = `0.5` * 0.1) %>%
mutate(`2` = `2` * 10) %>%
select(-RecordingNo) %>%
pivot_longer(-supp) %>%
rename(len = value, dose = name) %>%
mutate(dose = as_factor(dose)) %>%
as_tibble()
#Check df
df
##------
#This code is exactly the same as the working code above.
#Stats calculation
stat.test <- df %>%
group_by(dose) %>%
t_test(len ~ supp) %>%
adjust_pvalue(method = "bonferroni") %>%
add_significance()
# Make facet and add p-values
stat.test <- stat.test %>% add_xy_position(x = "supp", fun = "max")
#Check p value positions - y.position looks incorrect
stat.test
ggplot(df, aes(x = supp, y = len)) +
geom_boxplot() +
geom_jitter() +
facet_wrap( ~ dose, scales = "free") +
stat_pvalue_manual(stat.test, hide.ns = F,
label = "{p.adj}")
I guess there is a difference in the second dataframe which is causing the problems, but I can't figure it out. Thanks!
Like the scales option on facet_wrap, there is a scales option on add_xy_position that controls the p value position . As I am using "facet_wrap(...,scales = "free")" I should use add_xy_position(...,scales = "free") to make sure the positions match.
In my example:
stat.test <- stat.test %>% add_xy_position(x = "supp", fun = "max",scales = "free")
ggplot(df, aes(x = supp, y = len)) +
geom_boxplot() +
geom_jitter() +
facet_wrap( ~ dose, scales = "free") +
stat_pvalue_manual(stat.test, hide.ns = F,
label = "{p.adj}")
Answer from author's Github page.
I am trying to make part of my title in italics (M.alfredi) but cant figure out how? Can anyone help? Thanks.
library(tidyverse)
library(reshape2)
dat <- read_xlsx("ReefPA.xlsx")
names(dat) <- str_replace_all(names(dat), " ", "_")
dat1 <- dat d
at1$Date <- format(dat1$Date, "%Y/%m")
dat1 %>%
group_by(Date) %>%
tally() %>%
filter(Date > '2014-01-01') %>%
ggplot() +
geom_bar(aes(x = Date, y = n), stat = 'identity') +
theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1)) +
ylab("Total Number of M.alfredi Encounters Per Month")
You can use plotmath expressions to label your axis. There is no sample data here, but this mock-up should suffice:
ggplot(data = data.frame(x = 1:30, y = round(runif(30, 20, 50))), aes(x, y)) +
geom_col() +
labs(y = expression("Total Number of "~italic(M.alfredi)~"Encounters Per Month"))
I have a lot of data for which I need to create bar graphs that are arranged in descending order. If I do it outside of a function, the solutions shown in this post work, but not when used inside the function.
Here is a use case.
library(forcats)
library(tidyverse)
dat <- data.frame(
x = rep(letters[1:5], times=c(3,11,8, 2, 7))
)
plot_freq <- function(data, group, n=10){
group <- enquo(group)
data %>%
count(!!group) %>%
top_n(n) %>%
mutate(group := fct_reorder(!!group, n)) %>%
ggplot(., aes_(group, quo(n))) +
geom_bar(stat = "identity") +
coord_flip()
}
plot_freq(dat, x, n=5)
What else can I do with plot_freq that can give me my desired result?
dat %>% count(x) %>% top_n(5) %>% mutate(x = fct_reorder(x, n)) %>%
ggplot(., aes(x, n)) + geom_bar(stat = 'identity') + coord_flip()
You can change the function plot_freq accordingly
Change group to quo(group), similar to y aesthetic:
plot_freq <- function(data, group, n=10){
group <- enquo(group)
data %>%
count(!!group) %>%
top_n(n) %>%
mutate(group := fct_reorder(!!group, n)) %>%
ggplot(., aes_(x=quo(group), y=quo(n))) +
geom_bar(stat = "identity") +
coord_flip()
}
plot_freq(dat, x, n=5)
Two solutions.
plot_freq <- function(data, group, n=10){
group <- enquo(group)
data %>%
count(!!group) %>%
top_n(n) %>%
mutate(group := fct_reorder(!!group, n)) %>%
ggplot(., aes_(y=quo(n))) +
geom_bar(aes(group),stat = "identity") +
coord_flip()
}
plot_freq <- function(data, group, n=10){
group <- enquo(group)
data %>%
count(!!group) %>%
top_n(n) %>%
mutate(group := fct_reorder(!!group, n)) %>%
ggplot(., aes_(quo(group),quo(n))) +
geom_bar(stat = "identity") +
coord_flip()
}
Consider the following code that makes a bar chart with a purple color palette
library(dplyr)
library(ggplot2)
dd <- mpg %>%
group_by(manufacturer, cyl) %>%
summarise(n = n()) %>%
ungroup()
mm <- dd %>%
group_by(manufacturer) %>%
summarise(mcyl = weighted.mean(cyl, n)) %>%
arrange(mcyl) %>%
ungroup()
dd %>% left_join(mm) %>%
ggplot(mapping = aes(x = reorder(manufacturer, mcyl), y = n, fill = factor(cyl))) +
geom_bar(stat = "identity", position = "fill") +
coord_flip() +
scale_fill_brewer(palette = "Purples")
Question: How can I make the palette for Audi red ("Reds") and for Ford blue ("Blues"), while keeping the others purple ("Purples")?
What is the most convenient (preferably tidyverse) way to put these red/blue/purple palettes in a variable and passing it to scale_fill_manual() (as explained in this related Q&A)?
Full working solution:
cyl <- sort(unique(mpg$cyl))
ncat <- length(cyl) # 4 types of cylinders
# create palettes
library(RColorBrewer)
purples <- tibble(cyl, colr = brewer.pal(ncat, "Purples"))
reds <- tibble(manufacturer = "audi", cyl, colr = brewer.pal(ncat, "Reds"))
blues <- tibble(manufacturer = "ford", cyl, colr = brewer.pal(ncat, "Blues"))
# merge them with the data
dd_p <- dd %>% filter(!(manufacturer %in% c("audi", "ford"))) %>% left_join(purples)
dd_r <- dd %>% filter(manufacturer == "audi") %>% left_join(reds)
dd_b <- dd %>% filter(manufacturer == "ford") %>% left_join(blues)
gg_dd <- rbind(dd_p, dd_r, dd_b) %>%
left_join(mm)
gg_dd %>%
ggplot(mapping = aes(x = reorder(manufacturer, mcyl), y = n, fill = colr)) +
geom_bar(stat = "identity", position = "fill") +
coord_flip() +
scale_fill_identity()