2

I am trying to generate overlay density plots over time, comparing densities of males vs. females. Here is my output: enter image description here

I am following the Australian athletes height example from https://cran.r-project.org/web/packages/ggridges/vignettes/gallery.html. Here is my code:

ggplot(math_dat, aes(x = order_math, y = time, color = gender, point_color = gender, fill = gender)) +
  geom_density_ridges(
    jittered_points = TRUE, scale = .95, rel_min_height = .01,
    point_shape = "|", point_size = 3, size = 0.25,
    position = position_points_jitter(height = 0)
  ) +
  scale_y_discrete(expand = c(0, 0)) +
  scale_x_continuous(expand = c(0, 0), name = "Rankings") +
  scale_fill_manual(values = c("#D55E0050", "#0072B250"), labels = c("female", "male")) +
  scale_color_manual(values = c("#D55E00", "#0072B2"), guide = "none") +
  scale_discrete_manual("point_color", values = c("#D55E00", "#0072B2"), guide = "none") +
  coord_cartesian(clip = "off") +
  guides(fill = guide_legend(
    override.aes = list(
      fill = c("#D55E00A0", "#0072B2A0"),
      color = NA, point_color = NA)
  )
  ) +
  ggtitle("Ranks over time") +
  theme_ridges(center = TRUE)

My problem is I am unable to generate any Y axis tick values and the example doesn't display any either. Any ideas how to get Y axis tick marks to display? Here is some sample data similar to mine:

## generating dataset
order_math<-c(1,2,1,2,3,3,1,2,3,1,2,3)
gender<-c("M","F","M","M","M","F","F","M","F","M","M","F")
time<-c(1,1,2,3,3,2,1,2,3,2,3,1)
sample<-data.frame(order_math,gender,time)

UPdate: After @Tomasu's suggestions I have updated my code, but it does not run:

ggplot(math_dat, aes(x = order_math, y = time, color = gender, point_color = gender, fill = gender)) +
  geom_density_ridges(
    jittered_points = TRUE, scale = .95, rel_min_height = .01,
    point_shape = "|", point_size = 3, size = 0.25,
    position = position_points_jitter(height = 0)
  ) +
  scale_y_reverse(limits = c(1000, 500, 100),expand = c(0, 0)) +
  scale_x_continuous(expand = c(0, 0), name = "Rankings") +
  scale_fill_manual(values = c("#D55E0050", "#0072B250"), labels = c("female", "male")) +
  scale_color_manual(values = c("#D55E00", "#0072B2"), guide = "none") +
  scale_discrete_manual("point_color", values = c("#D55E00", "#0072B2"), guide = "none") +
  coord_cartesian(clip = "off") +
  guides(fill = guide_legend(
    override.aes = list(
      fill = c("#D55E00A0", "#0072B2A0"),
      color = NA, point_color = NA)
  )
  ) +
  ggtitle("Ranks over time") +
  theme_ridges(center = TRUE)+
  theme(
    axis.ticks = element_line(size=0.5),         # turn ticks back on
    axis.ticks.length = grid::unit(5, "pt"),     # set length
    axis.ticks.y = element_line(colour = "red"), # define tick line color
    axis.text.y = element_text(vjust = .4)       # center text with tick
  )
tjebo
  • 21,977
  • 7
  • 58
  • 94
user2450223
  • 235
  • 2
  • 10

2 Answers2

3

An easy solution to this problem would be to use a theme_ that includes the axis ticks as theme_ridges() has them turned off. Just removing that theme all together and using the base ggplot2 theme achieves the desired outcome.

However, let's say we still want to use theme_ridges() and just turn ticks back on. This can be achieved with a theme() edit after the theme_ridges().

I'm using the example in the link provided as I couldn't get your sample data to work properly.

library(ggplot2)
library(ggplot2movies)
library(ggridges)

ggplot(movies[movies$year>1912,], aes(x = length, y = year, group = year)) +
  geom_density_ridges(scale = 10, size = 0.25, rel_min_height = 0.03) +
  theme_ridges() +
  theme(
    axis.ticks = element_line(size=0.5),         # turn ticks back on
    axis.ticks.length = grid::unit(5, "pt"),     # set length
    axis.ticks.y = element_line(colour = "red"), # define tick line color
    axis.text.y = element_text(vjust = .4)       # center text with tick
  ) +
  scale_x_continuous(limits = c(1, 200), expand = c(0, 0)) +
  scale_y_reverse(
    breaks = c(2000, 1980, 1960, 1940, 1920, 1900),
    expand = c(0, 0)
  ) +
  coord_cartesian(clip = "off")

Created on 2021-05-11 by the reprex package (v1.0.0)

tomasu
  • 1,388
  • 9
  • 11
  • It doesn't work for me :( I tried turning on the ticks using theme() and using scale_y_reverse. For some reason, scale_y_reverse results in an error while using scale_y_discrete runs, but doesn't show Y axis labels. – user2450223 May 12 '21 at 06:12
  • This is the error I get with scale_y_reverse: Error in -x : invalid argument to unary operator. I have edited my questions to show how I'm using your suggestions. – user2450223 May 12 '21 at 06:21
  • Any chance you could use your `math_order` data set instead of your actual data? I’m unable to run your code because the supplied data errors when I try and use it. – tomasu May 12 '21 at 13:21
1

I think your problem is that you need to specify the group.

Related thread: geom_density_ridges requires the following missing aesthetics: y

Extending on code from user tomasu's answer +1

library(ggridges)
library(ggplot2)
order_math<-c(1,2,1,2,3,3,1,2,3,1,2,3)
gender<-c("M","F","M","M","M","F","F","M","F","M","M","F")
time<-c(1,1,2,3,3,2,1,2,3,2,3,1)
sample<-data.frame(order_math,gender,time)

ggplot(sample, aes(x = order_math, y = time, group = time,
                   color = gender, point_color = gender, fill = gender)) +
  geom_density_ridges()  +
  theme(
    axis.ticks = element_line(size=0.5),         # turn ticks back on
    axis.ticks.length = grid::unit(5, "pt"),     # set length
    axis.ticks.y = element_line(colour = "red"), # define tick line color
    axis.text.y = element_text(vjust = .4)       # center text with tick
  )
#> Picking joint bandwidth of 0.555

Created on 2021-05-12 by the reprex package (v2.0.0)

tjebo
  • 21,977
  • 7
  • 58
  • 94
  • I want the relative frequency or count to be displayed on the Y-axis, in addition to the labels specifying the level of the Y variable. None of these plots do that, including the original ones in the example code. For instance, if the frequency of order math=1 is around 1000 and order math=2 is about 500, I want to display that. I'm not able to do that even after adding in breaks=c(100,500,1000) in the scale_y_discrete statement – user2450223 May 12 '21 at 12:50
  • @user2450223 this is not what the Ridgeline plot does. consider a different visualisation, in particular facets. – tjebo May 13 '21 at 20:39