How to have sum of values sum to 1 in geom_freqpoly()?

Viewed 32

As an example, we can use geom_freqpoly() to examine how hp varies by cyl in the mtcars data.

library(tidyverse)

mtcars %>%
  mutate(cyl = as.factor(cyl)) %>%
  ggplot() +
  aes(x=hp, color=cyl) +
  geom_freqpoly(mapping = aes(y = after_stat(ncount)), bins=5)

enter image description here

Using after_stat(ncount), I can make each line be normalized between 0 and 1. However, is there a way to have it so that the sum of all the lines at any point is equal to 1? i.e., at any value of hp, the red, green, and blue lines add to one -- representing the estimated proportion of each cyl type at that value of hp.

1 Answers

This can be achieved with position = "fill", though it looks confusing with lines and is better represented as a filled geom using the same statistical transformation as geom_freqpoly

library(tidyverse)

mtcars %>%
  mutate(cyl = as.factor(cyl)) %>%
  ggplot() +
  aes(x = hp, fill =c yl) +
  stat_bin(bins = 5, position = "fill", geom = "area")

Compare this to the same result using an unfilled geom_freqpoly

mtcars %>%
  mutate(cyl = as.factor(cyl)) %>%
  ggplot() +
  aes(x = hp, color = cyl) +
  geom_freqpoly(position = "fill", bins = 5)

enter image description here

I think this is harder to follow.

Another alternative to geom_freqpoly would be geom_density, which permits more visually appealing representations of similar information:

mtcars %>%
  mutate(cyl = as.factor(cyl)) %>%
  ggplot() +
  aes(x = hp, fill = cyl) +
  geom_density(position = "fill", alpha = 0.5, color = "white", lwd = 2) +
  coord_cartesian(xlim = c(50, 200)) +
  scale_fill_brewer(palette = "Set2") +
  theme_minimal(base_size = 20) +
  labs(y = "Relative density")

enter image description here

Created on 2022-09-05 with reprex v2.0.2

Related