change alternations in geom_col dodge between fill and alpha - r

I got a bar graph with both alpha and fill. I would like the plot to alternate with alpha and mix colors. Currently, I only get it to mix alpha and order by colors (see MWE below). Any help towards changing the ordering would be very appreciated.
library(tibble)
library(ggplot2)
#> Warning: package 'ggplot2' was built under R version 4.2.2
set.seed(1)
tibble(
y = runif(20),
x = letters[rep(1:2, times = 10)],
f = factor(LETTERS[rep(1:2, each = 10)], levels = LETTERS[1:2], ordered = TRUE),
a = factor(rep(1:5, times = 4), levels = 1:5, ordered = TRUE)
) %>%
ggplot(aes(x, y, fill = f, alpha = a)) +
geom_col(position = position_dodge2(1)) +
scale_alpha_discrete(range = c(.5, 1))
#> Warning: Using alpha for a discrete variable is not advised.
Created on 2023-01-26 with reprex v2.0.2
I.e., I am trying to get dark yellow mixed with dark purple and light/transparent yellow with light/transparent purple.

Perhaps like this ..., i.e. simply switch the order of fill and alpha to change the grouping:
library(tibble)
library(ggplot2)
set.seed(1)
tibble(
y = runif(20),
x = letters[rep(1:2, times = 10)],
f = factor(LETTERS[rep(1:2, each = 10)], levels = LETTERS[1:2], ordered = TRUE),
a = factor(rep(1:5, times = 4), levels = 1:5, ordered = TRUE)
) %>%
ggplot(aes(x, y, alpha = a, fill = f)) +
geom_col(position = position_dodge2(1)) +
scale_alpha_discrete(range = c(.5, 1))
#> Warning: Using alpha for a discrete variable is not advised.

Related

Create stacked barplot with lower and upper limits

I have below dataframe and want to draw a ggplot with stacked bar for lower and upper limits with each data points.
library(ggplot2)
dat = rbind(data.frame('val' = c(3,4), 'val0' = c(1,2), 'val2' = c(5,6), 'name' = c('A', 'A')),
data.frame('val' = c(3,4)+2, 'val0' = c(1,2)+2, 'val2' = c(5,6)+2, 'name' = c('B', 'B')))
dat
> dat
val val0 val2 name
1 3 1 5 A
2 4 2 6 A
3 5 3 7 B
4 6 4 8 B
I am able to obtain below ggplot
ggplot(dat, aes(x = name)) +
geom_point(aes(y = val, color = name), size = 10, alpha = 0.3)
However I want to get below plot (hand-drawn - just for illustration)
Is there any way to draw above plot with my data?
Any pointer will be very helpful
To get the rectangles, the easiest way is probably to use a modified box plot:
ggplot(within(dat, group <- c(1, 2, 1, 2)), aes(name, val, group = group)) +
geom_boxplot(stat = "identity", alpha = 0.5, color = "#00000030",
aes(ymin = val0, lower = val0, fill = name,
group = interaction(name, group),
ymax = val2, upper = val2, middle = val0),
width = 0.5) +
geom_point(position = position_dodge(width = 0.5),
aes(fill = name), shape = 21, size = 4) +
scale_fill_brewer(palette = "Set1") +
theme_minimal(base_size = 20)
Maybe you want to use a dodged geom_pointrange like this:
library(ggplot2)
#> Warning: package 'ggplot2' was built under R version 4.1.2
dat = rbind(data.frame('val' = c(3,4), 'val0' = c(1,2), 'val2' = c(5,6), 'name' = c('A', 'A')),
data.frame('val' = c(3,4)+2, 'val0' = c(1,2)+2, 'val2' = c(5,6)+2, 'name' = c('B', 'B')))
dat$fac <- factor(unlist(sapply(as.vector(table(dat$name)), seq_len)))
ggplot(dat) +
geom_pointrange(aes(x=name,y=val,colour=name,
ymin=val0,ymax=val2, group = fac), position=position_dodge(width=0.3))
Created on 2022-07-20 by the reprex package (v2.0.1)

