Help with marking on a ridge plot

Hi all,

I've been struggling with making a graph. In this ridgeplot, I would like to mark an X value, for each category on the Y axis.

I've been toying with geom_label. But this only gives me a label (well, its in the name I guess :slight_smile:). And this label somehow takes on one of the fill values.

So I suppose my question is; in the plot the code generates:

  1. is it possible to add a marking on every ridge, corresponding to the "pop" value?
  2. if not, can I let the label show up in white? Or in a different shape of box?

Thanks!

library(tidyverse)
library(ggridges)

dfs <-
  data.frame(
    "estimate" = rnorm(300),
    "loading" = factor(rep(1:5, 60)),
    "set" = factor(rep(1:3, 100),),
    "pop" = rep(c(0.1, 0.15, 0.20, 0.05, 0.7), 60)
  )

ggplot(dfs, aes(x = estimate, y = loading, fill = set)) +
  geom_density_ridges(
    jittered_points = TRUE,
    point_shape = "|", point_size = 2, size = 0.25,
    position = position_points_jitter(height = 0), alpha = 0.6, scale = 1.2) 
#> Picking joint bandwidth of 0.445


loadsummary2 <- crossing("set" =  dfs$set, "loading" = dfs$loading)
loadsummary2$pop <- rep(c(0.1, 0.15, 0.20, 0.05, 0.7), 3)
  
ggplot(dfs, aes(x = estimate, y = loading, fill = set)) +
  geom_density_ridges(
    jittered_points = TRUE,
    point_shape = "|", point_size = 2, size = 0.25,
    position = position_points_jitter(height = 0), alpha = 0.6, scale = 1.2) + 
    geom_label(data = loadsummary2, aes(y = loading, x = pop), label = loadsummary2$pop)
#> Picking joint bandwidth of 0.445

Created on 2020-03-13 by the reprex package (v0.3.0)

Do you have an ideal location for where the labels should go? Like in the space above and to the left of the curves?

Ideally, it would look like this (the solution). I've played around with that code, and can't seem to adapt it.

I'm also just terrible with ggplot though, so I might be missing something simple. :frowning: :cold_sweat:

So just to confirm I understand, you want labels at the the pop values themselves, then? (With those exact numbers in them, right?)

Yes, at those exact values! :slight_smile:

Could you try using this to replace your current line with geom_label()?

geom_text(data = loadsummary2, 
          aes(y = loading, x = pop, label = pop),
          position=position_nudge(y=-0.1), 
          colour="red", 
          size=3.5)
)

I think you want the label argument inside of the aes() function.

Oh, something that silly!
Any solution for adding line segments?

Yes, you should be able to by using geom_segment(). Does this work?

geom_segment(
  aes(
    x = pop,
    y = loading,
    xend = pop,
    yend = loading + pop
  )
)

Sorry, the yend doesn't make sense...let me see if I can fix that.

Sadly, no.

Picking joint bandwidth of 0.448
Warning messages:
1: In Ops.factor(loading, pop) : ‘+’ not meaningful for factors
2: Removed 300 rows containing missing values (geom_segment).

I played around with making them not factors, but I still got the second error message.

I think you could try as.numeric(loading) + 1 (+ pop) doesn't make sense, and see if that at least makes vertical lines. Still thinking about the lines...

Sorry forgot to have you include the data in the geom_segment() layer. Here's the corrected version, but I have question for you: Did you want the lines to be a particular height?

  geom_segment( 
    data = loadsummary2, 
    aes( x = pop, y = loading, xend = pop, yend = as.numeric(loading) + 1 ) 
    )

I've been playing around. I can fudge with the numbers a little more, see what looks best. But for now this is more than sufficient to share as internal results!

Thanks so much for your effort!

p + geom_segment(aes(
  x = pop,, 
  y = as.numeric(loading) - .05,
  xend = pop,
  yend = as.numeric(loading) + .15))
1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.