density ridges, plotting geom_vline using specific values for each distribution

Hie,

I am trying to insert geom_vlines in my distributions using specific values. I was able to write the code is as below using the iris data, but get all the lines plotted on each distribution instead of one line for each.

irismean<-data.frame(z=c(5,5.8,6.3),Species=c("setosa","versicolor","virginica"))

ggplot(iris, aes(Sepal.Length)) +
  geom_density_ridges(alpha = 0.1,fill="red",colour="red") +
  facet_wrap(~Species) + xlim(0, 10)+
  geom_vline(aes(xintercept=z),irismean)

If I use facet_wrap it works to plot a line on each facet as below,

irismean<-data.frame(z=c(5,5.8,6.3),Species=c("setosa","versicolor","virginica"))

ggplot(iris, aes(Sepal.Length)) +
  geom_density(alpha = 0.1,fill="red",colour="red") +
  facet_wrap(~Species) + xlim(0, 10)+
  geom_vline(aes(xintercept=z),irismean)

I am comparing the same samples, as such the distributions get stacked on top of each other so it would be easier to visually see the differences if I could plot the lines in density ridges as compared to facet_wrap

furthermore, I would like to add lables to these lines and have tried the code below but keep getting the error (also shown)

library(ggrepel)
irismean<-data.frame(z=c(5,5.8,6.3),Species=c("setosa","versicolor","virginica"))

ggplot(iris, aes(Sepal.Length)) +
  geom_density(alpha = 0.1,fill="red",colour="red") +
  facet_wrap(~Species) + xlim(0, 10)+
  geom_vline(aes(xintercept=z),irismean)+  
geom_text_repel(data=iris,mapping=aes(x=Sepal.Length,y=Species,
+                                     label =paste(irismean),"cm",sep=""))
Warning: Ignoring unknown aesthetics: , sep

Error: Aesthetics must be either length 1 or the same as the data (150): label

Does anyone have suggestions on dealing with this?

I'm not 100% clear what you're trying to do here, but making a few plots using reprex is always helpful. Also I highly recommend looking at the vignette for the ggridges package, since it goes over the many variations and helper functions built in to help you do just this.

library(tidyverse)
library(ggridges)
#> 
#> Attaching package: 'ggridges'
#> The following object is masked from 'package:ggplot2':
#> 
#>     scale_discrete_manual

irismean <- data.frame(z = c(5, 5.8, 6.3), Species = c("setosa", "versicolor", "virginica"))

# throws error because geom_density_ridges() requires y aesthetic
ggplot(iris, aes(Sepal.Length)) +
  geom_density_ridges(alpha = 0.1, fill = "red", colour = "red") +
  facet_wrap(~Species) + xlim(0, 10) +
  geom_vline(aes(xintercept = z), irismean)
#> Picking joint bandwidth of 0.123
#> Picking joint bandwidth of 0.212
#> Picking joint bandwidth of 0.207
#> Error: geom_density_ridges requires the following missing aesthetics: y

ggplot(iris, aes(x = Sepal.Length, y = Species)) +
  geom_density_ridges(alpha = 0.1, fill = "red", colour = "red") +
  facet_wrap(~Species) + xlim(0, 10) +
  geom_vline(aes(xintercept = z), irismean)
#> Picking joint bandwidth of 0.123
#> Picking joint bandwidth of 0.212
#> Picking joint bandwidth of 0.207


ggplot(iris, aes(Sepal.Length)) +
  geom_density(alpha = 0.1, fill = "red", colour = "red") +
  facet_wrap(~Species) + xlim(0, 10) +
  geom_vline(aes(xintercept = z), irismean)


# specify x and y parameters
ggplot(iris, aes(x = Sepal.Length, y = Species)) +
  geom_density_ridges(alpha = 0.1, fill = "red", colour = "red")
#> Picking joint bandwidth of 0.181


# use `stat_density_ridges()` to plot quantile lines
ggplot(iris, aes(x = Sepal.Length, y = Species)) +
  stat_density_ridges(quantile_lines = TRUE, quantiles = 2, alpha = 0.1, fill = "red", colour = "red")
#> Picking joint bandwidth of 0.181

Created on 2019-09-02 by the reprex package (v0.3.0)

1 Like

I should start by saying I did read the introduction to gggridges, but it doesn't give the solution I am looking for. I've literary spent a whole day trying to figure it out (also by looking at other forums) but haven't been able to find the answer I want it's why I have asked here. What I want to plot is something like this

library(ggrepel)
#> Loading required package: ggplot2
library(ggridges)
#> 
#> Attaching package: 'ggridges'
#> The following object is masked from 'package:ggplot2':
#> 
#>     scale_discrete_manual
library(ggplot2)
irismean<-data.frame(z=c(5,5.8,6.3),Species=c("setosa","versicolor","virginica"))

ggplot(iris, aes(x=Sepal.Length,y=Species)) +
    geom_density_ridges(alpha = 0.1,fill="red",colour="red")+ xlim(0, 10)+
    geom_vline(aes(xintercept=z),irismean)
#> Picking joint bandwidth of 0.181

Created on 2019-09-02 by the reprex package (v0.3.0)

But I do not want the three plotted lines to run from top to bottom but just on the specific distribution. This example below shows (only visually), what I want to achieve:

But not entirely. The codes used in most of the examples, rely on built in functions such as mean, quantiles etc so it is possible to draw lines separately for each distribution. The lines I want are for means but I cannot use the `mean` function in this `ggplot2` package because it has no option to weight the data. As a result I need to input my mean values separately, which is how I ended up with the code I posted initially. 
My actual dataset is producing the result below because it is a comparison of the same sample (just different methods of getting the x value)

what I want is a way to not have the four lines running through all the four distributions, that's it.

The second question was about labeling, and it bases on the same, the available suggestions use built in functions, which I am not using. I have tried modifying the code for geom text and came up with the one I posted earlier (repeated partly below)

+ geom_text_repel(data=iris,mapping=aes(x=Sepal.Length,y=Species,
+                                     label =paste(irismean),"cm",sep=""))
Warning: Ignoring unknown aesthetics: , sep
Error: Aesthetics must be either length 1 or the same as the data (150): label
>

This doesn't seem to work also, it's why I am asking for assistance

geom_vline() inherently goes through the entire plot. If you want a line segment with a start and finish, you might take a look at geom_segment(), though I don't know the ggridges internals well enough to know how that clipping occurs — it uses stat_density_ridges() for height, but I'm not sure if/how to set that manually.

The below error occurs because you are using the iris dataset (which has 150 observations), and pasting from irismean, which has 3.

In ggplot geom_density() has a weight aesthetic in the development version:

But I don't think the same has been implemented in ggridges. See the open issue here

If this means that you know how to plot what you want to plot using a built in function, you can use weighted.mean. I'm entirely unfamiliar with any gg* package other than ggplot2 (and only very basics of it), so can't provide a solution. Sorry! Maybe Mara ot someone else can use this to solve your problem.