Unable to colour jittered points in geom_density_ridges

I'm trying to colour specific points within a ridge plot, but the points I am trying to highlight aren't displayed nor are they in the legend. In this example I am trying to highlight the points with labels "X" and "Y" withing ridges based on groups "A" and "B", but the points associated with "X" aren't plotted.
library(tidyverse)
library(ggridges)
data <- tibble(y = 1:10,
group = as.factor(rep(c("A", "B"), each=5)),
subgroup = as.factor(rep(c("X", rep("Y", each=4)),times=2)))
data%>%
ggplot(aes(x = y, y= group, fill = group))+
geom_density_ridges(alpha=0.5)+
geom_density_ridges(aes(point_fill = subgroup, point_color = subgroup),
alpha=0, colour = NA, jittered_points = T, point_alpha=1)
I was expecting the points associated with subgroup "X" to be plotted as points in a different colour and for subgroup "X" to appear in the legend.
You need to explicitly define the group, then it works:
library(dplyr)
library(ggplot2)
library(ggridges)
data <- tibble(y = 1:10,
group = as.factor(rep(c("A", "B"), each=5)),
subgroup = as.factor(rep(c("X", rep("Y", each=4)),times=2)))
data%>%
ggplot(aes(x = y, y= group, group=group, fill = group))+
geom_density_ridges(alpha=0.5)+
geom_density_ridges(aes(point_fill = subgroup, point_color = subgroup),
alpha=0, colour = NA, jittered_points = T, point_alpha=1)
#> Picking joint bandwidth of 0.974
#> Picking joint bandwidth of 0.974
Created on 2022-04-06 by the reprex package (v2.0.1)
You could achieve your desired result by adding the group aesthetic to the second geom_density_ridges, i.e. add group = group to aes.
library(tibble)
library(ggplot2)
library(ggridges)
set.seed(123)
data <- tibble(
y = 1:10,
group = as.factor(rep(c("A", "B"), each = 5)),
subgroup = as.factor(rep(c("X", rep("Y", each = 4)), times = 2))
)
ggplot(data, aes(x = y, y = group)) +
geom_density_ridges(aes(fill = group), alpha = 0.5) +
geom_density_ridges(aes(point_color = subgroup, group = group),
alpha = 0, colour = NA, jittered_points = T, point_alpha = 1
)
#> Picking joint bandwidth of 0.974
#> Picking joint bandwidth of 0.974

Combined scatter and line ggplot with proper legend

I try to find a clear approach for combined scatter and line plots with ggplot2 that have an appropriate legend. The following works, in principle, but with warnings:
library("ggplot2")
library("dplyr")
## 2 data sets, one for the lines, one for the points
tbl <- tibble(
f = rep(letters[1:2], each = 10),
x = rep(1:10, 2),
y = c(1e-4 * exp(1:10), log(1:10))
)
obs <- tibble(
f = rep("c", 5),
x = seq(2, 10, 2),
y = log(seq(2, 10, 2)) + rnorm(5, sd = 0.1)
)
rbind(tbl, obs) %>%
ggplot(aes(x, y, color = f, linetype = f)) +
geom_line(show.legend = TRUE) +
geom_point(show.legend = TRUE, aes(shape = f), size = 3) +
scale_linetype_manual(values=c("solid", "solid", "blank")) +
scale_shape_manual(values=c(NA, NA, 16))
but I would like to get rid of warnings and to write something like:
scale_shape_manual(values=c("none", "none", "circle"))
Is there already a "none" or "empty" shape code? Several past answers have been suggested on SO, but I wonder if there is a recent canonical way.

failed to convert my ggplot to interactive plot using ggplotly function

