Draw vertical quantile lines over histogram

ggplot2, quantile, r

Solution

Precomputing these values and plotting them separately seems like the simplest option. Doing so with `dplyr` requires minimal effort:

library(dplyr)
q.95 <- df_tot %>%
  group_by(Dataset) %>%
  summarise(Bin_q.95 = quantile(Bin, 0.95))

ggplot(data=df_tot[which(df_tot$Pdf>0),], 
       aes(x=Bin, y=Pdf, group=Dataset, colour=Dataset)) +
  geom_point(aes(color=Dataset), alpha = 0.7, size=1.5) + 
  geom_vline(data = q.95, aes(xintercept = Bin_q.95, colour = Dataset))

Problem

I currently generate the following plot using ggplot in R: The data is stored in a single dataframe with three columns: PDF (y-axis in the plot above), mids(x) and dataset name. This is created from histograms. What I want to do is to plot a color-coded vertical line for each dataset representing the 95th quantile, like I manually painted below as an example: I tried to use `+ geom_line(stat="vline", xintercept="mean")` but of course I'm looking for the quantiles, not for the mean, and AFAIK ggplot does not allow that. Colors are fine. I also tried `+ stat_quantile(quantiles = 0.95)` but I'm not sure what it does exactly. Documentation is very scarce. Colors, again, are fine. Please note that density values are very low, down to 1e-8. I don't know if the quantile() function likes that. I understand that calculating the quantile of an histogram is not quite the same as calculating that of a list of numbers. I don't know how it would help, but the `HistogramTools`package contains an `ApproxQuantile()` function for histogram quantiles. Minimum working example is included below. As you can see I obtain a data frame from each histogram, then bind the dataframes together and plot that. ``` library(ggplot2) v <- c(1:30, 2:50, 1:20, 1:5, 1:100, 1, 2, 1, 1:5, 0, 0, 0, 5, 1, 3, 7, 24, 77) h <- hist(v, breaks=c(0:100)) df1 <- data.frame(h$mids,h$density,rep("dataset1", 100)) colnames(df1) <- c('Bin','Pdf','Dataset') df2 <- data.frame(h$mids*2,h$density*2,rep("dataset2", 100)) colnames(df2) <- c('Bin','Pdf','Dataset') df_tot <- rbind(df1, df2) ggplot(data=df_tot[which(df_tot$Pdf>0),], aes(x=Bin, y=Pdf, group=Dataset, colour=Dataset)) + geom_point(aes(color=Dataset), alpha = 0.7, size=1.5) ```

Original source