I am trying to add a line segment intervals to a ggplot
. However, I am trying to make the line segments a gradient that fades the alpha to zero at each end of the interval.
For example, if I create a plot that includes some intervals, like so:
library(ggplot2)
library(dplyr)
df <- data.frame(
name = c('x1', 'x2', 'x3'),
value = c(0.251, 0.207, 0.182),
seg = c(0.027, 0.028, 0.049)
)
p <- df %>%
ggplot() aes(x=name, y=value)
geom_segment(aes(x=name, xend=name, y=(value - seg), yend=(value seg),
col = name),
size = 5)
geom_point(aes(x=name, y = value), shape = 18, size = 5, color = "black")
theme_bw()
xlab('Name')
ylab("Value")
p
This produces a plot like this:
However, I am trying to figure out a way to turn those line segments into a thicker bar, that fades the alpha to zero at each end.
Something like the plot below (which can be found
For clarity, I am just trying to recreate the coloured gradient intervals from the plot above.
EDIT
As per one of the comments, I tried using geom_link
for this... but I cant seem to get it to work correctly.
To begin, I created a vector of alpha values to pass to geom_link
like so:
alpLow <- seq(from = 0, to = 1, length.out = 150)
alpHigh <- rev(alpLow)
alp <- c(alpLow, alpHigh)
And then used this in geom_link
:
p <- df %>%
ggplot() aes(x=name, y=value)
geom_link(aes(x = name, y = (value - seg),
xend = name, yend = (value seg),
colour = stat(index)), lineend = "round", size = 5, alpha = alp)
As you can see, it only applies the gradient at the start and end of the 1st and last line segment.
Furthermore, Im not entirely pleased with the aesthetic of using geom_link
as it seems to link together points (which are visible when you zoom in)... I was really hoping for a solid bar that fades the alpha.
CodePudding user response:
Use ggforce::geom_link
alpha = stat(index) is just one option, from the documentation.
library(tidyverse)
library(ggforce)
df <- data.frame(
name = c('x1', 'x2', 'x3'),
value = c(0.251, 0.207, 0.182),
seg = c(0.027, 0.028, 0.049)
)
df %>%
ggplot(aes(x=name, y=value))
geom_link(aes(x=name, xend=name, yend=value seg,
col = name, alpha = rev(stat(index))),
size = 5)
geom_link(aes(x=name, xend=name, yend=value - seg,
col = name, alpha = rev(stat(index))),
size = 5)
geom_point(aes(x=name, y = value), shape = 18, size = 5, color = "black")
theme_bw()
labs(x= 'Name', y = "Value")
CodePudding user response:
I hope the below is sufficiently different to merit a new answer. I have had a bit more time to look into the link which you have provided. {ggdist} has those gradient interval stats - they need the underlying data and not summary data for calculation of their density.
Assuming that you have summarised data in a way that those values represent the distribution of your data (e.g., a normal distribution), you can use this in order to recreate data based on those values. I have here created normal distributions for each group, using your values as mean and standard deviation, and then you can use ggdist::stat_gradientinterval
. But you can also create other distributions of course.
library(tidyverse)
library(ggdist)
df <- data.frame(
name = c('x1', 'x2', 'x3'),
value = c(0.251, 0.207, 0.182),
seg = c(0.027, 0.028, 0.049)
)
df_norm <-
df %>%
split(., .$name) %>%
map(function(x) rnorm(100, x$value, x$seg)) %>%
bind_rows() %>%
pivot_longer(everything(), names_to = "name", values_to = "value")
ggplot(df_norm, aes(x=name, y=value, fill= name))
ggdist::stat_gradientinterval()
theme_bw()
labs(x= 'Name', y = "Value")
Created on 2021-12-01 by the reprex package (v2.0.1)