I'm making a stacked barplot. The width of the bar is set according to variable w.
library(plotly)
library(tidyverse)
df = data.frame(x = c("a","b","c"),
w = c(1.2, 1.3, 4),
y = c(9, 10, 6) )
dat = df %>% mutate(pos = 0.5 * (cumsum(w) + cumsum(c(0, w[-length(w)]))))
g= dat %>% ggplot(aes(x = pos, y = y, fill = x)) +
geom_bar(aes( width = w), stat = "identity") +
scale_x_continuous(labels = df$x, breaks = dat$pos)
ggplotly(g)
The ggplot is fine. But when I tried to convert it to interactive using ggplotly, I got error message as below:
Error in nchar(axisObj$ticktext) : 'nchar()' requires a character vector
Does anyone know why this failed? Thanks.
The Problem is your x-axis scaling.
This should work:
library(plotly)
library(tidyverse)
df = data.frame(x = c("a","b","c"),
w = c(1.2, 1.3, 4),
y = c(9, 10, 6) )
dat = df %>% mutate(pos = 0.5 * (cumsum(w) + cumsum(c(0, w[-length(w)]))))
g= dat %>% ggplot(aes(x = pos, y = y, fill = x)) +
geom_bar(aes(width = w), stat = "identity") +
scale_x_continuous(labels = levels(df$x), breaks = dat$pos)
ggplotly(g)
ggplot seems to keep your x-axis labels as factor-levels which ggplotly doesn't understand.
So you just need to convert them to character.

Use position_jitterdodge without mapping aesthetic

I would like to produce a plot like the one obtained with the code below. However, I would like to dodge by "replicate", but without actually mapping an aesthetic (because I would like to assign fill and colors to other aesthetics).
dataset <- data_frame(sample = rep(c("Sample1","Sample2","Sample3", "Sample4"), each = 25),
replicate = sample(x = c("A", "B"), size = 100, replace = TRUE),
value = rnorm(n = 100, mean = 0, sd = 10))
ggplot(data = dataset, aes(x = sample, y = value, fill = replicate)) +
geom_point(position = position_jitterdodge(jitter.width = 0.15, dodge.width = 0.75),
show.legend = F)
I had hope using group = replicate instead of fill = replicate but this doesn't work. I can imagine a workaround using for example alpha = replicate as an aesthetic and setting scale_alpha_manual(values = c(1, 1)) in case of duplicates, but I don't find this solution ideal and would like to keep all aesthetics available (other than x and y available for further use)
ggplot(data = dataset, aes(x = sample, y = value, alpha = replicate)) +
geom_point(position = position_jitterdodge(jitter.width = 0.15, dodge.width = 0.75),
show.legend = F) +
scale_alpha_manual(values = c(1, 1))
The plot that I expect to get is:
I hope my question makes sense, any hint ?
Best,
Yvan
You could unite the sample and replicate columns and use that as the x-axis, injecting a 'Placeholder' value for spacing between samples.
library(tidyverse)
set.seed(20181101)
dataset <- data_frame(sample = rep(c("Sample1","Sample2","Sample3", "Sample4"), each = 25),
replicate = sample(x = c("A", "B"), size = 100, replace = TRUE),
value = rnorm(n = 100, mean = 0, sd = 10))
dataset %>%
bind_rows({
#create a dummy placeholder to allow for spacing between samples
data.frame(sample = unique(dataset$sample),
replicate = rep("Placeholder", length(unique(dataset$sample))),
stringsAsFactors = FALSE)
}) %>%
#unite the sample & replicate columns, and use it as the new x-axis
unite(sample_replicate, sample, replicate, remove = FALSE) %>%
ggplot(aes(x = sample_replicate, y = value, color = replicate)) +
geom_jitter() +
#only have x-axis labels for each sample
scale_x_discrete(breaks = paste0("Sample", 1:length(unique(dataset$sample)), "_B"),
labels = paste0("Sample ", 1:length(unique(dataset$sample)))) +
labs(x = "Sample") +
#don't show the Placeholder value in the legend
scale_color_discrete(breaks = c("A", "B"))

Resources