I want bold values inside ggbarplot, but i really don't know how. yscale has to be "percent"
x <- pierwsze %>%
group_by(treatment_groups,sex) %>%
count() %>%
ggpubr::ggbarplot(
x = "treatment_groups",
fill = "sex",
y = "n",
label = TRUE, lab.col = "black", lab.vjust = 1.2,
position = position_fill(),
palette = get_palette(palette = "Oranges",5)
)+
labs(x="Treatment Group",y="Proportion",fill="Sex")+
yscale("percent",.format = TRUE)+
font("xy.text",size=10)
Here is a solution for printing labels in bold.
q <- ggplot_build(x)
x + geom_text(data=q$data[[2]], aes(x=x, y=y, label=label),
fontface="bold", vjust=1.2)
Related
I'm looking for a solution since too much time without finding it, so it's time to ask for some help...
I would like to add pValue to boxplots organized with facet_wrap (ggplot2). Similar to what you obtain with the script I add to this post (the first part of the script is the exemple of what I want and it's working well for 1 plot, the second part is related to facet and doesn't work).
I would like to add pvalue between all "dose" values of "OJ", same for "VC", but also between, for exemple "dose"=1 of OJ and VC (as in the plot). It's working well for 1 plot, but not in facet_wrap. The error message is:
Error: Assigned data value must be compatible with existing data.
x Existing data has 6 rows.
x Assigned data has 60 rows.
ℹ Only vectors of size 1 are recycled.
Thanks for your help (if only...)
The script:
################# DATAFRAME
data("ToothGrowth")
df <- ToothGrowth
vec <- c("A","B")
df$dose <- as.character(df$dose)
df$facet <- rep(sample(vec, 2),replace=T, nrow(df)/2)
view(df)
################### STAT
df_pval <- df %>%
rstatix::group_by(dose) %>%
rstatix::wilcox_test(len ~ supp) %>%
rstatix::add_xy_position()
df_pval2 <- df %>%
rstatix::group_by(supp) %>%
rstatix::wilcox_test(len ~ dose) %>%
rstatix::add_xy_position(x = "supp", dodge = 0.8)
################### PLOT
plotx <- ggplot(df, aes(x = supp, y = len)) +
geom_boxplot(aes(fill = dose)) +
stat_pvalue_manual(df_pval,
label = "{p}",
color = "dose",
fontface = "bold",
step.group.by = "dose",
step.increase = 0.1,
tip.length = 0,
bracket.colour = "black",
show.legend = FALSE) +
stat_pvalue_manual(df_pval2,
label = "{p}",
color = "black",
fontface = "bold",
step.group.by = "supp",
step.increase = 0.1,
tip.length = 0,
bracket.colour = "black",
show.legend = FALSE)
plot(plotx)
################### STAT FACET
df_pval3 <- df %>%
rstatix::group_by(dose, facet) %>%
rstatix::wilcox_test(len ~ supp) %>%
rstatix::add_xy_position()
df_pval4 <- df %>%
rstatix::group_by(supp, facet) %>%
rstatix::wilcox_test(len ~ dose) %>%
rstatix::add_xy_position(x = "supp", dodge = 0.8)
print(df_pval)
print(df_pval2)
###################### PLOT FACET
ploty <- ggplot(df, aes(x = supp, y = len)) +
geom_boxplot(aes(fill = dose)) +
facet_wrap(~df[,4]) + stat_pvalue_manual(df_pval3,
label = "{p}",
color = "dose",
fontface = "bold",
step.group.by = "dose",
step.increase = 0.1,
tip.length = 0,
bracket.colour = "black",
show.legend = FALSE) +
stat_pvalue_manual(df_pval4,
label = "{p}",
color = "black",
fontface = "bold",
step.group.by = "supp",
step.increase = 0.1,
tip.length = 0,
bracket.colour = "black",
show.legend = FALSE)
plot(ploty)
In the chart below, I would like to include an item in the legend for the blue reference line, which for the sake of this example, we can call "Arbitrary Line". Can anyone provide me a solution for getting that into the legend? Note that the final plot must be rendered in plotly.
library(tidyverse)
library(plotly)
dat <- data.frame(peeps= c("Bill", "Bob", "Becky"),
vals = c(10, 15, 12),
label = c("8% Fake", "12% Pizza", "45% Becky"),
grp = c("Bears", "Bears", "Mongoose") %>% as.factor)
p1 <- dat %>%
ggplot(aes(x = peeps, y = vals, fill = grp)) +
geom_bar(stat = "identity") +
geom_segment(aes(x = 0.55, xend = 3.45, y = 5, yend = 5), color = "blue") +
scale_y_continuous(expand = c(0, 0)) +
coord_flip()
ggplotly(p1) %>%
layout(legend = list(orientation = "h",
xanchor = "center",
y = -0.15,
x = 0.5))
Try to add:
scale_fill_manual(name = "", values="blue", label="Arbitrary Line")
I would like to add vertical segments to a ridgeline plot whose histograms show customized quantiles.
I managed to get the vertical segments if I map fill color with ..x... But I would like to show quantiles in the density plots. I wrote the following code:
library(datasets)
library(ggplot2)
data("iris")
iris_lines <- data.frame(Species = c("setosa", "versicolor", "virginica"),
x0 = c(5, 5.9, 6.5))
Figure1 <- ggplot(iris, aes(x=Sepal.Length, y=Species, fill=(..quantile..))) +
geom_density_ridges_gradient(jittered_points = FALSE, calc_ecdf = TRUE, quantile_lines = c(TRUE), quantiles =c(0.1,0.25,0.75,0.9),scale=0.9, color='white')+
geom_segment(data = iris_lines, aes(x = x0, xend = x0, y = as.numeric(Species), yend = as.numeric(Species) + c(.9,.5,.5)), color = "red") + scale_y_discrete(expand = c(0.01, 0))
Figure1
The code works if I map fill color as fill = ..x.. I get three vertical lines representing the mean of each density plot; however, if I map fill color as fill = ..quantile.. I get the following error:
Error in data.frame(..., check.names = FALSE) :
arguments imply differing number of rows: 1, 3
Nice chart!
Add inherit.aes = F to the second geom so it doesn't try to match your data with the fill calculation in the ggplot(aes() call.
Figure1 <- ggplot(iris, aes(x=Sepal.Length, y=Species, fill=(..quantile..))) +
geom_density_ridges_gradient(jittered_points = FALSE,
calc_ecdf = TRUE,
quantile_lines = c(TRUE),
quantiles =c(0.1,0.25,0.75,0.9),
scale=0.9, color='white') +
geom_segment(data = iris_lines,
aes(x = x0, xend = x0,
y = as.numeric(Species), yend = as.numeric(Species) + c(.9,.5,.5)),
color = "red", inherit.aes = F) + #### HERE ####
scale_y_discrete(expand = c(0.01, 0))
Figure1
Edit:
OP asked in comment about selectively labeling some elements and adding a label for the median line. Here's an approach, probably not the pithiest.
Figure1 <- ggplot(iris, aes(x=Sepal.Length, y=Species,
fill = (..quantile..),
color = (..quantile..))) +
geom_density_ridges_gradient(jittered_points = FALSE,
calc_ecdf = TRUE,
quantile_lines = c(TRUE),
quantiles =c(0.1,0.25,0.75,0.9),
scale=0.9, color='white') +
geom_segment(data = iris_lines,
aes(x = x0, xend = x0, fill = "median",
y = as.numeric(Species),
yend = as.numeric(Species) + c(.9,.5,.5),
color = "median")) + #### HERE ####
scale_y_discrete(expand = c(0.01, 0)) +
scale_color_manual(name = "quantile",
limits = c(1:3, "median"),
values = alpha("firebrick1", c(0, 0, 0, 1)),
labels = c("<10%", "10-25%", "IQR", "median")) +
scale_fill_manual(name = "quantile",
limits = c(1:3, "median"),
values = c("cadetblue", "coral", "orange", "white"),
na.value = "gray30",
labels = c("<10%", "10-25%", "IQR", "median"))
Figure1
In this SO answer, user #Crops shows how to add a legend to a ggalt::geom_dumbbell plot. Very nice.
library(ggalt)
df <- data.frame(trt=LETTERS[1:5], l=c(20, 40, 10, 30, 50), r=c(70, 50, 30, 60, 80))
df2 = tidyr::gather(df, group, value, -trt)
ggplot(df, aes(y = trt)) +
geom_point(data = df2, aes(x = value, color = group), size = 3) +
geom_dumbbell(aes(x = l, xend = r), size=3, color="#e3e2e1",
colour_x = "red", colour_xend = "blue",
dot_guide=TRUE, dot_guide_size=0.25) +
theme_bw() +
scale_color_manual(name = "", values = c("red", "blue") )
I want to sort trt descending on r. I tried replacing y = trt with y = reorder(trt, r), but I get an error that object r is not found.
Here is a way where we reorder the factor levels of trt in df and df2 before we plot.
# reorder factor levels
df$trt <- reorder(df$trt, df$r)
df2$trt <- factor(df2$trt, levels = levels(df$trt))
ggplot(df, aes(y = trt)) +
geom_point(data = df2, aes(x = value, color = group), size = 3) +
geom_dumbbell(aes(x = l, xend = r), size=3, color="#e3e2e1",
colour_x = "red", colour_xend = "blue",
dot_guide=TRUE, dot_guide_size=0.25) +
theme_bw() +
scale_color_manual(name = "", values = c("red", "blue") )
Using the dumbbell package
##Reformat data
df3<-df %>% arrange(r)
df2<-df%>% mutate("key"="trt")
df2$trt<-factor(df2$trt,df3$trt)
##plot
dumbbell::dumbbell(df2, id="trt", column1="l", column2="r",key="key", delt =1, textsize=3, lab1 = "l", lab2="r", pt_val = 1, pointsize = 3,pt_alpha = 0.6, arrow=1, leg = "Add legend title", pval=2) + xlim(8,85) + facet_wrap(key ~.)
Added in some bells and whistles, you can remove them toggling with the options.
I dont have enough points to embed for here is the link. Hope someone finds it useful.
I'm trying to add a bivariate legend to my ggplot2 chart but I don't know whether (a) this is possible through some guides options and (b) how to achieve it.
The only way I've managed to produce something close to the desired outcome was by specifically creating a new chart which resembles a legend (named p.legend below) and inserting it, via the cowplot package, somewhere in the original chart (named p.chart below). But surely there must be a better way than this, given that this approach requires creating the legend in the first place and fiddling with its size/location to fit it in the original chart.
Here's code for a dummy example of my approach:
library(tidyverse)
# Create Dummy Data #
set.seed(876)
n <- 2
df <- expand.grid(Area = LETTERS[1:n],
Period = c("Summer", "Winter"),
stringsAsFactors = FALSE) %>%
mutate(Objective = runif(2 * n, min = 0, max = 2),
Performance = runif(2 * n) * Objective) %>%
gather(Type, Value, Objective:Performance)
# Original chart without legend #
p.chart <- df %>%
ggplot(., aes(x = Area)) +
geom_col(data = . %>% filter(Type == "Objective"),
aes(y = Value, fill = Period),
position = "dodge", width = 0.7, alpha = 0.6) +
geom_col(data = . %>% filter(Type == "Performance"),
aes(y = Value, fill = Period),
position = "dodge", width = 0.7) +
scale_fill_manual(values = c("Summer" = "#ff7f00", "Winter" = "#1f78b4"), guide = FALSE) +
theme_minimal() +
theme(panel.grid.major.x = element_blank(),
panel.grid.minor.y = element_blank())
# Create a chart resembling a legend #
p.legend <- expand.grid(Period = c("Summer", "Winter"),
Type = c("Objective", "Performance"),
stringsAsFactors = FALSE) %>%
ggplot(., aes(x = Period, y = factor(Type, levels = c("Performance", "Objective")),
fill = Period, alpha = Type)) +
geom_tile() +
scale_fill_manual(values = c("Summer" = "#ff7f00", "Winter" = "#1f78b4"), guide = FALSE) +
scale_alpha_manual(values = c("Objective" = 0.7, "Performance" = 1), guide = FALSE) +
ggtitle("Legend") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5),
rect = element_rect(fill = "transparent"),
axis.title = element_blank(),
panel.grid.major = element_blank())
# Add legend to original chart #
p.final <- cowplot::ggdraw() +
cowplot::draw_plot(plot = p.chart) +
cowplot::draw_plot(plot = p.legend, x = 0.5, y = 0.65, width = 0.4, height = 0.28, scale = 0.7)
# Save chart #
cowplot::ggsave("Bivariate Legend.png", p.final, width = 8, height = 6, dpi = 500)
... and the resulting chart:
Is there an easier way of doing this?
This might work at some point, but right now the colorbox seems to ignore all breaks, names and labels (#ClausWilke?). Probably because the multiscales package is in really early stages.
Posting since it might work when future readers are here.
library(multiscales)
df %>%
mutate(
period = as.numeric(factor(Period)),
type = as.numeric(factor(Type))
) %>%
ggplot(., aes(x = Area, y = Value, fill = zip(period, type), group = interaction(Area, Period))) +
geom_col(width = 0.7, position = 'dodge') +
bivariate_scale(
"fill",
pal_hue_sat(c(0.07, 0.6), c(0.4, 0.8)),
guide = guide_colorbox(
nbin = 2,
name = c("Period", "Type"), #ignored
breaks = list(1:2, 1:2), #ignored
labels = list(levels(.$Period), levels(.$Type)) #ignored
)