BooBooKins
BooBooKins

Reputation: 3

Create violin plots, spaceship charts or similar for discrete variables in R using ggplot2

I'm trying to create a series of charts like these at the link below. These charts show the population at each of the UK Civil Service grades, with a chart for each government department. This allows for easy comparison across the charts to show how they are structured. For example, I can quickly see that DfID is very senior-heavy whereas MOJ is much more bottom-heavy.

https://www.instituteforgovernment.org.uk/charts/grade-composition-and-change-department

I'd like to do this in R and have been trialling some solutions using ggplot. I've tried the following approaches so far:

I've included an example below which would create a pair of lines showing the average fantasy football points by position for a particular team. I'd then like to do this across all Premier League teams, in a similar way to what has been done across the Civil Service departments at the link above.

library(tidyverse)
library(dplyr)

position <- c('Goalkeeper','Defender','Midfielder','Forward')
average_points <- c(100, 150, 185, 170)

football_df <- data.frame(position, average_points) %>%
  dplyr::mutate(negative_average_points = average_points * -1) %>% # create a column that shows the negative to create the mirrored line
  gather(key = key, value = average_points, -position, na.rm = TRUE) # turn into long format to create the line chart

ggplot(football_df, 
       aes(x = position, y = average_points, group = key)) + 
  geom_line() +
  coord_flip()

This is the route I'm heading down at the moment. I'd love to do something more like an area chart but the stacking won't allow negative values.

There are still a couple of issues with taking this approach:

I'd welcome any thoughts on better approaches, or how I might develop the line chart idea to make it look more like the charts in the example at the link above. Thank you!

Upvotes: 0

Views: 256

Answers (1)

stefan
stefan

Reputation: 124223

To achieve your desired result you could switch to geom_area and for the ordering you could set the limits to the desired order:

library(tidyverse)

position <- c('Goalkeeper','Defender','Midfielder','Forward')
average_points <- c(100, 150, 185, 170)

football_df <- data.frame(position, average_points) %>%
  dplyr::mutate(negative_average_points = average_points * -1) %>% # create a column that shows the negative to create the mirrored line
  gather(key = key, value = average_points, -position, na.rm = TRUE) # turn into long format to create the line chart

ggplot(football_df, 
       aes(x = position, y = average_points, group = key)) + 
  geom_area() +
  scale_x_discrete(limits = position) +
  coord_flip()

Upvotes: 0

Related Questions